guix-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

01/03: file-systems: Do not read superblocks past the end of a device.


From: Ludovic Courtès
Subject: 01/03: file-systems: Do not read superblocks past the end of a device.
Date: Tue, 31 Jan 2017 22:22:27 +0000 (UTC)

civodul pushed a commit to branch master
in repository guix.

commit 2fe4ceee18f8687de8520d28dbfefc7bc3a7e084
Author: Ludovic Courtès <address@hidden>
Date:   Tue Jan 31 21:52:46 2017 +0100

    file-systems: Do not read superblocks past the end of a device.
    
    Fixes <http://bugs.gnu.org/25573>.
    Reported by Alex Kost <address@hidden>.
    
    * gnu/build/file-systems.scm (seek*): New procedure.
    (read-superblock): Use it instead of 'seek' and ensure it returns
    OFFSET.
---
 gnu/build/file-systems.scm |   33 ++++++++++++++++++++++-----------
 1 file changed, 22 insertions(+), 11 deletions(-)

diff --git a/gnu/build/file-systems.scm b/gnu/build/file-systems.scm
index 6e5c6aa..f8ab953 100644
--- a/gnu/build/file-systems.scm
+++ b/gnu/build/file-systems.scm
@@ -1,5 +1,5 @@
 ;;; GNU Guix --- Functional package management for GNU
-;;; Copyright © 2014, 2015, 2016 Ludovic Courtès <address@hidden>
+;;; Copyright © 2014, 2015, 2016, 2017 Ludovic Courtès <address@hidden>
 ;;; Copyright © 2016, 2017 David Craven <address@hidden>
 ;;;
 ;;; This file is part of GNU Guix.
@@ -72,22 +72,33 @@
   "Bind-mount SOURCE at TARGET."
   (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?)
   "Read a superblock of SIZE from OFFSET and DEVICE.  Return the raw
 superblock on success, and #f if no valid superblock was found.  MAGIC?
 takes a bytevector and returns #t when it's a valid superblock."
   (call-with-input-file device
     (lambda (port)
-      (seek port offset SEEK_SET)
-
-      (let ((block (make-bytevector size)))
-        (match (get-bytevector-n! port block 0 (bytevector-length block))
-          ((? eof-object?)
-           #f)
-          ((? number? len)
-           (and (= len (bytevector-length block))
-                (and (magic? block)
-                     block))))))))
+      (and (= offset (seek* port offset SEEK_SET))
+           (let ((block (make-bytevector size)))
+             (match (get-bytevector-n! port block 0 (bytevector-length block))
+               ((? eof-object?)
+                #f)
+               ((? number? len)
+                (and (= len (bytevector-length block))
+                     (and (magic? block)
+                          block)))))))))
 
 (define (sub-bytevector bv start size)
   "Return a copy of the SIZE bytes of BV starting from offset START."



reply via email to

[Prev in Thread] Current Thread [Next in Thread]