diff -rupN httpd-2.2.22-old/support/Makefile.in httpd-2.2.22-new/support/Makefile.in
--- httpd-2.2.22-old/support/Makefile.in 2011-04-16 15:09:47.000000000 -0400
+++ httpd-2.2.22-new/support/Makefile.in 2012-03-06 04:50:51.000000000 -0500
@@ -60,7 +60,7 @@ checkgid: $(checkgid_OBJECTS)
suexec_OBJECTS = suexec.lo
suexec: $(suexec_OBJECTS)
- $(LINK) $(suexec_OBJECTS)
+ $(LINK) $(suexec_OBJECTS) -llve -ldl
htcacheclean_OBJECTS = htcacheclean.lo
htcacheclean: $(htcacheclean_OBJECTS)
diff -rupN httpd-2.2.22-old/support/suexec.c httpd-2.2.22-new/support/suexec.c
--- httpd-2.2.22-old/support/suexec.c 2011-02-14 15:36:12.000000000 -0500
+++ httpd-2.2.22-new/support/suexec.c 2012-02-14 09:19:00.000000000 -0500
@@ -55,6 +55,8 @@
#include <grp.h>
#endif
+#include <dlfcn.h>
+
/*
***********************************************************************
* There is no initgroups() in QNX, so I believe this is safe :-)
@@ -317,6 +319,9 @@ int main(int argc, char *argv[])
#ifdef AP_USERDIR_SUFFIX
fprintf(stderr, " -D AP_USERDIR_SUFFIX=\"%s\"\n", AP_USERDIR_SUFFIX);
#endif
+#ifdef AP_SAFE_DIRECTORY
+ fprintf(stderr, " -D AP_SAFE_DIRECTORY=\"%s\"\n", AP_SAFE_DIRECTORY);
+#endif
exit(0);
}
/*
@@ -466,6 +471,23 @@ int main(int argc, char *argv[])
exit(108);
}
+ void *lib_handle;
+ lib_handle = dlopen("liblve.so.0", RTLD_LAZY);
+ if (lib_handle) {
+ char *error;
+ char error_msg[8192];
+ int (*jail)(struct passwd *, char*) = dlsym(lib_handle, "jail");
+ if ((error = dlerror()) != NULL) {
+ log_err("failed to init LVE library %s\n", error);
+ exit(130);
+ }
+ int result = jail(pw, error_msg);
+ if (result < 0) {
+ log_err("SecureLVE jail error %s\n", error_msg);
+ exit(131);
+ }
+ }
+
/*
* Change UID/GID here so that the following tests work over NFS.
*
@@ -493,11 +515,32 @@ int main(int argc, char *argv[])
* Use chdir()s and getcwd()s to avoid problems with symlinked
* directories. Yuck.
*/
+
if (getcwd(cwd, AP_MAXPATH) == NULL) {
log_err("cannot get current working directory\n");
exit(111);
}
+ /* Check for safe directory existence */
+#ifdef AP_SAFE_DIRECTORY
+ char safe_dr[AP_MAXPATH];
+ int is_safe_dir_present = 0;
+ struct stat safe_dir_info;
+ if (((lstat(AP_SAFE_DIRECTORY, &safe_dir_info)) == 0) && (S_ISDIR(safe_dir_info.st_mode))) {
+ is_safe_dir_present = 1;
+ }
+
+ if(is_safe_dir_present){
+ if (((chdir(AP_SAFE_DIRECTORY)) != 0) ||
+ ((getcwd(safe_dr, AP_MAXPATH)) == NULL) ||
+ ((chdir(cwd)) != 0)) {
+ log_err("cannot get safe directory information (%s)\n", AP_SAFE_DIRECTORY);
+ exit(200);
+ }
+ }
+#endif
+
+
if (userdir) {
if (((chdir(target_homedir)) != 0) ||
((chdir(AP_USERDIR_SUFFIX)) != 0) ||
@@ -516,10 +559,28 @@ int main(int argc, char *argv[])
}
}
- if ((strncmp(cwd, dwd, strlen(dwd))) != 0) {
- log_err("command not in docroot (%s/%s)\n", cwd, cmd);
- exit(114);
+#ifdef AP_SAFE_DIRECTORY
+ int safe_work = 0;
+ if(is_safe_dir_present){
+ if ((strncmp(cwd, safe_dr, strlen(safe_dr))) != 0){
+ if ((strncmp(cwd, dwd, strlen(dwd))) != 0) {
+ log_err("command not in docroot (%s/%s)\n", cwd, cmd);
+ exit(114);
+ }
+ } else {
+ safe_work = 1;
+ }
+ } else {
+#endif
+ if ((strncmp(cwd, dwd, strlen(dwd))) != 0) {
+ log_err("command not in docroot (%s/%s)\n", cwd, cmd);
+ exit(114);
+ }
+#ifdef AP_SAFE_DIRECTORY
}
+#endif
+
+
/*
* Stat the cwd and verify it is a directory, or error out.
@@ -565,6 +626,9 @@ int main(int argc, char *argv[])
* Error out if the target name/group is different from
* the name/group of the cwd or the program.
*/
+#ifdef AP_SAFE_DIRECTORY
+ if (!safe_work){
+#endif
if ((uid != dir_info.st_uid) ||
(gid != dir_info.st_gid) ||
(uid != prg_info.st_uid) ||
@@ -576,6 +640,9 @@ int main(int argc, char *argv[])
prg_info.st_uid, prg_info.st_gid);
exit(120);
}
+#ifdef AP_SAFE_DIRECTORY
+ }
+#endif
/*
* Error out if the program is not executable for the user.
* Otherwise, she won't find any error in the logs except for