| [1] | 1 | # scripts.mit.edu httpd suexec patch | 
|---|
| [315] | 2 | # Copyright (C) 2006, 2007  Jeff Arnold <jbarnold@mit.edu>, Joe Presbrey <presbrey@mit.edu>, Anders Kaseorg <andersk@mit.edu> | 
|---|
| [1] | 3 | # | 
|---|
|  | 4 | # This program is free software; you can redistribute it and/or | 
|---|
|  | 5 | # modify it under the terms of the GNU General Public License | 
|---|
|  | 6 | # as published by the Free Software Foundation; either version 2 | 
|---|
|  | 7 | # of the License, or (at your option) any later version. | 
|---|
|  | 8 | # | 
|---|
|  | 9 | # This program is distributed in the hope that it will be useful, | 
|---|
|  | 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | 
|---|
|  | 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
|---|
|  | 12 | # GNU General Public License for more details. | 
|---|
|  | 13 | # | 
|---|
|  | 14 | # You should have received a copy of the GNU General Public License | 
|---|
|  | 15 | # along with this program; if not, write to the Free Software | 
|---|
|  | 16 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA | 
|---|
|  | 17 | # | 
|---|
|  | 18 | # See /COPYRIGHT in this repository for more information. | 
|---|
|  | 19 | # | 
|---|
| [103] | 20 | --- httpd-2.2.2/support/Makefile.in.old 2005-07-06 19:15:34.000000000 -0400 | 
|---|
|  | 21 | +++ httpd-2.2.2/support/Makefile.in     2007-01-20 17:12:51.000000000 -0500 | 
|---|
|  | 22 | @@ -60,7 +60,7 @@ | 
|---|
|  | 23 |  | 
|---|
|  | 24 | suexec_OBJECTS = suexec.lo | 
|---|
|  | 25 | suexec: $(suexec_OBJECTS) | 
|---|
|  | 26 | -       $(LINK) $(suexec_OBJECTS) | 
|---|
|  | 27 | +       $(LINK) -lselinux $(suexec_OBJECTS) | 
|---|
|  | 28 |  | 
|---|
|  | 29 | htcacheclean_OBJECTS = htcacheclean.lo | 
|---|
|  | 30 | htcacheclean: $(htcacheclean_OBJECTS) | 
|---|
| [1] | 31 | --- httpd-2.2.2/support/suexec.c.old    2006-04-21 21:53:06.000000000 -0400 | 
|---|
| [315] | 32 | +++ httpd-2.2.2/support/suexec.c        2007-05-22 10:32:04.000000000 -0400 | 
|---|
| [298] | 33 | @@ -30,6 +30,8 @@ | 
|---|
|  | 34 | * | 
|---|
|  | 35 | */ | 
|---|
|  | 36 |  | 
|---|
|  | 37 | +#define STATIC_CAT_PATH "/usr/local/bin/static-cat" | 
|---|
|  | 38 | + | 
|---|
|  | 39 | #include "apr.h" | 
|---|
|  | 40 | #include "ap_config.h" | 
|---|
|  | 41 | #include "suexec.h" | 
|---|
|  | 42 | @@ -46,6 +48,7 @@ | 
|---|
| [103] | 43 | #include <stdio.h> | 
|---|
|  | 44 | #include <stdarg.h> | 
|---|
|  | 45 | #include <stdlib.h> | 
|---|
|  | 46 | +#include <selinux/selinux.h> | 
|---|
|  | 47 |  | 
|---|
|  | 48 | #ifdef HAVE_PWD_H | 
|---|
|  | 49 | #include <pwd.h> | 
|---|
| [405] | 50 | @@ -95,6 +98,7 @@ | 
|---|
| [1] | 51 | { | 
|---|
|  | 52 | /* variable name starts with */ | 
|---|
|  | 53 | "HTTP_", | 
|---|
|  | 54 | +    "HTTPS_", | 
|---|
|  | 55 | "SSL_", | 
|---|
|  | 56 |  | 
|---|
|  | 57 | /* variable name is */ | 
|---|
| [405] | 58 | @@ -140,6 +144,7 @@ | 
|---|
| [1] | 59 | "UNIQUE_ID=", | 
|---|
|  | 60 | "USER_NAME=", | 
|---|
|  | 61 | "TZ=", | 
|---|
|  | 62 | +    "PHPRC=", | 
|---|
|  | 63 | NULL | 
|---|
|  | 64 | }; | 
|---|
|  | 65 |  | 
|---|
| [618] | 66 | @@ -245,6 +250,54 @@ | 
|---|
| [298] | 67 | environ = cleanenv; | 
|---|
|  | 68 | } | 
|---|
|  | 69 |  | 
|---|
|  | 70 | +static const char *static_extensions[] = { | 
|---|
|  | 71 | +    "html", | 
|---|
|  | 72 | +    "css", | 
|---|
|  | 73 | +    "gif", | 
|---|
|  | 74 | +    "jpg", | 
|---|
|  | 75 | +    "png", | 
|---|
|  | 76 | +    "htm", | 
|---|
|  | 77 | +    "jpeg", | 
|---|
|  | 78 | +    "js", | 
|---|
|  | 79 | +    "ico", | 
|---|
|  | 80 | +    "xml", | 
|---|
|  | 81 | +    "xsl", | 
|---|
|  | 82 | +    "tiff", | 
|---|
|  | 83 | +    "tif", | 
|---|
|  | 84 | +    "tgz", | 
|---|
|  | 85 | +    "tar", | 
|---|
|  | 86 | +    "jar", | 
|---|
|  | 87 | +    "zip", | 
|---|
|  | 88 | +    "pdf", | 
|---|
|  | 89 | +    "ps", | 
|---|
|  | 90 | +    "doc", | 
|---|
|  | 91 | +    "xls", | 
|---|
|  | 92 | +    "ppt", | 
|---|
|  | 93 | +    "swf", | 
|---|
|  | 94 | +    "mp3", | 
|---|
|  | 95 | +    "mov", | 
|---|
|  | 96 | +    "wmv", | 
|---|
|  | 97 | +    "mpg", | 
|---|
|  | 98 | +    "mpeg", | 
|---|
|  | 99 | +    "avi", | 
|---|
|  | 100 | +    "il", | 
|---|
|  | 101 | +    "JPG", | 
|---|
| [315] | 102 | +    "xhtml", | 
|---|
| [618] | 103 | +    "svg", | 
|---|
| [298] | 104 | +    NULL | 
|---|
|  | 105 | +}; | 
|---|
|  | 106 | + | 
|---|
|  | 107 | +static int is_static_extension(const char *file) | 
|---|
|  | 108 | +{ | 
|---|
|  | 109 | +    const char *extension = strrchr(file, '.'); | 
|---|
|  | 110 | +    const char **p; | 
|---|
|  | 111 | +    if (extension == NULL) return 0; | 
|---|
|  | 112 | +    for (p = static_extensions; *p; ++p) { | 
|---|
|  | 113 | +        if (strcmp(extension + 1, *p) == 0) return 1; | 
|---|
|  | 114 | +    } | 
|---|
|  | 115 | +    return 0; | 
|---|
|  | 116 | +} | 
|---|
|  | 117 | + | 
|---|
|  | 118 | int main(int argc, char *argv[]) | 
|---|
|  | 119 | { | 
|---|
|  | 120 | int userdir = 0;        /* ~userdir flag             */ | 
|---|
| [405] | 121 | @@ -450,7 +501,7 @@ | 
|---|
| [103] | 122 | * Error out if attempt is made to execute as root or as | 
|---|
|  | 123 | * a UID less than AP_UID_MIN.  Tsk tsk. | 
|---|
|  | 124 | */ | 
|---|
|  | 125 | -    if ((uid == 0) || (uid < AP_UID_MIN)) { | 
|---|
|  | 126 | +    if ((uid == 0) || (uid < AP_UID_MIN && uid != 102)) { | 
|---|
|  | 127 | log_err("cannot run as forbidden uid (%d/%s)\n", uid, cmd); | 
|---|
|  | 128 | exit(107); | 
|---|
|  | 129 | } | 
|---|
| [406] | 130 | @@ -482,6 +533,19 @@ | 
|---|
| [103] | 131 | log_err("failed to setuid (%ld: %s)\n", uid, cmd); | 
|---|
|  | 132 | exit(110); | 
|---|
|  | 133 | } | 
|---|
| [406] | 134 | +    if (is_selinux_enabled()) { | 
|---|
|  | 135 | +        if (uid == 102) { | 
|---|
|  | 136 | +            if (setexeccon("system_u:system_r:signup_t:s0") == -1) { | 
|---|
|  | 137 | +                log_err("failed to setexeccon (%ld: %s) to signup_t\n", uid, cmd); | 
|---|
|  | 138 | +                exit(201); | 
|---|
|  | 139 | +            } | 
|---|
|  | 140 | +        } else { | 
|---|
|  | 141 | +            if (setexeccon("user_u:user_r:user_t:s0") == -1) { | 
|---|
|  | 142 | +                log_err("failed to setexeccon (%ld: %s) to user_t\n", uid, cmd); | 
|---|
|  | 143 | +                exit(202); | 
|---|
|  | 144 | +            } | 
|---|
| [405] | 145 | +        } | 
|---|
| [103] | 146 | +    } | 
|---|
|  | 147 |  | 
|---|
|  | 148 | /* | 
|---|
|  | 149 | * Get the current working directory, as well as the proper | 
|---|
| [405] | 150 | @@ -513,6 +575,13 @@ | 
|---|
| [1] | 151 | exit(113); | 
|---|
|  | 152 | } | 
|---|
|  | 153 | } | 
|---|
| [298] | 154 | +    size_t expected_len = strlen(target_homedir)+1+strlen(AP_USERDIR_SUFFIX)+1; | 
|---|
|  | 155 | +    char *expected = malloc(expected_len); | 
|---|
|  | 156 | +    snprintf(expected, expected_len, "%s/%s", target_homedir, AP_USERDIR_SUFFIX); | 
|---|
| [300] | 157 | +    if (strncmp(cwd, expected, expected_len-1) != 0) { | 
|---|
| [1] | 158 | +        log_err("error: file's directory not a subdirectory of user's home directory (%s, %s)\n", cwd, expected); | 
|---|
|  | 159 | +        exit(114); | 
|---|
|  | 160 | +    } | 
|---|
|  | 161 |  | 
|---|
|  | 162 | if ((strncmp(cwd, dwd, strlen(dwd))) != 0) { | 
|---|
|  | 163 | log_err("command not in docroot (%s/%s)\n", cwd, cmd); | 
|---|
| [405] | 164 | @@ -530,15 +598,17 @@ | 
|---|
| [1] | 165 | /* | 
|---|
|  | 166 | * Error out if cwd is writable by others. | 
|---|
|  | 167 | */ | 
|---|
|  | 168 | +#if 0 | 
|---|
|  | 169 | if ((dir_info.st_mode & S_IWOTH) || (dir_info.st_mode & S_IWGRP)) { | 
|---|
|  | 170 | log_err("directory is writable by others: (%s)\n", cwd); | 
|---|
|  | 171 | exit(116); | 
|---|
|  | 172 | } | 
|---|
|  | 173 | +#endif | 
|---|
|  | 174 |  | 
|---|
|  | 175 | /* | 
|---|
|  | 176 | * Error out if we cannot stat the program. | 
|---|
|  | 177 | */ | 
|---|
|  | 178 | -    if (((lstat(cmd, &prg_info)) != 0) || (S_ISLNK(prg_info.st_mode))) { | 
|---|
|  | 179 | +    if (((lstat(cmd, &prg_info)) != 0) /*|| (S_ISLNK(prg_info.st_mode))*/) { | 
|---|
|  | 180 | log_err("cannot stat program: (%s)\n", cmd); | 
|---|
|  | 181 | exit(117); | 
|---|
|  | 182 | } | 
|---|
| [405] | 183 | @@ -546,10 +616,12 @@ | 
|---|
| [1] | 184 | /* | 
|---|
|  | 185 | * Error out if the program is writable by others. | 
|---|
|  | 186 | */ | 
|---|
|  | 187 | +#if 0 | 
|---|
|  | 188 | if ((prg_info.st_mode & S_IWOTH) || (prg_info.st_mode & S_IWGRP)) { | 
|---|
|  | 189 | log_err("file is writable by others: (%s/%s)\n", cwd, cmd); | 
|---|
|  | 190 | exit(118); | 
|---|
|  | 191 | } | 
|---|
|  | 192 | +#endif | 
|---|
|  | 193 |  | 
|---|
|  | 194 | /* | 
|---|
|  | 195 | * Error out if the file is setuid or setgid. | 
|---|
| [405] | 196 | @@ -563,6 +635,7 @@ | 
|---|
| [1] | 197 | * Error out if the target name/group is different from | 
|---|
|  | 198 | * the name/group of the cwd or the program. | 
|---|
|  | 199 | */ | 
|---|
|  | 200 | +#if 0 | 
|---|
|  | 201 | if ((uid != dir_info.st_uid) || | 
|---|
|  | 202 | (gid != dir_info.st_gid) || | 
|---|
|  | 203 | (uid != prg_info.st_uid) || | 
|---|
| [405] | 204 | @@ -574,6 +647,7 @@ | 
|---|
| [1] | 205 | prg_info.st_uid, prg_info.st_gid); | 
|---|
|  | 206 | exit(120); | 
|---|
|  | 207 | } | 
|---|
|  | 208 | +#endif | 
|---|
|  | 209 | /* | 
|---|
|  | 210 | * Error out if the program is not executable for the user. | 
|---|
|  | 211 | * Otherwise, she won't find any error in the logs except for | 
|---|
| [405] | 212 | @@ -609,6 +683,13 @@ | 
|---|
| [298] | 213 | log = NULL; | 
|---|
|  | 214 | } | 
|---|
|  | 215 |  | 
|---|
|  | 216 | +    if (is_static_extension(cmd)) { | 
|---|
|  | 217 | +        argv[2] = STATIC_CAT_PATH; | 
|---|
|  | 218 | +        execv(STATIC_CAT_PATH, &argv[2]); | 
|---|
|  | 219 | +       log_err("(%d)%s: static_cat exec failed (%s)\n", errno, strerror(errno), argv[2]); | 
|---|
|  | 220 | +       exit(255); | 
|---|
|  | 221 | +    } | 
|---|
|  | 222 | + | 
|---|
|  | 223 | /* | 
|---|
|  | 224 | * Execute the command, replacing our image with its own. | 
|---|
|  | 225 | */ | 
|---|