dgaudet     97/06/26 19:21:25

  Modified:    src       Tag: APACHE_1_2_X  http_request.c mod_cern_meta.c
                        mod_dir.c
  Log:
  Ugh I messed up the security fixes commit.
  
  Revision  Changes    Path
  No                   revision
  
  
  No                   revision
  
  
  1.50.2.1  +41 -4     apache/src/http_request.c
  
  Index: http_request.c
  ===================================================================
  RCS file: /export/home/cvs/apache/src/http_request.c,v
  retrieving revision 1.50
  retrieving revision 1.50.2.1
  diff -C3 -r1.50 -r1.50.2.1
  *** http_request.c    1997/05/14 19:22:52     1.50
  --- http_request.c    1997/06/27 02:21:21     1.50.2.1
  ***************
  *** 85,90 ****
  --- 85,108 ----
     * they change, all the way down.
     */
    
  + 
  + /*
  +  * We don't want people able to serve up pipes, or unix sockets, or other
  +  * scary things.  Note that symlink tests are performed later.
  +  */
  + static int check_safe_file(request_rec *r)
  + {
  +     if (r->finfo.st_mode == 0               /* doesn't exist */
  +     || S_ISDIR (r->finfo.st_mode)
  +     || S_ISREG (r->finfo.st_mode)
  +     || S_ISLNK (r->finfo.st_mode)) {
  +     return OK;
  +     }
  +     log_reason("object is not a file, directory or symlink", r->filename, 
r);
  +     return HTTP_FORBIDDEN;
  + }
  + 
  + 
    int check_symlinks (char *d, int opts)
    {
        struct stat lfi, fi;
  ***************
  *** 310,320 ****
        if (res != OK) {
        return res;
        }
  !     
        if (test_filename[strlen(test_filename)-1] == '/')
        --num_dirs;
    
  !     if (S_ISDIR (r->finfo.st_mode)) ++num_dirs;
    
        for (i = 1; i <= num_dirs; ++i) {
            core_dir_config *core_dir =
  --- 328,344 ----
        if (res != OK) {
        return res;
        }
  ! 
  !     if ((res = check_safe_file(r))) {
  !     return res;
  !     }
  ! 
        if (test_filename[strlen(test_filename)-1] == '/')
        --num_dirs;
    
  !     if (S_ISDIR (r->finfo.st_mode)) {
  !     ++num_dirs;
  !     }
    
        for (i = 1; i <= num_dirs; ++i) {
            core_dir_config *core_dir =
  ***************
  *** 399,406 ****
    
        r->per_dir_config = per_dir_defaults;
    
  !     if ((res = check_symlinks (r->filename, allow_options(r))))
  !     {
        log_reason("Symbolic link not allowed", r->filename, r);
        return res;
        }
  --- 423,438 ----
    
        r->per_dir_config = per_dir_defaults;
    
  !     /* Symlink permissions are determined by the parent.  If the request is 
for
  !      * a directory then applying the symlink test here would use the
  !      * permissions of the directory as opposed to its parent.  Consider a
  !      * symlink pointing to a dir with a .htaccess disallowing symlinks.  If 
you
  !      * access /symlink (or /symlink/) you would get a 403 without this 
S_ISDIR
  !      * test.  But if you accessed /symlink/index.html, for example, you 
would
  !      * *not* get the 403.
  !      */
  !     if (!S_ISDIR (r->finfo.st_mode)
  !     && (res = check_symlinks (r->filename, allow_options(r)))) {
        log_reason("Symbolic link not allowed", r->filename, r);
        return res;
        }
  ***************
  *** 667,672 ****
  --- 699,709 ----
        rnew->filename = make_full_path (rnew->pool, fdir, new_file);
        if (stat (rnew->filename, &rnew->finfo) < 0) {
            rnew->finfo.st_mode = 0;
  +     }
  + 
  +     if ((res = check_safe_file(rnew))) {
  +         rnew->status = res;
  +         return rnew;
        }
    
        rnew->per_dir_config = r->per_dir_config;
  
  
  
  1.10.2.1  +14 -20    apache/src/mod_cern_meta.c
  
  Index: mod_cern_meta.c
  ===================================================================
  RCS file: /export/home/cvs/apache/src/mod_cern_meta.c,v
  retrieving revision 1.10
  retrieving revision 1.10.2.1
  diff -C3 -r1.10 -r1.10.2.1
  *** mod_cern_meta.c   1997/03/07 14:15:39     1.10
  --- mod_cern_meta.c   1997/06/27 02:21:22     1.10.2.1
  ***************
  *** 131,136 ****
  --- 131,137 ----
    #include <sys/stat.h>
    #include "util_script.h"
    #include "http_log.h"
  + #include "http_request.h"
    
    #define DEFAULT_METADIR             ".web"
    #define DEFAULT_METASUFFIX  ".meta"
  ***************
  *** 238,247 ****
        char *last_slash;
        char *real_file;
        char *scrap_book;
  -     struct stat meta_stat;
        FILE *f;   
        cern_meta_config *cmc ;
        int rv;
    
        cmc = get_module_config (r->server->module_config,
                               &cern_meta_module); 
  --- 239,248 ----
        char *last_slash;
        char *real_file;
        char *scrap_book;
        FILE *f;   
        cern_meta_config *cmc ;
        int rv;
  +     request_rec *rr;
    
        cmc = get_module_config (r->server->module_config,
                               &cern_meta_module); 
  ***************
  *** 276,305 ****
    
        metafilename = pstrcat(r->pool, "/", scrap_book, "/", cmc->metadir, 
"/", real_file, cmc->metasuffix, NULL);
    
  !     /*
  !      * stat can legitimately fail for a bewildering number of reasons,
  !      * only one of which implies the file isn't there.  A hardened
  !      * version of this module should test for all conditions, but later...
         */
  !     if (stat(metafilename, &meta_stat) == -1) {
  !     /* stat failed, possibly file missing */
        return DECLINED;
  !     };
  ! 
  !     /*
  !      * this check is to be found in other Jan/96 Apache code, I've
  !      * not been able to find any corroboration in the man pages but
  !      * I've been wrong before so I'll put it in anyway.  Never
  !      * admit to being clueless...
  !      */
  !     if ( meta_stat.st_mode == 0 ) {
  !     /* stat failed, definately file missing */
  !     return DECLINED;
  !     };
    
        f = pfopen (r->pool, metafilename, "r");
  -     
        if (f == NULL) {
            log_reason("meta file permissions deny server access", 
metafilename, r);
            return FORBIDDEN;
        };
  --- 277,299 ----
    
        metafilename = pstrcat(r->pool, "/", scrap_book, "/", cmc->metadir, 
"/", real_file, cmc->metasuffix, NULL);
    
  !     /* XXX: it sucks to require this subrequest to complete, because this
  !      * means people must leave their meta files accessible to the world.
  !      * A better solution might be a "safe open" feature of pfopen to avoid
  !      * pipes, symlinks, and crap like that.
         */
  !     rr = sub_req_lookup_file (metafilename, r);
  !     if (rr->status != HTTP_OK) {
  !     destroy_sub_req (rr);
        return DECLINED;
  !     }
  !     destroy_sub_req (rr);
    
        f = pfopen (r->pool, metafilename, "r");
        if (f == NULL) {
  +     if (errno == ENOENT) {
  +         return DECLINED;
  +     }
            log_reason("meta file permissions deny server access", 
metafilename, r);
            return FORBIDDEN;
        };
  
  
  
  1.26.2.1  +19 -0     apache/src/mod_dir.c
  
  Index: mod_dir.c
  ===================================================================
  RCS file: /export/home/cvs/apache/src/mod_dir.c,v
  retrieving revision 1.26
  retrieving revision 1.26.2.1
  diff -C3 -r1.26 -r1.26.2.1
  *** mod_dir.c 1997/05/13 04:01:50     1.26
  --- mod_dir.c 1997/06/27 02:21:22     1.26.2.1
  ***************
  *** 164,174 ****
  --- 164,180 ----
    }
    
    const char *add_header(cmd_parms *cmd, void *d, char *name) {
  +     if (strchr (name, '/')) {
  +     return "HeaderName cannot contain a /";
  +     }
        push_item(((dir_config_rec *)d)->hdr_list, 0, NULL, cmd->path, name);
        return NULL;
    }
    
    const char *add_readme(cmd_parms *cmd, void *d, char *name) {
  +     if (strchr (name, '/')) {
  +     return "ReadmeName cannot contain a /";
  +     }
        push_item(((dir_config_rec *)d)->rdme_list, 0, NULL, cmd->path, name);
        return NULL;
    }
  ***************
  *** 408,414 ****
  --- 414,422 ----
        FILE *f;
        struct stat finfo;
        int plaintext=0;
  +     request_rec *rr;
    
  +     /* XXX: this is a load of crap, it needs to do a full 
sub_req_lookup_uri */
        fn = make_full_path(r->pool, name, readme_fname);
        fn = pstrcat(r->pool, fn, ".html", NULL);
        if(stat(fn,&finfo) == -1) {
  ***************
  *** 421,426 ****
  --- 429,442 ----
            rputs("<PRE>\n", r);
        }
        else if (rule) rputs("<HR>\n", r);
  +     /* XXX: when the above is rewritten properly, this necessary security
  +      * check will be redundant. -djg */
  +     rr = sub_req_lookup_file (fn, r);
  +     if (rr->status != HTTP_OK) {
  +     destroy_sub_req (rr);
  +     return 0;
  +     }
  +     destroy_sub_req (rr);
        if(!(f = pfopen(r->pool,fn,"r")))
            return 0;
        if (!plaintext)
  ***************
  *** 462,467 ****
  --- 478,486 ----
        FILE *thefile = NULL;
        int x,y,n,p;
    
  +     if (r->status != HTTP_OK) {
  +     return NULL;
  +     }
        if (r->content_type && !strcmp(r->content_type,"text/html") && 
!r->content_encoding) {
            if(!(thefile = pfopen(r->pool, r->filename,"r")))
                return NULL;
  
  
  

Reply via email to