httpd-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Randy Terbush <ra...@zyzzyva.com>
Subject setrlimit config Directives
Date Fri, 26 Jul 1996 17:27:31 GMT
Please review the following patch.

These changes add support for RLimitCPU, RLimitMEM, and RLimitNPROC.

I've changed the code to initialize the values to the existing system
limits. These directives can then be used on a per/dir, per/vhost
basis to limit system resource usage. There are still some warts in
the override area that need some discussion. Do we add OR_RLIMIT?

Also, obviously there are other limits we can diddle. I've picked
these three since they have the most impact on system performance/security.
Others?


Index: src/http_core.c
===================================================================
RCS file: /export/home/cvs/apache/src/http_core.c,v
retrieving revision 1.19
diff -c -r1.19 http_core.c
*** http_core.c	1996/07/25 19:32:28	1.19
--- http_core.c	1996/07/26 17:24:49
***************
*** 94,99 ****
--- 94,120 ----
      conf->hostname_lookups = 2;/* binary, but will use 2 as an "unset = on" */
      conf->do_rfc1413 = DEFAULT_RFC1413 | 2;  /* set bit 1 to indicate default */
  
+ #ifdef RLIMIT_CPU
+     conf->limit_cpu = (struct rlimit *) pcalloc (a, sizeof (struct rlimit));
+     if ((getrlimit(RLIMIT_CPU, conf->limit_cpu)) != 0)
+ 	conf->limit_cpu = NULL;
+ #endif
+ #ifdef RLIMIT_DATA
+     conf->limit_mem = (struct rlimit *) pcalloc (a, sizeof (struct rlimit));
+     if ((getrlimit(RLIMIT_DATA, conf->limit_mem)) != 0)
+ 	conf->limit_mem = NULL;
+ #endif
+ #ifdef RLIMIT_VMEM
+     conf->limit_mem = (struct rlimit *) pcalloc (a, sizeof (struct rlimit));
+     if ((getrlimit(RLIMIT_VMEM, conf->limit_mem)) != 0)
+ 	conf->limit_mem = NULL;
+ #endif
+ #ifdef RLIMIT_NPROC
+     conf->limit_nproc = (struct rlimit *) pcalloc (a, sizeof (struct rlimit));
+     if ((getrlimit(RLIMIT_NPROC, conf->limit_nproc)) != 0)
+ 	conf->limit_nproc = NULL;
+ #endif
+ 
      conf->sec = make_array (a, 2, sizeof(void *));
  
      return (void *)conf;
***************
*** 128,133 ****
--- 149,164 ----
      if ((new->do_rfc1413 & 2) == 0) conf->do_rfc1413 = new->do_rfc1413;
      if ((new->content_md5 & 2) == 0) conf->content_md5 = new->content_md5;
  
+ #ifdef RLIMIT_CPU
+     if (new->limit_cpu) conf->limit_cpu = new->limit_cpu;
+ #endif
+ #if defined(RLIMIT_DATA) || defined(RLIMIT_VMEM)
+     if (new->limit_mem) conf->limit_mem = new->limit_mem;
+ #endif
+ #ifdef RLIMIT_NPROC    
+     if (new->limit_nproc) conf->limit_nproc = new->limit_nproc;
+ #endif
+ 
      conf->sec = append_arrays (a, base->sec, new->sec);
  
      return (void*)conf;
***************
*** 808,813 ****
--- 839,871 ----
      return NULL;
  }
  
+ char *set_limit_cpu (cmd_parms *cmd, core_dir_config *conf, char *arg)
+ {
+ #ifdef RLIMIT_CPU
+     conf->limit_cpu->rlim_cur = atol(getword_conf(cmd->pool, &arg));
+     conf->limit_cpu->rlim_max = atol(getword_conf(cmd->pool, &arg));
+ #endif
+     return NULL;
+ }
+ 
+ char *set_limit_mem (cmd_parms *cmd, core_dir_config *conf, char *arg)
+ {
+ #ifdef RLIMIT_DATA
+     conf->limit_mem->rlim_cur = atol(getword_conf(cmd->pool, &arg));
+     conf->limit_mem->rlim_max = atol(getword_conf(cmd->pool, &arg));
+ #endif
+     return NULL;
+ }
+ 
+ char *set_limit_nproc (cmd_parms *cmd, core_dir_config *conf, char *arg)
+ {
+ #ifdef RLIMIT_NPROC
+     conf->limit_nproc->rlim_cur = atol(getword_conf(cmd->pool, &arg));
+     conf->limit_nproc->rlim_max = atol(getword_conf(cmd->pool, &arg));
+ #endif
+     return NULL;
+ }
+ 
  char *set_bind_address (cmd_parms *cmd, void *dummy, char *arg) {
      bind_address.s_addr = get_virthost_addr (arg, NULL);
      return NULL;
***************
*** 919,924 ****
--- 977,994 ----
  { "ServersSafetyLimit", set_server_limit, NULL, RSRC_CONF, TAKE1, NULL },
  { "MaxClients", set_server_limit, NULL, RSRC_CONF, TAKE1, NULL },
  { "MaxRequestsPerChild", set_max_requests, NULL, RSRC_CONF, TAKE1, NULL },
+ #ifdef RLIMIT_CPU
+ { "RLimitCPU", set_limit_cpu, (void*)XtOffsetOf(core_dir_config, limit_cpu),
+       OR_ALL, RAW_ARGS, "soft/hard limits for max CPU usage in seconds" },
+ #endif
+ #if defined (RLIMIT_DATA) || defined (RLIMIT_VMEM)
+ { "RLimitMEM", set_limit_mem, (void*)XtOffsetOf(core_dir_config, limit_mem),
+       OR_ALL, RAW_ARGS, "soft/hard limits for max memory usage per process" },
+ #endif
+ #ifdef RLIMIT_NPROC
+ { "RLimitNPROC", set_limit_nproc, (void*)XtOffsetOf(core_dir_config, limit_nproc),
+       OR_ALL, RAW_ARGS, "soft/hard limits for max number of processes per uid" },
+ #endif
  { "BindAddress", set_bind_address, NULL, RSRC_CONF, TAKE1,
    "'*', a numeric IP address, or the name of a host with a unique IP address"},
  { "Listen", set_listener, NULL, RSRC_CONF, TAKE1,
Index: src/http_core.h
===================================================================
RCS file: /export/home/cvs/apache/src/http_core.h,v
retrieving revision 1.7
diff -c -r1.7 http_core.h
*** http_core.h	1996/07/25 19:32:28	1.7
--- http_core.h	1996/07/26 17:24:52
***************
*** 152,157 ****
--- 152,168 ----
      int hostname_lookups;
      int do_rfc1413;   /* See if client is advertising a username? */
  
+     /* System Resource Control */
+ #ifdef RLIMIT_CPU
+     struct rlimit *limit_cpu;
+ #endif
+ #if defined(RLIMIT_DATA) || defined(RLIMIT_VMEM)
+     struct rlimit *limit_mem;
+ #endif
+ #ifdef RLIMIT_NPROC    
+     struct rlimit *limit_nproc;
+ #endif
+ 
      /* Access control */
      array_header *sec;
      regex_t *r;
Index: src/util_script.c
===================================================================
RCS file: /export/home/cvs/apache/src/util_script.c,v
retrieving revision 1.13
diff -c -r1.13 util_script.c
*** util_script.c	1996/07/21 20:03:45	1.13
--- util_script.c	1996/07/26 17:25:24
***************
*** 53,59 ****
--- 53,62 ----
  
  
  
+ #define CORE_PRIVATE
  #include "httpd.h"
+ #include "http_config.h"
+ #include "http_conf_globals.h"
  #include "http_main.h"
  #include "http_log.h"
  #include "http_protocol.h"
***************
*** 61,66 ****
--- 64,70 ----
  #include "http_request.h"       /* for sub_req_lookup_uri() */
  #include "util_script.h"
  
+ 
  /*
   * Various utility functions which are common to a whole lot of
   * script-type extensions mechanisms, and might as well be gathered
***************
*** 365,404 ****
  
  void call_exec (request_rec *r, char *argv0, char **env, int shellcmd) 
  {
!     
! #ifdef RLIMIT_CPU
!     struct rlimit cpulim = { 9, 10 };
! #endif
  
- #ifdef RLIMIT_DATA
-     struct rlimit datalim = { 2000000, 2500000 };
- #endif
- 
- #ifdef RLIMIT_NPROC
-     struct rlimit proclim = { 20, 40 };
- #endif
      
! #ifdef RLIMIT_VMEM
!     struct rlimit vmlim = { 2000000, 2500000 };
! #endif
      
! #ifdef RLIMIT_CPU
!     setrlimit (RLIMIT_CPU, &cpulim);
! #endif
  
! #ifdef RLIMIT_DATA
!     setrlimit (RLIMIT_DATA, &datalim);
  #endif
- 
  #ifdef RLIMIT_NPROC
!     setrlimit (RLIMIT_NPROC, &proclim);
  #endif
-     
  #ifdef RLIMIT_VMEM
!     setrlimit (RLIMIT_VMEM, &vmlim);
  #endif
      
- 
  #ifdef __EMX__    
      if ((!r->args) || (!r->args[0]) || (ind(r->args,'=') >= 0)) {
  	int emxloop;
--- 369,402 ----
  
  void call_exec (request_rec *r, char *argv0, char **env, int shellcmd) 
  {
!     char *execuser;
  
      
!     core_dir_config *conf = (core_dir_config *)pcalloc(r->pool, sizeof(core_dir_config));
      
!     conf = (core_dir_config *)get_module_config(r->per_dir_config, &core_module);
  
! #ifdef RLIMIT_CPU
!     if (conf->limit_cpu != NULL)
! 	if ((setrlimit (RLIMIT_CPU, conf->limit_cpu)) != 0)
! 	    log_unixerr("setrlimit", NULL, "failed to set CPU usage limit", r->server);
  #endif
  #ifdef RLIMIT_NPROC
!     if (conf->limit_nproc != NULL)
! 	if ((setrlimit (RLIMIT_NPROC, conf->limit_nproc)) != 0)
! 	    log_unixerr("setrlimit", NULL, "failed to set process limit", r->server);
! #endif
! #ifdef RLIMIT_DATA
!     if (conf->limit_mem != NULL)
! 	if ((setrlimit (RLIMIT_DATA, conf->limit_mem)) != 0)
! 	    log_unixerr("setrlimit", NULL, "failed to set memory usage limit", r->server);
  #endif
  #ifdef RLIMIT_VMEM
!     if (conf->limit_mem != NULL)
! 	if ((setrlimit (RLIMIT_VMEM, conf->limit_mem)) != 0)
! 	    log_unixerr("setrlimit", NULL, "failed to set memory usage limit", r->server);
  #endif
      
  #ifdef __EMX__    
      if ((!r->args) || (!r->args[0]) || (ind(r->args,'=') >= 0)) {
  	int emxloop;
***************
*** 438,444 ****
  	    execv(r->filename, create_argv(r->pool, argv0, r->args));
      }
  #else
! 
      if (shellcmd) 
  	execle(SHELL_PATH, SHELL_PATH, "-c", argv0, NULL, env);
  
--- 436,442 ----
  	    execv(r->filename, create_argv(r->pool, argv0, r->args));
      }
  #else
!     
      if (shellcmd) 
  	execle(SHELL_PATH, SHELL_PATH, "-c", argv0, NULL, env);
  






Mime
View raw message