| [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 |   | 
|---|
| [405] | 66 | @@ -245,6 +250,53 @@ | 
|---|
| [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", | 
|---|
| [298] | 103 | +    NULL | 
|---|
 | 104 | +}; | 
|---|
 | 105 | + | 
|---|
 | 106 | +static int is_static_extension(const char *file) | 
|---|
 | 107 | +{ | 
|---|
 | 108 | +    const char *extension = strrchr(file, '.'); | 
|---|
 | 109 | +    const char **p; | 
|---|
 | 110 | +    if (extension == NULL) return 0; | 
|---|
 | 111 | +    for (p = static_extensions; *p; ++p) { | 
|---|
 | 112 | +        if (strcmp(extension + 1, *p) == 0) return 1; | 
|---|
 | 113 | +    } | 
|---|
 | 114 | +    return 0; | 
|---|
 | 115 | +} | 
|---|
 | 116 | + | 
|---|
 | 117 |  int main(int argc, char *argv[]) | 
|---|
 | 118 |  { | 
|---|
 | 119 |      int userdir = 0;        /* ~userdir flag             */ | 
|---|
| [405] | 120 | @@ -450,7 +501,7 @@ | 
|---|
| [103] | 121 |       * Error out if attempt is made to execute as root or as | 
|---|
 | 122 |       * a UID less than AP_UID_MIN.  Tsk tsk. | 
|---|
 | 123 |       */ | 
|---|
 | 124 | -    if ((uid == 0) || (uid < AP_UID_MIN)) { | 
|---|
 | 125 | +    if ((uid == 0) || (uid < AP_UID_MIN && uid != 102)) { | 
|---|
 | 126 |          log_err("cannot run as forbidden uid (%d/%s)\n", uid, cmd); | 
|---|
 | 127 |          exit(107); | 
|---|
 | 128 |      } | 
|---|
| [406] | 129 | @@ -482,6 +533,19 @@ | 
|---|
| [103] | 130 |          log_err("failed to setuid (%ld: %s)\n", uid, cmd); | 
|---|
 | 131 |          exit(110); | 
|---|
 | 132 |      } | 
|---|
| [406] | 133 | +    if (is_selinux_enabled()) { | 
|---|
 | 134 | +        if (uid == 102) { | 
|---|
 | 135 | +            if (setexeccon("system_u:system_r:signup_t:s0") == -1) { | 
|---|
 | 136 | +                log_err("failed to setexeccon (%ld: %s) to signup_t\n", uid, cmd); | 
|---|
 | 137 | +                exit(201); | 
|---|
 | 138 | +            } | 
|---|
 | 139 | +        } else { | 
|---|
 | 140 | +            if (setexeccon("user_u:user_r:user_t:s0") == -1) { | 
|---|
 | 141 | +                log_err("failed to setexeccon (%ld: %s) to user_t\n", uid, cmd); | 
|---|
 | 142 | +                exit(202); | 
|---|
 | 143 | +            } | 
|---|
| [405] | 144 | +        } | 
|---|
| [103] | 145 | +    } | 
|---|
 | 146 |   | 
|---|
 | 147 |      /* | 
|---|
 | 148 |       * Get the current working directory, as well as the proper | 
|---|
| [405] | 149 | @@ -513,6 +575,13 @@ | 
|---|
| [1] | 150 |              exit(113); | 
|---|
 | 151 |          } | 
|---|
 | 152 |      } | 
|---|
| [298] | 153 | +    size_t expected_len = strlen(target_homedir)+1+strlen(AP_USERDIR_SUFFIX)+1; | 
|---|
 | 154 | +    char *expected = malloc(expected_len); | 
|---|
 | 155 | +    snprintf(expected, expected_len, "%s/%s", target_homedir, AP_USERDIR_SUFFIX); | 
|---|
| [300] | 156 | +    if (strncmp(cwd, expected, expected_len-1) != 0) { | 
|---|
| [1] | 157 | +        log_err("error: file's directory not a subdirectory of user's home directory (%s, %s)\n", cwd, expected); | 
|---|
 | 158 | +        exit(114); | 
|---|
 | 159 | +    } | 
|---|
 | 160 |   | 
|---|
 | 161 |      if ((strncmp(cwd, dwd, strlen(dwd))) != 0) { | 
|---|
 | 162 |          log_err("command not in docroot (%s/%s)\n", cwd, cmd); | 
|---|
| [405] | 163 | @@ -530,15 +598,17 @@ | 
|---|
| [1] | 164 |      /* | 
|---|
 | 165 |       * Error out if cwd is writable by others. | 
|---|
 | 166 |       */ | 
|---|
 | 167 | +#if 0 | 
|---|
 | 168 |      if ((dir_info.st_mode & S_IWOTH) || (dir_info.st_mode & S_IWGRP)) { | 
|---|
 | 169 |          log_err("directory is writable by others: (%s)\n", cwd); | 
|---|
 | 170 |          exit(116); | 
|---|
 | 171 |      } | 
|---|
 | 172 | +#endif | 
|---|
 | 173 |   | 
|---|
 | 174 |      /* | 
|---|
 | 175 |       * Error out if we cannot stat the program. | 
|---|
 | 176 |       */ | 
|---|
 | 177 | -    if (((lstat(cmd, &prg_info)) != 0) || (S_ISLNK(prg_info.st_mode))) { | 
|---|
 | 178 | +    if (((lstat(cmd, &prg_info)) != 0) /*|| (S_ISLNK(prg_info.st_mode))*/) { | 
|---|
 | 179 |          log_err("cannot stat program: (%s)\n", cmd); | 
|---|
 | 180 |          exit(117); | 
|---|
 | 181 |      } | 
|---|
| [405] | 182 | @@ -546,10 +616,12 @@ | 
|---|
| [1] | 183 |      /* | 
|---|
 | 184 |       * Error out if the program is writable by others. | 
|---|
 | 185 |       */ | 
|---|
 | 186 | +#if 0 | 
|---|
 | 187 |      if ((prg_info.st_mode & S_IWOTH) || (prg_info.st_mode & S_IWGRP)) { | 
|---|
 | 188 |          log_err("file is writable by others: (%s/%s)\n", cwd, cmd); | 
|---|
 | 189 |          exit(118); | 
|---|
 | 190 |      } | 
|---|
 | 191 | +#endif | 
|---|
 | 192 |   | 
|---|
 | 193 |      /* | 
|---|
 | 194 |       * Error out if the file is setuid or setgid. | 
|---|
| [405] | 195 | @@ -563,6 +635,7 @@ | 
|---|
| [1] | 196 |       * Error out if the target name/group is different from | 
|---|
 | 197 |       * the name/group of the cwd or the program. | 
|---|
 | 198 |       */ | 
|---|
 | 199 | +#if 0 | 
|---|
 | 200 |      if ((uid != dir_info.st_uid) || | 
|---|
 | 201 |          (gid != dir_info.st_gid) || | 
|---|
 | 202 |          (uid != prg_info.st_uid) || | 
|---|
| [405] | 203 | @@ -574,6 +647,7 @@ | 
|---|
| [1] | 204 |                  prg_info.st_uid, prg_info.st_gid); | 
|---|
 | 205 |          exit(120); | 
|---|
 | 206 |      } | 
|---|
 | 207 | +#endif | 
|---|
 | 208 |      /* | 
|---|
 | 209 |       * Error out if the program is not executable for the user. | 
|---|
 | 210 |       * Otherwise, she won't find any error in the logs except for | 
|---|
| [405] | 211 | @@ -609,6 +683,13 @@ | 
|---|
| [298] | 212 |          log = NULL; | 
|---|
 | 213 |      } | 
|---|
 | 214 |   | 
|---|
 | 215 | +    if (is_static_extension(cmd)) { | 
|---|
 | 216 | +        argv[2] = STATIC_CAT_PATH; | 
|---|
 | 217 | +        execv(STATIC_CAT_PATH, &argv[2]); | 
|---|
 | 218 | +       log_err("(%d)%s: static_cat exec failed (%s)\n", errno, strerror(errno), argv[2]); | 
|---|
 | 219 | +       exit(255); | 
|---|
 | 220 | +    } | 
|---|
 | 221 | + | 
|---|
 | 222 |      /* | 
|---|
 | 223 |       * Execute the command, replacing our image with its own. | 
|---|
 | 224 |       */ | 
|---|