]> git.ipfire.org Git - thirdparty/apache/httpd.git/commitdiff
Where the OS allows, we now proactively use the various _ex and
authorJim Jagielski <jim@apache.org>
Thu, 12 Dec 2002 16:09:52 +0000 (16:09 +0000)
committerJim Jagielski <jim@apache.org>
Thu, 12 Dec 2002 16:09:52 +0000 (16:09 +0000)
magic cleanups to close fds (lock files, log files and sockets)
to prevent them from leaking into 3rd party modules that don't
call ap_cleanup_for_exec() before forking off subprocesses.

Expect some possible fine-tuning.

Obtained from:
Submitted by:
Reviewed by:

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/1.3.x@97896 13f79535-47bb-0310-9956-ffa450edef68

14 files changed:
src/CHANGES
src/include/ap_alloc.h
src/include/ap_mmn.h
src/main/alloc.c
src/main/http_main.c
src/main/rfc1413.c
src/modules/proxy/proxy_connect.c
src/modules/proxy/proxy_ftp.c
src/modules/proxy/proxy_http.c
src/modules/standard/mod_log_agent.c
src/modules/standard/mod_log_config.c
src/modules/standard/mod_log_referer.c
src/modules/standard/mod_rewrite.c
src/os/netware/mod_log_nw.c

index 8924db7f7367f5c3dde2943793aac1f7a24dc495..8281ab2fe060f8c878d92bbd48959b53b985bc11 100644 (file)
@@ -1,5 +1,14 @@
 Changes with Apache 1.3.28
 
+  *) Certain 3rd party modules would bypass the Apache API and not
+     invoke ap_cleanup_for_exec() before creating sub-processes.
+     To such a child process, Apache's file descriptors (lock
+     fd's, log files, sockets) were accessible, allowing them
+     direct access to Apache log file etc.  Where the OS allows,
+     we now add proactive close functions to prevent these file
+     descriptors from leaking to the child processes.
+     [Jim Jagielski, Martin Kraemer]
+
   *) Prevent obscenely large values of precision in ap_vformatter
      from clobbering a buffer. [Sander Striker, Jim Jagielski]
 
index 738f9d441bb2b154d8ec0042d55bdb265efedfa9..cb284c526d5812524dd7a1ebc48459ee4c9ccfce 100644 (file)
@@ -337,6 +337,8 @@ API_EXPORT(void) ap_unblock_alarms(void);
 API_EXPORT(FILE *) ap_pfopen(struct pool *, const char *name, const char *fmode);
 API_EXPORT(FILE *) ap_pfdopen(struct pool *, int fd, const char *fmode);
 API_EXPORT(int) ap_popenf(struct pool *, const char *name, int flg, int mode);
+API_EXPORT(int) ap_popenf_ex(struct pool *, const char *name, int flg,
+                             int mode, int domagic);
 
 API_EXPORT(void) ap_note_cleanups_for_file(pool *, FILE *);
 API_EXPORT(void) ap_note_cleanups_for_file_ex(pool *, FILE *, int);
@@ -351,6 +353,7 @@ API_EXPORT(void) ap_note_cleanups_for_socket(pool *, int);
 API_EXPORT(void) ap_note_cleanups_for_socket_ex(pool *, int, int);
 API_EXPORT(void) ap_kill_cleanups_for_socket(pool *p, int sock);
 API_EXPORT(int) ap_psocket(pool *p, int, int, int);
+API_EXPORT(int) ap_psocket_ex(pool *p, int, int, int, int);
 API_EXPORT(int) ap_pclosesocket(pool *a, int sock);
 
 API_EXPORT(regex_t *) ap_pregcomp(pool *p, const char *pattern, int cflags);
index 1043634d0f1b3473209d8cd3d112bdf28f967d48..81ca8fa45fc3c8e8b326408201ce9f318c00e9f5 100644 (file)
  * 19990320.13          - add ap_strtol()
  * 19990320.14          - add ap_register_cleanup_ex(),
  *                        ap_note_cleanups_for_fd_ex(),
- *                        ap_note_cleanups_for_socket_ex() and
- *                        ap_note_cleanups_for_file_ex()
+ *                        ap_note_cleanups_for_socket_ex(),
+ *                        ap_note_cleanups_for_file_ex(),
+ *                        ap_popenf_ex() and ap_psocket_ex().
  */
 
 #define MODULE_MAGIC_COOKIE 0x41503133UL /* "AP13" */
index 3b7165aa88089a956e919a5e4e77c3321c61db96..94bb6d0c36ef9c843cc5765ae5864b221b977bd5 100644 (file)
@@ -1687,14 +1687,19 @@ API_EXPORT(void) ap_register_cleanup_ex(pool *p, void *data,
                                      void (*child_cleanup) (void *),
                                      int (*magic_cleanup) (void *))
 {
-    struct cleanup *c = (struct cleanup *) ap_palloc(p, sizeof(struct cleanup));
-    c->data = data;
-    c->plain_cleanup = plain_cleanup;
-    c->child_cleanup = child_cleanup;
-    c->next = p->cleanups;
-    p->cleanups = c;
-    if(magic_cleanup) {
-       if(!magic_cleanup(data)) 
+    struct cleanup *c;
+    if (p) {
+       c = (struct cleanup *) ap_palloc(p, sizeof(struct cleanup));
+       c->data = data;
+       c->plain_cleanup = plain_cleanup;
+       c->child_cleanup = child_cleanup;
+       c->next = p->cleanups;
+       p->cleanups = c;
+    }
+    /* attempt to do magic even if not passed a pool. Allows us
+     * to perform the magic, therefore, "whenever" we want/need */
+    if (magic_cleanup) {
+       if (!magic_cleanup(data)) 
           ap_log_error(APLOG_MARK, APLOG_WARNING, NULL,
                 "exec() may not be safe");
     }
@@ -1827,7 +1832,8 @@ API_EXPORT(void) ap_kill_cleanups_for_fd(pool *p, int fd)
     ap_kill_cleanup(p, (void *) (long) fd, fd_cleanup);
 }
 
-API_EXPORT(int) ap_popenf(pool *a, const char *name, int flg, int mode)
+API_EXPORT(int) ap_popenf_ex(pool *a, const char *name, int flg, int mode,
+                             int domagic)
 {
     int fd;
     int save_errno;
@@ -1837,13 +1843,18 @@ API_EXPORT(int) ap_popenf(pool *a, const char *name, int flg, int mode)
     save_errno = errno;
     if (fd >= 0) {
        fd = ap_slack(fd, AP_SLACK_HIGH);
-       ap_note_cleanups_for_fd(a, fd);
+       ap_note_cleanups_for_fd_ex(a, fd, domagic);
     }
     ap_unblock_alarms();
     errno = save_errno;
     return fd;
 }
 
+API_EXPORT(int) ap_popenf(pool *a, const char *name, int flg, int mode)
+{
+    return ap_popenf_ex(a, name, flg, mode, 0);
+}
+
 API_EXPORT(int) ap_pclosef(pool *a, int fd)
 {
     int res;
@@ -2047,7 +2058,8 @@ API_EXPORT(void) ap_kill_cleanups_for_socket(pool *p, int sock)
     ap_kill_cleanup(p, (void *) (long) sock, socket_cleanup);
 }
 
-API_EXPORT(int) ap_psocket(pool *p, int domain, int type, int protocol)
+API_EXPORT(int) ap_psocket_ex(pool *p, int domain, int type, int protocol,
+                              int domagic)
 {
     int fd;
 
@@ -2059,11 +2071,16 @@ API_EXPORT(int) ap_psocket(pool *p, int domain, int type, int protocol)
        errno = save_errno;
        return -1;
     }
-    ap_note_cleanups_for_socket(p, fd);
+    ap_note_cleanups_for_socket_ex(p, fd, domagic);
     ap_unblock_alarms();
     return fd;
 }
 
+API_EXPORT(int) ap_psocket(pool *p, int domain, int type, int protocol)
+{
+    return ap_psocket_ex(p, domain, type, protocol, 0);
+}
+
 API_EXPORT(int) ap_pclosesocket(pool *a, int sock)
 {
     int res;
index 34e7d6d7396f2e196a282f6df4d585bf3b41f1e4..50bad3cdcbb6bbec6ae32baa9003af5df006ecd8 100644 (file)
@@ -876,7 +876,7 @@ static void accept_mutex_init_fcntl(pool *p)
     unlock_it.l_pid = 0;               /* pid not actually interesting */
 
     expand_lock_fname(p);
-    lock_fd = ap_popenf(p, ap_lock_fname, O_CREAT | O_WRONLY | O_EXCL, 0644);
+    lock_fd = ap_popenf_ex(p, ap_lock_fname, O_CREAT | O_WRONLY | O_EXCL, 0644, 1);
     if (lock_fd == -1) {
        perror("open");
        fprintf(stderr, "Cannot open lock file: %s\n", ap_lock_fname);
@@ -943,7 +943,7 @@ static void accept_mutex_cleanup_flock(void *foo)
 static void accept_mutex_child_init_flock(pool *p)
 {
 
-    flock_fd = ap_popenf(p, ap_lock_fname, O_WRONLY, 0600);
+    flock_fd = ap_popenf_ex(p, ap_lock_fname, O_WRONLY, 0600, 1);
     if (flock_fd == -1) {
        ap_log_error(APLOG_MARK, APLOG_EMERG, server_conf,
                    "Child cannot open lock file: %s", ap_lock_fname);
@@ -959,7 +959,7 @@ static void accept_mutex_init_flock(pool *p)
 {
     expand_lock_fname(p);
     unlink(ap_lock_fname);
-    flock_fd = ap_popenf(p, ap_lock_fname, O_CREAT | O_WRONLY | O_EXCL, 0600);
+    flock_fd = ap_popenf_ex(p, ap_lock_fname, O_CREAT | O_WRONLY | O_EXCL, 0600, 1);
     if (flock_fd == -1) {
        ap_log_error(APLOG_MARK, APLOG_EMERG, server_conf,
                    "Parent cannot open lock file: %s", ap_lock_fname);
@@ -2457,7 +2457,7 @@ void reopen_scoreboard(pool *p)
 #ifdef TPF
     ap_scoreboard_fname = ap_server_root_relative(p, ap_scoreboard_fname);
 #endif /* TPF */
-    scoreboard_fd = ap_popenf(p, ap_scoreboard_fname, O_CREAT | O_BINARY | O_RDWR, 0666);
+    scoreboard_fd = ap_popenf_ex(p, ap_scoreboard_fname, O_CREAT | O_BINARY | O_RDWR, 0666, 1);
     if (scoreboard_fd == -1) {
        perror(ap_scoreboard_fname);
        fprintf(stderr, "Cannot open scoreboard file:\n");
@@ -2483,7 +2483,7 @@ static void reinit_scoreboard(pool *p)
     ap_scoreboard_image = &_scoreboard_image;
     ap_scoreboard_fname = ap_server_root_relative(p, ap_scoreboard_fname);
 
-    scoreboard_fd = ap_popenf(p, ap_scoreboard_fname, O_CREAT | O_BINARY | O_RDWR, 0644);
+    scoreboard_fd = ap_popenf_ex(p, ap_scoreboard_fname, O_CREAT | O_BINARY | O_RDWR, 0644, 1);
     if (scoreboard_fd == -1) {
        perror(ap_scoreboard_fname);
        fprintf(stderr, "Cannot open scoreboard file:\n");
@@ -3655,7 +3655,7 @@ static int make_sock(pool *p, const struct sockaddr_in *server)
     s = ap_slack(s, AP_SLACK_HIGH);
 #endif
 
-    ap_note_cleanups_for_socket(p, s); /* arrange to close on exec or restart */
+    ap_note_cleanups_for_socket_ex(p, s, 1);   /* arrange to close on exec or restart */
 #ifdef TPF
     os_note_additional_cleanups(p, s);
 #endif /* TPF */
@@ -3796,7 +3796,7 @@ static int make_sock(pool *p, const struct sockaddr_in *server)
 #ifdef WORKAROUND_SOLARIS_BUG
     s = ap_slack(s, AP_SLACK_HIGH);
 
-    ap_note_cleanups_for_socket(p, s); /* arrange to close on exec or restart */
+    ap_note_cleanups_for_socket_ex(p, s, 1);   /* arrange to close on exec or restart */
 #endif
     ap_unblock_alarms();
 
@@ -3903,7 +3903,7 @@ static void setup_listeners(pool *p)
            fd = make_sock(p, &lr->local_addr);
        }
        else {
-           ap_note_cleanups_for_socket(p, fd);
+           ap_note_cleanups_for_socket_ex(p, fd, 1);
        }
        /* if we get here, (fd >= 0) && (fd < FD_SETSIZE) */
        FD_SET(fd, &listenfds);
@@ -4517,7 +4517,7 @@ static void child_main(int child_num_arg)
         */
        signal(SIGUSR1, SIG_IGN);
 
-       ap_note_cleanups_for_socket(ptrans, csd);
+       ap_note_cleanups_for_socket_ex(ptrans, csd, 1);
 
        /* protect various fd_sets */
 #ifdef CHECK_FD_SETSIZE
@@ -4565,7 +4565,7 @@ static void child_main(int child_num_arg)
                        "dup: couldn't duplicate csd");
            dupped_csd = csd;   /* Oh well... */
        }
-       ap_note_cleanups_for_socket(ptrans, dupped_csd);
+       ap_note_cleanups_for_socket_ex(ptrans, dupped_csd, 1);
 
        /* protect various fd_sets */
 #ifdef CHECK_FD_SETSIZE
@@ -5092,7 +5092,7 @@ static void standalone_main(int argc, char **argv)
 #ifdef SCOREBOARD_FILE
        else {
            ap_scoreboard_fname = ap_server_root_relative(pconf, ap_scoreboard_fname);
-           ap_note_cleanups_for_fd(pconf, scoreboard_fd);
+           ap_note_cleanups_for_fd_ex(pconf, scoreboard_fd, 1); /* close on exec */
        }
 #endif
 
@@ -5892,7 +5892,7 @@ static void child_sub_main(int child_num)
 
        requests_this_child++;
 
-       ap_note_cleanups_for_socket(ptrans, csd);
+       ap_note_cleanups_for_socket_ex(ptrans, csd, 1);
 
        /*
         * We now have a connection, so set it up with the appropriate
@@ -5924,7 +5924,7 @@ static void child_sub_main(int child_num)
                        "dup: couldn't duplicate csd");
            dupped_csd = csd;   /* Oh well... */
        }
-       ap_note_cleanups_for_socket(ptrans, dupped_csd);
+       ap_note_cleanups_for_socket_ex(ptrans, dupped_csd, 1);
 #endif
        ap_bpushfd(conn_io, csd, dupped_csd);
 
@@ -6140,7 +6140,7 @@ static void setup_inherited_listeners(pool *p)
             if (fd > listenmaxfd)
                 listenmaxfd = fd;
         }
-        ap_note_cleanups_for_socket(p, fd);
+        ap_note_cleanups_for_socket_ex(p, fd, 1);
         lr->fd = fd;
         if (lr->next == NULL) {
             /* turn the list into a ring */
index e115d0e39786df2fd33baa527997b9e3222aab4c..628bec7bac2803dc77a2894baf0c8b0532b410b9 100644 (file)
@@ -243,7 +243,7 @@ API_EXPORT(char *) ap_rfc1413(conn_rec *conn, server_rec *srv)
 
     result = FROM_UNKNOWN;
 
-    sock = ap_psocket(conn->pool, AF_INET, SOCK_STREAM, IPPROTO_TCP);
+    sock = ap_psocket_ex(conn->pool, AF_INET, SOCK_STREAM, IPPROTO_TCP, 1);
     if (sock < 0) {
        ap_log_error(APLOG_MARK, APLOG_CRIT, srv,
                    "socket: rfc1413: error creating socket");
index 9b955d5177621453a8c6edaef30831c9389a22d5..7ae9af9ee9adeee51f7fa9e40c560947cda1dd61 100644 (file)
@@ -182,7 +182,7 @@ int ap_proxy_connect_handler(request_rec *r, cache_req *c, char *url,
         return ap_proxyerror(r,
             proxyhost ? HTTP_BAD_GATEWAY : HTTP_INTERNAL_SERVER_ERROR, err);
 
-    sock = ap_psocket(r->pool, PF_INET, SOCK_STREAM, IPPROTO_TCP);
+    sock = ap_psocket_ex(r->pool, PF_INET, SOCK_STREAM, IPPROTO_TCP, 1);
     if (sock == -1) {
         ap_log_rerror(APLOG_MARK, APLOG_ERR, r, "proxy: error creating socket");
         return HTTP_INTERNAL_SERVER_ERROR;
index 076d23b00a75dd84b2b9278a36fb6ba0f703f57e..f01b890d6bb8fa6f64e4d9a389ede41d3ae8cce9 100644 (file)
@@ -665,7 +665,7 @@ int ap_proxy_ftp_handler(request_rec *r, cache_req *c, char *url)
     if (err != NULL)
         return ap_proxyerror(r, HTTP_INTERNAL_SERVER_ERROR, err);
 
-    sock = ap_psocket(p, PF_INET, SOCK_STREAM, IPPROTO_TCP);
+    sock = ap_psocket_ex(p, PF_INET, SOCK_STREAM, IPPROTO_TCP, 1);
     if (sock == -1) {
         ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
                       "proxy: error creating socket");
@@ -944,7 +944,7 @@ int ap_proxy_ftp_handler(request_rec *r, cache_req *c, char *url)
     }
 
 /* try to set up PASV data connection first */
-    dsock = ap_psocket(p, PF_INET, SOCK_STREAM, IPPROTO_TCP);
+    dsock = ap_psocket_ex(p, PF_INET, SOCK_STREAM, IPPROTO_TCP, 1);
     if (dsock == -1) {
         return ftp_cleanup_and_return(r, ctrl, data, sock, dsock,
                                 ap_proxyerror(r, HTTP_INTERNAL_SERVER_ERROR,
@@ -1032,7 +1032,7 @@ int ap_proxy_ftp_handler(request_rec *r, cache_req *c, char *url)
                                     "proxy: error getting socket address"));
         }
 
-        dsock = ap_psocket(p, PF_INET, SOCK_STREAM, IPPROTO_TCP);
+        dsock = ap_psocket_ex(p, PF_INET, SOCK_STREAM, IPPROTO_TCP, 1);
         if (dsock == -1) {
             return ftp_cleanup_and_return(r, ctrl, data, sock, dsock,
                                 ap_proxyerror(r, HTTP_INTERNAL_SERVER_ERROR,
index a11688d8a8c206a1cbdef06b2fbf2d5f834bd81a..db6ce82910eefaef5decfbe8e9d665a3784a2bba 100644 (file)
@@ -241,7 +241,7 @@ int ap_proxy_http_handler(request_rec *r, cache_req *c, char *url,
      * we have worked out who exactly we are going to connect to, now make
      * that connection...
      */
-    sock = ap_psocket(p, PF_INET, SOCK_STREAM, IPPROTO_TCP);
+    sock = ap_psocket_ex(p, PF_INET, SOCK_STREAM, IPPROTO_TCP, 1);
     if (sock == -1) {
         ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
                       "proxy: error creating socket");
index fde6b917eb424341b1f810ab8165c414a6926c02..ac7e6ca739d90d50c74047e278556860c27e2751 100644 (file)
@@ -125,7 +125,8 @@ static void open_agent_log(server_rec *s, pool *p)
         cls->agent_fd = ap_piped_log_write_fd(pl);
     }
     else if (*cls->fname != '\0') {
-        if ((cls->agent_fd = ap_popenf(p, fname, xfer_flags, xfer_mode)) < 0) {
+        if ((cls->agent_fd = ap_popenf_ex(p, fname, xfer_flags, xfer_mode, 1))
+             < 0) {
             ap_log_error(APLOG_MARK, APLOG_ERR, s,
                          "could not open agent log file %s.", fname);
             exit(1);
index 078a060253dbe9d4cc99e6318fd134eb8b845f80..ceeffc3333df63ba54cda064b4ab55be6c192d27 100644 (file)
@@ -1069,7 +1069,8 @@ static config_log_state *open_config_log(server_rec *s, pool *p,
     }
     else {
         char *fname = ap_server_root_relative(p, cls->fname);
-        if ((cls->log_fd = ap_popenf(p, fname, xfer_flags, xfer_mode)) < 0) {
+        if ((cls->log_fd = ap_popenf_ex(p, fname, xfer_flags, xfer_mode, 1))
+             < 0) {
             ap_log_error(APLOG_MARK, APLOG_ERR, s,
                          "could not open transfer log file %s.", fname);
             exit(1);
index 733fd18a2d6f4a15ffdf158c9f0a98a8f8a08dcc..fbec82ab9b0422eb11ee954ed68dc72e802eb0a7 100644 (file)
@@ -142,7 +142,8 @@ static void open_referer_log(server_rec *s, pool *p)
         cls->referer_fd = ap_piped_log_write_fd(pl);
     }
     else if (*cls->fname != '\0') {
-        if ((cls->referer_fd = ap_popenf(p, fname, xfer_flags, xfer_mode)) < 0) {
+        if ((cls->referer_fd = ap_popenf_ex(p, fname, xfer_flags, xfer_mode, 1))
+             < 0) {
            ap_log_error(APLOG_MARK, APLOG_ERR, s,
                         "could not open referer log file %s.", fname);        
            exit(1);
index 4dee75c5a53caf602d1533dc176af6af5d3b45a7..a25ca73dc59f28066c90e63d639eb83b45dbbe51 100644 (file)
@@ -3105,8 +3105,8 @@ static void open_rewritelog(server_rec *s, pool *p)
         conf->rewritelogfp = ap_piped_log_write_fd(pl);
     }
     else if (*conf->rewritelogfile != '\0') {
-        if ((conf->rewritelogfp = ap_popenf(p, fname, rewritelog_flags,
-                                            rewritelog_mode)) < 0) {
+        if ((conf->rewritelogfp = ap_popenf_ex(p, fname, rewritelog_flags,
+                                            rewritelog_mode, 1)) < 0) {
             ap_log_error(APLOG_MARK, APLOG_ERR, s, 
 
                          "mod_rewrite: could not open RewriteLog "
@@ -3253,8 +3253,8 @@ static void rewritelock_create(server_rec *s, pool *p)
 
     /* create the lockfile */
     unlink(lockname);
-    if ((lockfd = ap_popenf(p, lockname, O_WRONLY|O_CREAT,
-                                         REWRITELOCK_MODE)) < 0) {
+    if ((lockfd = ap_popenf_ex(p, lockname, O_WRONLY|O_CREAT,
+                                         REWRITELOCK_MODE, 1)) < 0) {
         ap_log_error(APLOG_MARK, APLOG_ERR, s,
                      "mod_rewrite: Parent could not create RewriteLock "
                      "file %s", lockname);
@@ -3281,8 +3281,8 @@ static void rewritelock_open(server_rec *s, pool *p)
     }
 
     /* open the lockfile (once per child) to get a unique fd */
-    if ((lockfd = ap_popenf(p, lockname, O_WRONLY,
-                                         REWRITELOCK_MODE)) < 0) {
+    if ((lockfd = ap_popenf_ex(p, lockname, O_WRONLY,
+                                         REWRITELOCK_MODE, 1)) < 0) {
         ap_log_error(APLOG_MARK, APLOG_ERR, s,
                      "mod_rewrite: Child could not open RewriteLock "
                      "file %s", lockname);
index f5718746f13f762c082ea367e05b5db7cfb247db..69febd1dce7e11f235d53e950f02073585901e15 100644 (file)
@@ -1161,7 +1161,7 @@ static config_log_state *open_config_log(server_rec *s, pool *p,
                 fname = ap_server_root_relative(p, cls->fname);
         }
             
-        if ((cls->log_fd = ap_popenf(p, fname, xfer_flags, xfer_mode)) < 0) {
+        if ((cls->log_fd = ap_popenf_ex(p, fname, xfer_flags, xfer_mode, 1)) < 0) {
             ap_log_error(APLOG_MARK, APLOG_ERR, s,
                          "could not open transfer log file %s.", fname);
             exit(1);