source: trunk/server/common/patches/httpd-suexec-scripts.patch @ 1169

Last change on this file since 1169 was 1169, checked in by geofft, 15 years ago
suexec: Hardcode the JAVA_TOOL_OPTIONS value. Because, otherwise, suexec doesn't save you from JAVA_TOOL_OPTIONS="-cp /path/to/sketchy/code.jar". Reported by Anders.
File size: 9.2 KB
  • httpd-2.2.2/support/Makefile.in

    # scripts.mit.edu httpd suexec patch
    # Copyright (C) 2006, 2007, 2008  Jeff Arnold <jbarnold@mit.edu>,
    #                                 Joe Presbrey <presbrey@mit.edu>,
    #                                 Anders Kaseorg <andersk@mit.edu>,
    #                                 Geoffrey Thomas <geofft@mit.edu>
    #
    # This program is free software; you can redistribute it and/or
    # modify it under the terms of the GNU General Public License
    # as published by the Free Software Foundation; either version 2
    # of the License, or (at your option) any later version.
    #
    # This program is distributed in the hope that it will be useful,
    # but WITHOUT ANY WARRANTY; without even the implied warranty of
    # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    # GNU General Public License for more details.
    #
    # You should have received a copy of the GNU General Public License
    # along with this program; if not, write to the Free Software
    # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
    #
    # See /COPYRIGHT in this repository for more information.
    #
    old new  
    6060
    6161suexec_OBJECTS = suexec.lo
    6262suexec: $(suexec_OBJECTS)
    63         $(LINK) $(suexec_OBJECTS)
     63        $(LINK) -lselinux $(suexec_OBJECTS)
    6464
    6565htcacheclean_OBJECTS = htcacheclean.lo
    6666htcacheclean: $(htcacheclean_OBJECTS)
  • httpd-2.2.2/configure.in

    old new  
    559559APACHE_HELP_STRING(--with-suexec-userdir,User subdirectory),[
    560560  AC_DEFINE_UNQUOTED(AP_USERDIR_SUFFIX, "$withval", [User subdirectory] ) ] )
    561561
     562AC_ARG_WITH(suexec-trusteddir,
     563APACHE_HELP_STRING(--with-suexec-trusteddir,Trusted SuExec directory),[
     564  AC_DEFINE_UNQUOTED(AP_TRUSTED_DIRECTORY, "$withval", [Trusted SuExec directory] ) ] )
     565
    562566AC_ARG_WITH(suexec-docroot,
    563567APACHE_HELP_STRING(--with-suexec-docroot,SuExec root directory),[
    564568  AC_DEFINE_UNQUOTED(AP_DOC_ROOT, "$withval", [SuExec root directory] ) ] )
  • httpd-2.2.2/support/suexec.c

    old new  
    3030 *
    3131 */
    3232
     33#define STATIC_CAT_PATH "/usr/local/bin/static-cat"
     34#define PHP_PATH "/usr/bin/php-cgi"
     35
    3336#include "apr.h"
    3437#include "ap_config.h"
    3538#include "suexec.h"
     
    4648#include <stdio.h>
    4749#include <stdarg.h>
    4850#include <stdlib.h>
     51#include <selinux/selinux.h>
    4952
    5053#ifdef HAVE_PWD_H
    5154#include <pwd.h>
     
    9598{
    9699    /* variable name starts with */
    97100    "HTTP_",
     101    "HTTPS_",
    98102    "SSL_",
    99103
    100104    /* variable name is */
     
    245250    environ = cleanenv;
    246251}
    247252
     253static const char *static_extensions[] = {
     254    "html",
     255    "css",
     256    "gif",
     257    "jpg",
     258    "png",
     259    "htm",
     260    "jpeg",
     261    "js",
     262    "ico",
     263    "xml",
     264    "xsl",
     265    "tiff",
     266    "tif",
     267    "tgz",
     268    "tar",
     269    "jar",
     270    "zip",
     271    "pdf",
     272    "ps",
     273    "doc",
     274    "xls",
     275    "ppt",
     276    "swf",
     277    "mp3",
     278    "mov",
     279    "wmv",
     280    "mpg",
     281    "mpeg",
     282    "avi",
     283    "il",
     284    "JPG",
     285    "xhtml",
     286    "svg",
     287    "xaml",
     288    "xap",
     289    NULL
     290};
     291
     292static int is_static_extension(const char *file)
     293{
     294    const char *extension = strrchr(file, '.');
     295    const char **p;
     296    if (extension == NULL) return 0;
     297    for (p = static_extensions; *p; ++p) {
     298        if (strcmp(extension + 1, *p) == 0) return 1;
     299    }
     300    return 0;
     301}
     302
     303static int is_php_extension(const char *file)
     304{
     305    const char *extension = strrchr(file, '.');
     306    if (extension == NULL) return 0;
     307    return strcmp(extension + 1, "php") == 0;
     308}
     309
    248310int main(int argc, char *argv[])
    249311{
    250312    int userdir = 0;        /* ~userdir flag             */
     313    int trusteddir = 0;     /* TRUSTED_DIRECTORY flag    */
    251314    uid_t uid;              /* user information          */
    252315    gid_t gid;              /* target group placeholder  */
    253316    char *target_uname;     /* target user name          */
     
    268331     * Start with a "clean" environment
    269332     */
    270333    clean_env();
     334    setenv("JAVA_TOOL_OPTIONS", "-Xmx128M", 1); /* scripts.mit.edu local hack */
    271335
    272336    prog = argv[0];
    273337    /*
     
    350406#endif /*_OSD_POSIX*/
    351407
    352408    /*
     409     * First check if this is an absolute path to the directory
     410     * of trusted executables. These are supposed to be security
     411     * audited to check parameters and validity on their own...
     412     */
     413    if (strstr(cmd, AP_TRUSTED_DIRECTORY) == cmd) {
     414        if (strstr(cmd, "/../") != NULL) {
     415            log_err("invalid command (%s)\n", cmd);
     416            exit(104);
     417        }
     418        trusteddir = 1;
     419        goto TRUSTED_DIRECTORY;
     420    }
     421
     422    /*
    353423     * Check for a leading '/' (absolute path) in the command to be executed,
    354424     * or attempts to back up out of the current directory,
    355425     * to protect against attacks.  If any are
     
    371441        userdir = 1;
    372442    }
    373443
     444TRUSTED_DIRECTORY:
    374445    /*
    375446     * Error out if the target username is invalid.
    376447     */
     
    450521     * Error out if attempt is made to execute as root or as
    451522     * a UID less than AP_UID_MIN.  Tsk tsk.
    452523     */
    453     if ((uid == 0) || (uid < AP_UID_MIN)) {
     524    if ((uid == 0) || (uid < AP_UID_MIN && uid != 102)) {
    454525        log_err("cannot run as forbidden uid (%d/%s)\n", uid, cmd);
    455526        exit(107);
    456527    }
     
    482553        log_err("failed to setuid (%ld: %s)\n", uid, cmd);
    483554        exit(110);
    484555    }
     556    if (is_selinux_enabled()) {
     557        if (uid == 102) {
     558            if (setexeccon("system_u:system_r:signup_t:s0") == -1) {
     559                log_err("failed to setexeccon (%ld: %s) to signup_t\n", uid, cmd);
     560                exit(201);
     561            }
     562        } else {
     563            if (setexeccon("user_u:user_r:user_t:s0") == -1) {
     564                log_err("failed to setexeccon (%ld: %s) to user_t\n", uid, cmd);
     565                exit(202);
     566            }
     567        }
     568    }
     569
     570    setenv("HOME", target_homedir, 1);
    485571
    486572    /*
    487573     * Get the current working directory, as well as the proper
     
    504588            log_err("cannot get docroot information (%s)\n", target_homedir);
    505589            exit(112);
    506590        }
     591        size_t expected_len = strlen(target_homedir)+1+strlen(AP_USERDIR_SUFFIX)+1;
     592        char *expected = malloc(expected_len);
     593        snprintf(expected, expected_len, "%s/%s", target_homedir, AP_USERDIR_SUFFIX);
     594        if (strncmp(cwd, expected, expected_len-1) != 0) {
     595            log_err("error: file's directory not a subdirectory of user's home directory (%s, %s)\n", cwd, expected);
     596            exit(114);
     597        }
     598    }
     599    else if (trusteddir) {
     600        if (((chdir(AP_TRUSTED_DIRECTORY)) != 0) ||
     601            ((getcwd(dwd, AP_MAXPATH)) == NULL) |
     602            ((chdir(cwd)) != 0)) {
     603            log_err("cannot get docroot information (%s)\n", AP_TRUSTED_DIRECTORY);
     604            exit(112);
     605        }
    507606    }
    508607    else {
    509608        if (((chdir(AP_DOC_ROOT)) != 0) ||
     
    530629    /*
    531630     * Error out if cwd is writable by others.
    532631     */
     632#if 0
    533633    if ((dir_info.st_mode & S_IWOTH) || (dir_info.st_mode & S_IWGRP)) {
    534634        log_err("directory is writable by others: (%s)\n", cwd);
    535635        exit(116);
    536636    }
     637#endif
    537638
    538639    /*
    539640     * Error out if we cannot stat the program.
    540641     */
    541     if (((lstat(cmd, &prg_info)) != 0) || (S_ISLNK(prg_info.st_mode))) {
     642    if (((lstat(cmd, &prg_info)) != 0) /*|| (S_ISLNK(prg_info.st_mode))*/) {
    542643        log_err("cannot stat program: (%s)\n", cmd);
    543644        exit(117);
    544645    }
     
    546647    /*
    547648     * Error out if the program is writable by others.
    548649     */
     650#if 0
    549651    if ((prg_info.st_mode & S_IWOTH) || (prg_info.st_mode & S_IWGRP)) {
    550652        log_err("file is writable by others: (%s/%s)\n", cwd, cmd);
    551653        exit(118);
    552654    }
     655#endif
    553656
    554657    /*
    555658     * Error out if the file is setuid or setgid.
     
    563666     * Error out if the target name/group is different from
    564667     * the name/group of the cwd or the program.
    565668     */
     669#if 0
    566670    if ((uid != dir_info.st_uid) ||
    567671        (gid != dir_info.st_gid) ||
    568672        (uid != prg_info.st_uid) ||
     
    574678                prg_info.st_uid, prg_info.st_gid);
    575679        exit(120);
    576680    }
     681#endif
    577682    /*
    578683     * Error out if the program is not executable for the user.
    579684     * Otherwise, she won't find any error in the logs except for
    580685     * "[error] Premature end of script headers: ..."
    581686     */
    582     if (!(prg_info.st_mode & S_IXUSR)) {
     687    if (!is_static_extension(cmd) && !is_php_extension(cmd) &&
     688        !(prg_info.st_mode & S_IXUSR)) {
    583689        log_err("file has no execute permission: (%s/%s)\n", cwd, cmd);
    584690        exit(121);
    585691    }
     
    606711      exit(122);
    607712    }
    608713
     714    if (is_static_extension(cmd)) {
     715        argv[2] = STATIC_CAT_PATH;
     716        execv(STATIC_CAT_PATH, &argv[2]);
     717        log_err("(%d)%s: static_cat exec failed (%s)\n", errno, strerror(errno), argv[2]);
     718        exit(255);
     719    }
     720    if (is_php_extension(cmd)) {
     721        setenv("PHPRC", ".", 1);
     722        argv[1] = PHP_PATH;
     723        argv[2] = "-f";
     724        execv(PHP_PATH, &argv[1]);
     725        log_err("(%d)%s: php exec failed (%s)\n", errno, strerror(errno), argv[2]);
     726        exit(255);
     727    }
     728
    609729    /*
    610730     * Execute the command, replacing our image with its own.
    611731     */
Note: See TracBrowser for help on using the repository browser.