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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
|
From 24496747b648d1a7bd0d6da1ef3759f035ba1cd6 Mon Sep 17 00:00:00 2001
From: Martin Pitt <martin.pitt@ubuntu.com>
Date: Wed, 05 Mar 2014 12:47:15 +0000
Subject: Fix buffer overflow in mount path parsing
In the mount monitor we parse mount points from /proc/self/mountinfo and
/proc/swaps. 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
---
diff --git a/src/udisksmountmonitor.c b/src/udisksmountmonitor.c
index 8af1028..e7097fa 100644
--- a/src/udisksmountmonitor.c
+++ b/src/udisksmountmonitor.c
@@ -38,6 +38,11 @@
#include "udisksmount.h"
#include "udisksprivate.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"
+
/**
* SECTION:udisksmountmonitor
* @title: UDisksMountMonitor
@@ -416,8 +421,8 @@ udisks_mount_monitor_get_mountinfo (UDisksMountMonitor *monitor,
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;
@@ -425,7 +430,7 @@ udisks_mount_monitor_get_mountinfo (UDisksMountMonitor *monitor,
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,
@@ -436,6 +441,8 @@ udisks_mount_monitor_get_mountinfo (UDisksMountMonitor *monitor,
udisks_warning ("Error parsing line '%s'", lines[n]);
continue;
}
+ encoded_root[sizeof encoded_root - 1] = '\0';
+ encoded_mount_point[sizeof encoded_mount_point - 1] = '\0';
/* Temporary work-around for btrfs, see
*
@@ -450,15 +457,17 @@ udisks_mount_monitor_get_mountinfo (UDisksMountMonitor *monitor,
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)
{
udisks_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;
@@ -546,7 +555,7 @@ udisks_mount_monitor_get_swaps (UDisksMountMonitor *monitor,
lines = g_strsplit (contents, "\n", 0);
for (n = 0; lines[n] != NULL; n++)
{
- gchar filename[PATH_MAX];
+ gchar filename[PATH_MAX + 1];
struct stat statbuf;
dev_t dev;
@@ -557,11 +566,12 @@ udisks_mount_monitor_get_swaps (UDisksMountMonitor *monitor,
if (strlen (lines[n]) == 0)
continue;
- if (sscanf (lines[n], "%s", filename) != 1)
+ if (sscanf (lines[n], PATH_MAX_FMT, filename) != 1)
{
udisks_warning ("Error parsing line '%s'", lines[n]);
continue;
}
+ filename[sizeof filename - 1] = '\0';
if (stat (filename, &statbuf) != 0)
{
--
cgit v0.9.0.2-2-gbebe
|