~ubuntu-branches/ubuntu/quantal/cups-pk-helper/quantal-updates

« back to all changes in this revision

Viewing changes to debian/patches/CVE-2012-4510-part2.patch

  • Committer: Package Import Robot
  • Author(s): Jeremy Bicha
  • Date: 2012-11-26 22:12:08 UTC
  • Revision ID: package-import@ubuntu.com-20121126221208-bg74o9vm5bm8c1q5
Tags: 0.2.1.2-1ubuntu1.1
* SECURITY UPDATE: CUPS function calls were wrapped insecurely, which
  could be used to upload sensitive data to a CUPS resource, or overwrite
  specific files with the content of a CUPS resource. The user would have
  to explicitly approve the action. (LP: #1083416)
  - CVE-2012-4510
  - debian/patches/CVE-2012-4510-part1.patch: Copied from git
  - debian/patches/CVE-2012-4510-part2.patch: Copied from git

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
From a397b90823af3e4e697b9118022aa88f91a80989 Mon Sep 17 00:00:00 2001
 
2
From: Vincent Untz <vuntz@suse.com>
 
3
Date: Wed, 10 Oct 2012 07:54:18 +0000
 
4
Subject: Also change supplementary groups when changing effective uid/gid
 
5
 
 
6
Thanks to Alexander Peslyak <solar@openwall.com> and Sebastian Krahmer
 
7
<krahmer@suse.de> for catching this.
 
8
 
 
9
Part of fix for CVE-2012-4510.
 
10
---
 
11
diff --git a/src/cups.c b/src/cups.c
 
12
index 6ff6cba..d45a315 100644
 
13
--- a/src/cups.c
 
14
+++ b/src/cups.c
 
15
@@ -28,6 +28,7 @@
 
16
 #include <fcntl.h>
 
17
 #include <errno.h>
 
18
 #include <ctype.h>
 
19
+#include <grp.h>
 
20
 #include <pwd.h>
 
21
 #include <sys/wait.h>
 
22
 #include <sys/types.h>
 
23
@@ -512,31 +513,81 @@ _CPH_CUPS_IS_VALID (filename, "filename", TRUE, CPH_STR_MAXLEN)
 
24
  ******************************************************/
 
25
 
 
26
 static gboolean
 
27
-_cph_cups_set_effective_id (unsigned int sender_uid)
 
28
+_cph_cups_set_effective_id (unsigned int   sender_uid,
 
29
+                            int           *saved_ngroups,
 
30
+                            gid_t        **saved_groups)
 
31
 {
 
32
         struct passwd *password_entry;
 
33
+        int            ngroups;
 
34
+        gid_t         *groups;
 
35
+
 
36
+        /* avoid g_assert() because we don't want to crash here */
 
37
+        if (saved_ngroups == NULL || saved_groups == NULL) {
 
38
+                g_critical ("Internal error: cannot save supplementary groups.");
 
39
+                return FALSE;
 
40
+        }
 
41
+
 
42
+        *saved_ngroups = -1;
 
43
+        *saved_groups = NULL;
 
44
+
 
45
+        ngroups = getgroups (0, NULL);
 
46
+        if (ngroups < 0)
 
47
+                return FALSE;
 
48
+
 
49
+        groups = g_new (gid_t, ngroups);
 
50
+        if (groups == NULL && ngroups > 0)
 
51
+                return FALSE;
 
52
+
 
53
+        if (getgroups (ngroups, groups) < 0) {
 
54
+                g_free (groups);
 
55
+
 
56
+                return FALSE;
 
57
+        }
 
58
 
 
59
         password_entry = getpwuid ((uid_t) sender_uid);
 
60
 
 
61
         if (password_entry == NULL ||
 
62
-            setegid (password_entry->pw_gid) != 0)
 
63
+            setegid (password_entry->pw_gid) != 0) {
 
64
+                g_free (groups);
 
65
+
 
66
+                return FALSE;
 
67
+        }
 
68
+
 
69
+        if (initgroups (password_entry->pw_name,
 
70
+                        password_entry->pw_gid) != 0) {
 
71
+                if (getgid () != getegid ())
 
72
+                        setegid (getgid ());
 
73
+
 
74
+                g_free (groups);
 
75
+
 
76
                 return FALSE;
 
77
+        }
 
78
+
 
79
 
 
80
         if (seteuid (sender_uid) != 0) {
 
81
                 if (getgid () != getegid ())
 
82
                         setegid (getgid ());
 
83
 
 
84
+                setgroups (ngroups, groups);
 
85
+                g_free (groups);
 
86
+
 
87
                 return FALSE;
 
88
         }
 
89
 
 
90
+        *saved_ngroups = ngroups;
 
91
+        *saved_groups = groups;
 
92
+
 
93
         return TRUE;
 
94
 }
 
95
 
 
96
 static void
 
97
-_cph_cups_reset_effective_id (void)
 
98
+_cph_cups_reset_effective_id (int    saved_ngroups,
 
99
+                              gid_t *saved_groups)
 
100
 {
 
101
         seteuid (getuid ());
 
102
         setegid (getgid ());
 
103
+        if (saved_ngroups >= 0)
 
104
+                setgroups (saved_ngroups, saved_groups);
 
105
 }
 
106
 
 
107
 static void
 
108
@@ -1115,6 +1166,8 @@ cph_cups_file_get (CphCups      *cups,
 
109
                    const char   *filename,
 
110
                    unsigned int  sender_uid)
 
111
 {
 
112
+        int           saved_ngroups = -1;
 
113
+        gid_t        *saved_groups = NULL;
 
114
         http_status_t status;
 
115
         int           fd;
 
116
         struct stat   file_stat;
 
117
@@ -1127,7 +1180,8 @@ cph_cups_file_get (CphCups      *cups,
 
118
         if (!_cph_cups_is_filename_valid (cups, filename))
 
119
                 return FALSE;
 
120
 
 
121
-        if (!_cph_cups_set_effective_id (sender_uid)) {
 
122
+        if (!_cph_cups_set_effective_id (sender_uid,
 
123
+                                         &saved_ngroups, &saved_groups)) {
 
124
                 error = g_strdup_printf ("Cannot check if \"%s\" is "
 
125
                                          "writable: %s",
 
126
                                          filename, strerror (errno));
 
127
@@ -1139,7 +1193,8 @@ cph_cups_file_get (CphCups      *cups,
 
128
 
 
129
         fd = open (filename, O_WRONLY | O_NOFOLLOW | O_TRUNC);
 
130
 
 
131
-        _cph_cups_reset_effective_id ();
 
132
+        _cph_cups_reset_effective_id (saved_ngroups, saved_groups);
 
133
+        g_free (saved_groups);
 
134
 
 
135
         if (fd < 0) {
 
136
                 error = g_strdup_printf ("Cannot open \"%s\": %s",
 
137
@@ -1200,6 +1255,8 @@ cph_cups_file_put (CphCups      *cups,
 
138
                    const char   *filename,
 
139
                    unsigned int  sender_uid)
 
140
 {
 
141
+        int           saved_ngroups = -1;
 
142
+        gid_t        *saved_groups = NULL;
 
143
         http_status_t status;
 
144
         int           fd;
 
145
         struct stat   file_stat;
 
146
@@ -1212,7 +1269,8 @@ cph_cups_file_put (CphCups      *cups,
 
147
         if (!_cph_cups_is_filename_valid (cups, filename))
 
148
                 return FALSE;
 
149
 
 
150
-        if (!_cph_cups_set_effective_id (sender_uid)) {
 
151
+        if (!_cph_cups_set_effective_id (sender_uid,
 
152
+                                         &saved_ngroups, &saved_groups)) {
 
153
                 error = g_strdup_printf ("Cannot check if \"%s\" is "
 
154
                                          "readable: %s",
 
155
                                          filename, strerror (errno));
 
156
@@ -1224,7 +1282,8 @@ cph_cups_file_put (CphCups      *cups,
 
157
 
 
158
         fd = open (filename, O_RDONLY);
 
159
 
 
160
-        _cph_cups_reset_effective_id ();
 
161
+        _cph_cups_reset_effective_id (saved_ngroups, saved_groups);
 
162
+        g_free (saved_groups);
 
163
 
 
164
         if (fd < 0) {
 
165
                 error = g_strdup_printf ("Cannot open \"%s\": %s",
 
166