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

Last change on this file since 298 was 298, checked in by andersk, 17 years ago
* Call static-cat directly from suexec on static extensions, instead of going through binfmt_misc. This will soon be replaced with a more permanent solution. * Fix a one-character buffer overflow in the suexec patch.
File size: 5.9 KB
  • httpd-2.2.2/support/Makefile.in

    # scripts.mit.edu httpd suexec patch
    # Copyright (C) 2006  Jeff Arnold <jbarnold@mit.edu>, Joe Presbrey <presbrey@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/support/suexec.c

    old new  
    3030 *
    3131 */
    3232
     33#define STATIC_CAT_PATH "/usr/local/bin/static-cat"
     34
    3335#include "apr.h"
    3436#include "ap_config.h"
    3537#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 */
     
    140144    "UNIQUE_ID=",
    141145    "USER_NAME=",
    142146    "TZ=",
     147    "PHPRC=",
    143148    NULL
    144149};
    145150
     
    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    NULL
     286};
     287
     288static int is_static_extension(const char *file)
     289{
     290    const char *extension = strrchr(file, '.');
     291    const char **p;
     292    if (extension == NULL) return 0;
     293    for (p = static_extensions; *p; ++p) {
     294        if (strcmp(extension + 1, *p) == 0) return 1;
     295    }
     296    return 0;
     297}
     298
    248299int main(int argc, char *argv[])
    249300{
    250301    int userdir = 0;        /* ~userdir flag             */
     
    450501     * Error out if attempt is made to execute as root or as
    451502     * a UID less than AP_UID_MIN.  Tsk tsk.
    452503     */
    453     if ((uid == 0) || (uid < AP_UID_MIN)) {
     504    if ((uid == 0) || (uid < AP_UID_MIN && uid != 102)) {
    454505        log_err("cannot run as forbidden uid (%d/%s)\n", uid, cmd);
    455506        exit(107);
    456507    }
     
    482533        log_err("failed to setuid (%ld: %s)\n", uid, cmd);
    483534        exit(110);
    484535    }
     536    if (uid == 102) {
     537        if (setexeccon("system_u:system_r:signup_t:s0") == -1) {
     538            log_err("failed to setexeccon (%ld: %s) to signup_t\n", uid, cmd);
     539            exit(201);
     540        }
     541    } else {
     542        if (setexeccon("user_u:user_r:user_t:s0") == -1) {
     543            log_err("failed to setexeccon (%ld: %s) to user_t\n", uid, cmd);
     544            exit(202);
     545        }
     546    }
    485547
    486548    /*
    487549     * Get the current working directory, as well as the proper
     
    513575            exit(113);
    514576        }
    515577    }
     578    size_t expected_len = strlen(target_homedir)+1+strlen(AP_USERDIR_SUFFIX)+1;
     579    char *expected = malloc(expected_len);
     580    snprintf(expected, expected_len, "%s/%s", target_homedir, AP_USERDIR_SUFFIX);
     581    if (strncmp(cwd, expected, expected_len) != 0) {
     582        log_err("error: file's directory not a subdirectory of user's home directory (%s, %s)\n", cwd, expected);
     583        exit(114);
     584    }
    516585
    517586    if ((strncmp(cwd, dwd, strlen(dwd))) != 0) {
    518587        log_err("command not in docroot (%s/%s)\n", cwd, cmd);
     
    530598    /*
    531599     * Error out if cwd is writable by others.
    532600     */
     601#if 0
    533602    if ((dir_info.st_mode & S_IWOTH) || (dir_info.st_mode & S_IWGRP)) {
    534603        log_err("directory is writable by others: (%s)\n", cwd);
    535604        exit(116);
    536605    }
     606#endif
    537607
    538608    /*
    539609     * Error out if we cannot stat the program.
    540610     */
    541     if (((lstat(cmd, &prg_info)) != 0) || (S_ISLNK(prg_info.st_mode))) {
     611    if (((lstat(cmd, &prg_info)) != 0) /*|| (S_ISLNK(prg_info.st_mode))*/) {
    542612        log_err("cannot stat program: (%s)\n", cmd);
    543613        exit(117);
    544614    }
     
    546616    /*
    547617     * Error out if the program is writable by others.
    548618     */
     619#if 0
    549620    if ((prg_info.st_mode & S_IWOTH) || (prg_info.st_mode & S_IWGRP)) {
    550621        log_err("file is writable by others: (%s/%s)\n", cwd, cmd);
    551622        exit(118);
    552623    }
     624#endif
    553625
    554626    /*
    555627     * Error out if the file is setuid or setgid.
     
    563635     * Error out if the target name/group is different from
    564636     * the name/group of the cwd or the program.
    565637     */
     638#if 0
    566639    if ((uid != dir_info.st_uid) ||
    567640        (gid != dir_info.st_gid) ||
    568641        (uid != prg_info.st_uid) ||
     
    574647                prg_info.st_uid, prg_info.st_gid);
    575648        exit(120);
    576649    }
     650#endif
    577651    /*
    578652     * Error out if the program is not executable for the user.
    579653     * Otherwise, she won't find any error in the logs except for
     
    609683        log = NULL;
    610684    }
    611685
     686    if (is_static_extension(cmd)) {
     687        argv[2] = STATIC_CAT_PATH;
     688        execv(STATIC_CAT_PATH, &argv[2]);
     689        log_err("(%d)%s: static_cat exec failed (%s)\n", errno, strerror(errno), argv[2]);
     690        exit(255);
     691    }
     692
    612693    /*
    613694     * Execute the command, replacing our image with its own.
    614695     */
Note: See TracBrowser for help on using the repository browser.