mirror of
https://git.in.rschanz.org/ryan77627/guix.git
synced 2024-12-24 21:38:07 -05:00
file-systems: Do not read superblocks past the end of a device.
Fixes <http://bugs.gnu.org/25573>. Reported by Alex Kost <alezost@gmail.com>. * gnu/build/file-systems.scm (seek*): New procedure. (read-superblock): Use it instead of 'seek' and ensure it returns OFFSET.
This commit is contained in:
parent
69f2b3bdf9
commit
2fe4ceee18
1 changed files with 22 additions and 11 deletions
|
@ -1,5 +1,5 @@
|
||||||
;;; GNU Guix --- Functional package management for GNU
|
;;; GNU Guix --- Functional package management for GNU
|
||||||
;;; Copyright © 2014, 2015, 2016 Ludovic Courtès <ludo@gnu.org>
|
;;; Copyright © 2014, 2015, 2016, 2017 Ludovic Courtès <ludo@gnu.org>
|
||||||
;;; Copyright © 2016, 2017 David Craven <david@craven.ch>
|
;;; Copyright © 2016, 2017 David Craven <david@craven.ch>
|
||||||
;;;
|
;;;
|
||||||
;;; This file is part of GNU Guix.
|
;;; This file is part of GNU Guix.
|
||||||
|
@ -72,22 +72,33 @@ (define (bind-mount source target)
|
||||||
"Bind-mount SOURCE at TARGET."
|
"Bind-mount SOURCE at TARGET."
|
||||||
(mount source target "" MS_BIND))
|
(mount source target "" MS_BIND))
|
||||||
|
|
||||||
|
(define (seek* fd/port offset whence)
|
||||||
|
"Like 'seek' but return -1 instead of throwing to 'system-error' upon
|
||||||
|
EINVAL. This makes it easier to catch cases like OFFSET being too large for
|
||||||
|
FD/PORT."
|
||||||
|
(catch 'system-error
|
||||||
|
(lambda ()
|
||||||
|
(seek fd/port offset whence))
|
||||||
|
(lambda args
|
||||||
|
(if (= EINVAL (system-error-errno args))
|
||||||
|
-1
|
||||||
|
(apply throw args)))))
|
||||||
|
|
||||||
(define (read-superblock device offset size magic?)
|
(define (read-superblock device offset size magic?)
|
||||||
"Read a superblock of SIZE from OFFSET and DEVICE. Return the raw
|
"Read a superblock of SIZE from OFFSET and DEVICE. Return the raw
|
||||||
superblock on success, and #f if no valid superblock was found. MAGIC?
|
superblock on success, and #f if no valid superblock was found. MAGIC?
|
||||||
takes a bytevector and returns #t when it's a valid superblock."
|
takes a bytevector and returns #t when it's a valid superblock."
|
||||||
(call-with-input-file device
|
(call-with-input-file device
|
||||||
(lambda (port)
|
(lambda (port)
|
||||||
(seek port offset SEEK_SET)
|
(and (= offset (seek* port offset SEEK_SET))
|
||||||
|
(let ((block (make-bytevector size)))
|
||||||
(let ((block (make-bytevector size)))
|
(match (get-bytevector-n! port block 0 (bytevector-length block))
|
||||||
(match (get-bytevector-n! port block 0 (bytevector-length block))
|
((? eof-object?)
|
||||||
((? eof-object?)
|
#f)
|
||||||
#f)
|
((? number? len)
|
||||||
((? number? len)
|
(and (= len (bytevector-length block))
|
||||||
(and (= len (bytevector-length block))
|
(and (magic? block)
|
||||||
(and (magic? block)
|
block)))))))))
|
||||||
block))))))))
|
|
||||||
|
|
||||||
(define (sub-bytevector bv start size)
|
(define (sub-bytevector bv start size)
|
||||||
"Return a copy of the SIZE bytes of BV starting from offset START."
|
"Return a copy of the SIZE bytes of BV starting from offset START."
|
||||||
|
|
Loading…
Reference in a new issue