~ubuntu-branches/ubuntu/lucid/suphp/lucid

« back to all changes in this revision

Viewing changes to debian/patches/04_CVE-2008-1614.dpatch

  • Committer: Bazaar Package Importer
  • Author(s): Emmanuel Lacour
  • Date: 2009-08-03 15:15:38 UTC
  • mfrom: (8.1.2 sid)
  • Revision ID: james.westby@ubuntu.com-20090803151538-pv7yhe6w1mqmceas
Tags: 0.7.1-1
* New upstream release (closes: #528379, #520182) 
* debian/NEWS: add information about AddHandler -> AddType change introduced
  in 0.6.2-2 (closes: #517805)
* debian/conf/suphp.conf, debian/patches/01_debian.dpatch: switch from
  application/x-httpd-php to application/x-httpd-suphp to allow
  simultaneous use of mod_suphp and mod_php (closes: #519005, #514725)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
#! /bin/sh /usr/share/dpatch/dpatch-run
2
 
## 04_CVE-2008-1614.dpatch
3
 
##
4
 
## All lines beginning with `## DP:' are a description of the patch.
5
 
## DP: Fix for CVE-2008-1614 - race condition in symlink handling
6
 
 
7
 
@DPATCH@
8
 
--- suphp-0.6.2.orig/src/API_Linux.hpp
9
 
+++ suphp-0.6.2/src/API_Linux.hpp
10
 
@@ -169,6 +169,11 @@
11
 
        virtual GroupInfo File_getGroup(const File& file) const
12
 
            throw (SystemException);
13
 
 
14
 
+        /**
15
 
+         * Checks whether a file is a symlink
16
 
+         */
17
 
+        virtual bool File_isSymlink(const File& file) const throw (SystemException);
18
 
+        
19
 
        /**
20
 
         * Runs another program (replaces current process)
21
 
         */
22
 
only in patch2:
23
 
unchanged:
24
 
--- suphp-0.6.2.orig/src/File.cpp
25
 
+++ suphp-0.6.2/src/File.cpp
26
 
@@ -57,6 +57,9 @@
27
 
 File suPHP::File::getParentDirectory() const {
28
 
     std::string path = this->getPath();
29
 
     path = path.substr(0, path.rfind('/'));
30
 
+    if (path.length() == 0) {
31
 
+        path = "/";
32
 
+    }
33
 
     return File(path);
34
 
 }
35
 
 
36
 
@@ -104,3 +107,7 @@
37
 
 GroupInfo suPHP::File::getGroup() const throw (SystemException) {
38
 
     return API_Helper::getSystemAPI().File_getGroup(*this);
39
 
 }
40
 
+
41
 
+bool suPHP::File::isSymlink() const throw (SystemException) {
42
 
+    return API_Helper::getSystemAPI().File_isSymlink(*this);
43
 
+}
44
 
only in patch2:
45
 
unchanged:
46
 
--- suphp-0.6.2.orig/src/Application.hpp
47
 
+++ suphp-0.6.2/src/Application.hpp
48
 
@@ -107,6 +107,14 @@
49
 
                           const Configuration& config) const
50
 
            throw (SoftException);
51
 
 
52
 
+         
53
 
+         /**
54
 
+          * Checks ownership and permissions for parent directories
55
 
+          */
56
 
+         void checkParentDirectories(const File& file,
57
 
+                                     const UserInfo& owner,
58
 
+                                     const Configuration& config) const
59
 
+             throw (SoftException);
60
 
 
61
 
     public:
62
 
        /**
63
 
only in patch2:
64
 
unchanged:
65
 
--- suphp-0.6.2.orig/src/Application.cpp
66
 
+++ suphp-0.6.2/src/Application.cpp
67
 
@@ -177,6 +177,7 @@
68
 
     throw (SystemException, SoftException) {
69
 
     Logger& logger = API_Helper::getSystemAPI().getSystemLogger();
70
 
     File scriptFile = File(scriptFilename);
71
 
+    File realScriptFile = File(scriptFile.getRealPath());
72
 
 
73
 
     // Check wheter file exists
74
 
     if (!scriptFile.exists()) {
75
 
@@ -184,11 +185,13 @@
76
 
        logger.logWarning(error);
77
 
        throw SoftException(error, __FILE__, __LINE__);
78
 
     }
79
 
-    
80
 
-    // Get full path to script file
81
 
-
82
 
-    File realScriptFile = File(scriptFile.getRealPath());
83
 
-    File directory = realScriptFile.getParentDirectory();
84
 
+    if (!realScriptFile.exists()) {
85
 
+        std::string error = "File " + realScriptFile.getPath() 
86
 
+            + " referenced by symlink " +scriptFile.getPath() 
87
 
+            + " does not exist";
88
 
+        logger.logWarning(error);
89
 
+        throw SoftException(error, __FILE__, __LINE__);
90
 
+    }
91
 
     
92
 
     // Check wheter script is in docroot
93
 
     if (realScriptFile.getPath().find(config.getDocroot()) != 0) {
94
 
@@ -213,8 +216,19 @@
95
 
        logger.logWarning(error);
96
 
        throw SoftException(error, __FILE__, __LINE__);
97
 
     }
98
 
+    if (config.getCheckVHostDocroot()
99
 
+        && scriptFile.getPath().find(environment.getVar("DOCUMENT_ROOT")) 
100
 
+        != 0) {
101
 
+        
102
 
+        std::string error = "File \"" + scriptFile.getPath()
103
 
+            + "\" is not in document root of Vhost \""
104
 
+            + environment.getVar("DOCUMENT_ROOT") + "\"";
105
 
+        logger.logWarning(error);
106
 
+        throw SoftException(error, __FILE__, __LINE__);
107
 
+    }
108
 
 
109
 
-    // Check script and directory permissions
110
 
+    // Check script permissions
111
 
+    // Directories will be checked later
112
 
     if (!realScriptFile.hasUserReadBit()) {
113
 
        std::string error = "File \"" + realScriptFile.getPath()
114
 
            + "\" not readable";
115
 
@@ -231,14 +245,6 @@
116
 
        throw SoftException(error, __FILE__, __LINE__);
117
 
     }
118
 
     
119
 
-    if (!config.getAllowDirectoryGroupWriteable() 
120
 
-       && directory.hasGroupWriteBit()) {
121
 
-       std::string error = "Directory \"" + directory.getPath()
122
 
-           + "\" is writeable by group";
123
 
-       logger.logWarning(error);
124
 
-       throw SoftException(error, __FILE__, __LINE__);
125
 
-    }
126
 
-
127
 
     if (!config.getAllowFileOthersWriteable()
128
 
        && realScriptFile.hasOthersWriteBit()) {
129
 
        std::string error = "File \"" + realScriptFile.getPath()
130
 
@@ -247,14 +253,6 @@
131
 
        throw SoftException(error, __FILE__, __LINE__);
132
 
     }
133
 
     
134
 
-    if (!config.getAllowDirectoryOthersWriteable()
135
 
-       && directory.hasOthersWriteBit()) {
136
 
-       std::string error = "Directory \"" + directory.getPath()
137
 
-           + "\" is writeable by others";
138
 
-       logger.logWarning(error);
139
 
-       throw SoftException(error, __FILE__, __LINE__);
140
 
-    }
141
 
-
142
 
     // Check UID/GID of symlink is matching target
143
 
     if (scriptFile.getUser() != realScriptFile.getUser()
144
 
        || scriptFile.getGroup() != realScriptFile.getGroup()) {
145
 
@@ -274,7 +272,8 @@
146
 
     UserInfo targetUser;
147
 
     GroupInfo targetGroup;
148
 
 
149
 
-    File scriptFile = File(File(scriptFilename).getRealPath());
150
 
+    File scriptFile = File(scriptFilename);
151
 
+    File realScriptFile = File(scriptFile.getRealPath());
152
 
     API& api = API_Helper::getSystemAPI();
153
 
     Logger& logger = api.getSystemLogger();
154
 
 
155
 
@@ -360,7 +359,11 @@
156
 
        throw SoftException(error, __FILE__, __LINE__);
157
 
     }
158
 
 #endif // OPT_USERGROUP_PARANOID    
159
 
-
160
 
+    
161
 
+    // Check directory ownership and permissions
162
 
+    checkParentDirectories(realScriptFile, targetUser, config);
163
 
+    checkParentDirectories(scriptFile, targetUser, config);
164
 
+    
165
 
     // Common code used for all modes
166
 
 
167
 
     // Set new group first, because we still need super-user privileges
168
 
@@ -480,6 +483,43 @@
169
 
 }
170
 
 
171
 
 
172
 
+void suPHP::Application::checkParentDirectories(const File& file,
173
 
+                                               const UserInfo& owner,
174
 
+                                               const Configuration& config) const throw (SoftException) {
175
 
+    File directory = file;
176
 
+    Logger& logger = API_Helper::getSystemAPI().getSystemLogger();
177
 
+    do {
178
 
+        directory = directory.getParentDirectory();
179
 
+        
180
 
+        UserInfo directoryOwner = directory.getUser();
181
 
+        if (directoryOwner != owner && !directoryOwner.isSuperUser()) {
182
 
+            std::string error = "Directory " + directory.getPath()
183
 
+                + " is not owned by " + owner.getUsername();
184
 
+            logger.logWarning(error);
185
 
+            throw SoftException(error, __FILE__, __LINE__);
186
 
+        }
187
 
+        
188
 
+        if (!directory.isSymlink()
189
 
+            && !config.getAllowDirectoryGroupWriteable() 
190
 
+            && directory.hasGroupWriteBit()) {
191
 
+            std::string error = "Directory \"" + directory.getPath()
192
 
+                + "\" is writeable by group";
193
 
+            logger.logWarning(error);
194
 
+            throw SoftException(error, __FILE__, __LINE__);
195
 
+        }
196
 
+        
197
 
+        if (!directory.isSymlink()
198
 
+            && !config.getAllowDirectoryOthersWriteable()
199
 
+            && directory.hasOthersWriteBit()) {
200
 
+            std::string error = "Directory \"" + directory.getPath()
201
 
+                + "\" is writeable by others";
202
 
+            logger.logWarning(error);
203
 
+            throw SoftException(error, __FILE__, __LINE__);
204
 
+        }
205
 
+    } while (directory.getPath() != "/");
206
 
+}
207
 
+
208
 
+
209
 
 int main(int argc, char **argv) {
210
 
     try {
211
 
        API& api = API_Helper::getSystemAPI();
212
 
only in patch2:
213
 
unchanged:
214
 
--- suphp-0.6.2.orig/src/API_Linux.cpp
215
 
+++ suphp-0.6.2/src/API_Linux.cpp
216
 
@@ -225,10 +225,10 @@
217
 
 
218
 
 bool suPHP::API_Linux::File_exists(const File& file) const {
219
 
     struct stat dummy;
220
 
-    if (::stat(file.getPath().c_str(), &dummy) == 0)
221
 
-       return true;
222
 
+    if (::lstat(file.getPath().c_str(), &dummy) == 0)
223
 
+        return true;
224
 
     else
225
 
-       return false;
226
 
+        return false;
227
 
 }
228
 
 
229
 
 std::string suPHP::API_Linux::File_getRealPath(const File& file) const
230
 
@@ -304,7 +304,7 @@
231
 
 bool suPHP::API_Linux::File_hasPermissionBit(const File& file, FileMode perm) 
232
 
     const throw (SystemException) {
233
 
     struct stat temp;
234
 
-    if (stat(file.getPath().c_str(), &temp) == -1) {
235
 
+    if (lstat(file.getPath().c_str(), &temp) == -1) {
236
 
        throw SystemException(std::string("Could not stat \"")
237
 
                              + file.getPath() + "\": "
238
 
                              + ::strerror(errno), __FILE__, __LINE__);
239
 
@@ -362,7 +362,7 @@
240
 
 UserInfo suPHP::API_Linux::File_getUser(const File& file) const
241
 
     throw (SystemException) {
242
 
     struct stat temp;
243
 
-    if (stat(file.getPath().c_str(), &temp) == -1) {
244
 
+    if (lstat(file.getPath().c_str(), &temp) == -1) {
245
 
        throw SystemException(std::string("Could not stat \"")
246
 
                              + file.getPath() + "\": "
247
 
                              + ::strerror(errno), __FILE__, __LINE__);
248
 
@@ -373,7 +373,7 @@
249
 
 GroupInfo suPHP::API_Linux::File_getGroup(const File& file) const
250
 
     throw (SystemException) {
251
 
     struct stat temp;
252
 
-    if (stat(file.getPath().c_str(), &temp) == -1) {
253
 
+    if (lstat(file.getPath().c_str(), &temp) == -1) {
254
 
        throw SystemException(std::string("Could not stat \"")
255
 
                              + file.getPath() + "\": "
256
 
                              + ::strerror(errno), __FILE__, __LINE__);
257
 
@@ -382,6 +382,11 @@
258
 
 }
259
 
 
260
 
 
261
 
+bool suPHP::API_Linux::File_isSymlink(const File& file) const throw (SystemException) {
262
 
+    return this->isSymlink(file.getPath());
263
 
+}
264
 
+
265
 
+
266
 
 void suPHP::API_Linux::execute(std::string program, const CommandLine& cline,
267
 
                               const Environment& env) const
268
 
     throw (SystemException) {
269
 
only in patch2:
270
 
unchanged:
271
 
--- suphp-0.6.2.orig/src/File.hpp
272
 
+++ suphp-0.6.2/src/File.hpp
273
 
@@ -143,7 +143,11 @@
274
 
         * Returns owning group of file
275
 
         */
276
 
        GroupInfo getGroup() const throw (SystemException);
277
 
-       
278
 
+
279
 
+        /**
280
 
+         * Checks whether this file is a symlink
281
 
+         */
282
 
+        bool isSymlink() const throw (SystemException);
283
 
     };
284
 
 };
285
 
 
286
 
only in patch2:
287
 
unchanged:
288
 
--- suphp-0.6.2.orig/src/API.hpp
289
 
+++ suphp-0.6.2/src/API.hpp
290
 
@@ -157,6 +157,12 @@
291
 
        virtual GroupInfo File_getGroup(const File& file) const
292
 
            throw (SystemException) =0;
293
 
        
294
 
+        /**
295
 
+         * Checks whether a file is a symlink
296
 
+         */
297
 
+        virtual bool File_isSymlink(const File& file) const 
298
 
+            throw (SystemException) =0;
299
 
+        
300
 
        /**
301
 
         * Runs another program (replaces current process)
302
 
         */