summary refs log tree commit diff
path: root/pkgs/os-specific/linux/udisks/cve-2014-0004.patch
blob: ce907507538f7ef7fa315cb4c39aa66beaf9b99a (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
commit ebf61ed8471a45cf8bce7231de00cb1bbc140708
Author: Martin Pitt <martin.pitt@ubuntu.com>
Date:   Wed Mar 5 14:07:44 2014 +0100

    Fix buffer overflow in mount path parsing
    
    In the mount monitor we parse mount points from /proc/self/mountinfo.  Ensure
    that we don't overflow the buffers on platforms where mount paths could be
    longer than PATH_MAX (unknown if that can actually happen), as at least the
    mount paths for hotpluggable devices are somewhat user-controlled.
    
    Thanks to Florian Weimer for discovering this bug, and to David Zeuthen
    for his initial patch!
    
    CVE-2014-0004

Index: udisks-1.0.4/src/mount-monitor.c
===================================================================
--- udisks-1.0.4.orig/src/mount-monitor.c	2011-08-25 20:27:33.000000000 +0200
+++ udisks-1.0.4/src/mount-monitor.c	2014-03-10 13:38:18.309406561 +0100
@@ -39,6 +39,11 @@
 #include "mount.h"
 #include "private.h"
 
+/* build a %Ns format string macro with N == PATH_MAX */
+#define xstr(s) str(s)
+#define str(s) #s
+#define PATH_MAX_FMT "%" xstr(PATH_MAX) "s"
+
 /*--------------------------------------------------------------------------------------------------------------*/
 
 enum
@@ -320,8 +325,8 @@ mount_monitor_ensure (MountMonitor *moni
       guint mount_id;
       guint parent_id;
       guint major, minor;
-      gchar encoded_root[PATH_MAX];
-      gchar encoded_mount_point[PATH_MAX];
+      gchar encoded_root[PATH_MAX + 1];
+      gchar encoded_mount_point[PATH_MAX + 1];
       gchar *mount_point;
       dev_t dev;
 
@@ -329,7 +334,7 @@ mount_monitor_ensure (MountMonitor *moni
         continue;
 
       if (sscanf (lines[n],
-                  "%d %d %d:%d %s %s",
+                  "%d %d %d:%d " PATH_MAX_FMT " " PATH_MAX_FMT,
                   &mount_id,
                   &parent_id,
                   &major,
@@ -340,6 +345,8 @@ mount_monitor_ensure (MountMonitor *moni
           g_warning ("Error parsing line '%s'", lines[n]);
           continue;
         }
+      encoded_root[sizeof encoded_root - 1] = '\0';
+      encoded_mount_point[sizeof encoded_mount_point - 1] = '\0';
 
       /* ignore mounts where only a subtree of a filesystem is mounted */
       if (g_strcmp0 (encoded_root, "/") != 0)
@@ -358,15 +365,17 @@ mount_monitor_ensure (MountMonitor *moni
           sep = strstr (lines[n], " - ");
           if (sep != NULL)
             {
-              gchar fstype[PATH_MAX];
-              gchar mount_source[PATH_MAX];
+              gchar fstype[PATH_MAX + 1];
+              gchar mount_source[PATH_MAX + 1];
               struct stat statbuf;
 
-              if (sscanf (sep + 3, "%s %s", fstype, mount_source) != 2)
+              if (sscanf (sep + 3, PATH_MAX_FMT " " PATH_MAX_FMT, fstype, mount_source) != 2)
                 {
                   g_warning ("Error parsing things past - for '%s'", lines[n]);
                   continue;
                 }
+              fstype[sizeof fstype - 1] = '\0';
+              mount_source[sizeof mount_source - 1] = '\0';
 
               if (g_strcmp0 (fstype, "btrfs") != 0)
                 continue;