[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[patch] OpenBSD -CURRENT Bug: httpd restarts fail in chroot from etag-state
- To: bugs_(_at_)_openbsd_(_dot_)_org
- Subject: [patch] OpenBSD -CURRENT Bug: httpd restarts fail in chroot from etag-state
- From: Chad Loder <cloder_(_at_)_openbsd_(_dot_)_org>
- Date: Thu, 20 Feb 2003 14:54:07 -0800
I believe this patch solves the problem. The essence
is: use an absolute path to the etag-state if we're
already chrooted; make sure the owner of the etag-state
file is root.www and make it the file group readable
so that we can read it (but not write it) after chrooting;
make some more informative error messages.
Tested on my system by running httpd with no arguments,
then doing a kill -HUP on the httpd parent process.
Confirmed that the httpd process succesfully restarts itself
(logging no errors) and correctly reads the etag-state file,
and that the generated etags (from a HEAD request) are
the same before and after the restart.
Comments/corrections?
Index: src/main/http_protocol.c
===================================================================
RCS file: /cvs/src/usr.sbin/httpd/src/main/http_protocol.c,v
retrieving revision 1.18
diff -u -r1.18 http_protocol.c
--- src/main/http_protocol.c 2003/02/17 03:14:33 1.18
+++ src/main/http_protocol.c 2003/02/20 23:08:17
@@ -3189,6 +3189,8 @@
*/
static AP_SHA1_CTX baseCtx;
+#define S_ETAG_MODE (S_IRUSR | S_IWUSR | S_IRGRP)
+
API_EXPORT(void) ap_init_etag(pool *pconf)
{
struct stat st;
@@ -3199,11 +3201,19 @@
ap_SHA1Init(&baseCtx);
- filename = ap_server_root_relative(pconf, "logs/etag-state");
- ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_NOTICE, NULL,
- "Initializing etag from %s", filename);
+ if (ap_server_is_chrooted()) {
+ filename = "/logs/etag-state";
+ ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_NOTICE, NULL,
+ "Initializing etag from %s (chrooted)", filename);
+ fd = open(filename, O_RDONLY|O_NOFOLLOW, S_ETAG_MODE);
+ } else {
+ filename = ap_server_root_relative(pconf, "logs/etag-state");
+ ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_NOTICE, NULL,
+ "Initializing etag from %s (not yet chrooted)", filename);
+ fd = open(filename, O_CREAT|O_RDWR|O_NOFOLLOW, S_ETAG_MODE);
+ }
- if ((fd = open(filename, O_CREAT|O_RDWR|O_NOFOLLOW, 0600)) == -1) {
+ if (fd == -1) {
ap_log_error(APLOG_MARK, APLOG_CRIT, NULL,
"could not open %s", filename);
exit(-1);
@@ -3215,7 +3225,44 @@
exit(-1);
}
+ if ((st.st_mode & ALLPERMS) != S_ETAG_MODE) {
+ /* if wrong permissions and already chrooted, nothing we can do */
+ if (ap_server_is_chrooted()) {
+ ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_CRIT, NULL,
+ "%s has wrong permissions: %o", filename, st.st_mode);
+ exit(-1);
+ }
+
+ if (fchmod(fd, S_ETAG_MODE) == -1) {
+ ap_log_error(APLOG_MARK, APLOG_CRIT, NULL,
+ "could not set correct permissions of %s", filename);
+ exit(-1);
+ }
+ }
+
+ if (st.st_gid != ap_group_id) {
+ /* if wrong ownership and already chrooted, nothing we can do */
+ if (ap_server_is_chrooted()) {
+ ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_CRIT, NULL,
+ "%s has wrong group ownership", filename);
+ exit(-1);
+ }
+
+ if (fchown(fd, -1, ap_group_id) == -1) {
+ ap_log_error(APLOG_MARK, APLOG_CRIT, NULL,
+ "could not set correct group ownership of %s", filename);
+ exit(-1);
+ }
+ }
+
if (st.st_size != sizeof(rnd)*4) {
+ /* if wrong size and we're already chrooted, nothing we can do */
+ if (ap_server_is_chrooted()) {
+ ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_CRIT, NULL,
+ "%s is the wrong size (%qd bytes)", filename, st.st_size);
+ exit(-1);
+ }
+
if (st.st_size > 0) {
ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_WARNING, NULL,
"truncating %s from %qd bytes to 0", filename, st.st_size);
Visit your host, monkey.org