From 1d08e3caaaf4e8ee1243fcfce763d17530b1e723 Mon Sep 17 00:00:00 2001 From: Oskari Saarenmaa Date: Wed, 18 Apr 2012 00:30:36 +0300 Subject: [PATCH] Configuration: max-open-files to set RLIMIT_NOFILE before switching UIDs. --- README.md | 1 + configuration.c | 20 ++++++++++++++++++++ configuration.h | 1 + stud.8 | 6 +++++- stud.c | 9 +++++++++ 5 files changed, 36 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 5edfe50..4314e6b 100644 --- a/README.md +++ b/README.md @@ -107,6 +107,7 @@ Detail about the entire set of options can be found by invoking `stud -h`: -n --workers=NUM Number of worker processes (Default: 1) -B --backlog=NUM Set listen backlog size (Default: 100) + --max-open-files=NUM Set maximum open files before (Default: 1024) -k --keepalive=SECS TCP keepalive on client socket (Default: 3600) SECURITY: diff --git a/configuration.c b/configuration.c index ff3409f..a711dec 100644 --- a/configuration.c +++ b/configuration.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include "configuration.h" @@ -38,6 +39,8 @@ #define CFG_CHROOT "chroot" #define CFG_USER "user" #define CFG_GROUP "group" +#define CFG_MAXFDS "max-open-files" +#define CFG_PARAM_MAXFDS 11012 #define CFG_QUIET "quiet" #define CFG_SYSLOG "syslog" #define CFG_SYSLOG_FACILITY "syslog-facility" @@ -144,6 +147,7 @@ stud_config * config_new (void) { r->TCP_KEEPALIVE_TIME = 3600; r->DAEMONIZE = 0; r->PREFER_SERVER_CIPHERS = 0; + r->MAXFDS = -1; return r; } @@ -618,6 +622,9 @@ void config_param_validate (char *k, char *v, stud_config *cfg, char *file, int } } } + else if (strcmp(k, CFG_MAXFDS) == 0) { + r = config_param_val_int(v, &cfg->MAXFDS); + } else if (strcmp(k, CFG_QUIET) == 0) { r = config_param_val_bool(v, &cfg->QUIET); } @@ -876,6 +883,9 @@ void config_print_usage_fd (char *prog, stud_config *cfg, FILE *out) { fprintf(out, "\n"); fprintf(out, " -n --workers=NUM Number of worker processes (Default: %ld)\n", cfg->NCORES); fprintf(out, " -B --backlog=NUM Set listen backlog size (Default: %d)\n", cfg->BACKLOG); + struct rlimit nof; + getrlimit(RLIMIT_NOFILE, &nof); + fprintf(out, " --"CFG_MAXFDS"=NUM Set maximum open files before (Default: %d)\n", (int) nof.rlim_cur); fprintf(out, " -k --keepalive=SECS TCP keepalive on client socket (Default: %d)\n", cfg->TCP_KEEPALIVE_TIME); #ifdef USE_SHARED_CACHE @@ -1044,6 +1054,12 @@ void config_print_default (FILE *fd, stud_config *cfg) { fprintf(fd, FMT_QSTR, CFG_GROUP, config_disp_gid(cfg->GID)); fprintf(fd, "\n"); + fprintf(fd, "# Set the maximum number of open files (and sockets) before switching uid\n"); + fprintf(fd, "#\n"); + fprintf(fd, "# type: integer\n"); + fprintf(fd, FMT_ISTR, CFG_MAXFDS, cfg->MAXFDS); + fprintf(fd, "\n"); + fprintf(fd, "# Quiet execution, report only error messages\n"); fprintf(fd, "#\n"); fprintf(fd, "# type: boolean\n"); @@ -1124,6 +1140,7 @@ void config_parse_cli(int argc, char **argv, stud_config *cfg) { { CFG_CHROOT, 1, NULL, 'r' }, { CFG_USER, 1, NULL, 'u' }, { CFG_GROUP, 1, NULL, 'g' }, + { CFG_MAXFDS, 1, NULL, CFG_PARAM_MAXFDS }, { CFG_QUIET, 0, NULL, 'q' }, { CFG_SYSLOG, 0, NULL, 's' }, { CFG_SYSLOG_FACILITY, 1, NULL, CFG_PARAM_SYSLOG_FACILITY }, @@ -1164,6 +1181,9 @@ void config_parse_cli(int argc, char **argv, stud_config *cfg) { case CFG_PARAM_SYSLOG_FACILITY: config_param_validate(CFG_SYSLOG_FACILITY, optarg, cfg, NULL, 0); break; + case CFG_PARAM_MAXFDS: + config_param_validate(CFG_MAXFDS, optarg, cfg, NULL, 0); + break; case 'c': config_param_validate(CFG_CIPHERS, optarg, cfg, NULL, 0); break; diff --git a/configuration.h b/configuration.h index 44be7f6..2185c2f 100644 --- a/configuration.h +++ b/configuration.h @@ -57,6 +57,7 @@ struct __stud_config { int TCP_KEEPALIVE_TIME; int DAEMONIZE; int PREFER_SERVER_CIPHERS; + int MAXFDS; }; typedef struct __stud_config stud_config; diff --git a/stud.8 b/stud.8 index bca288a..e365262 100644 --- a/stud.8 +++ b/stud.8 @@ -44,6 +44,8 @@ .Op Fl r Ar path .Op Fl u Ar username .Op Fl qs +.Op Fl -max-open-files Ns =num +.Op Fl -syslog-facility Ns =facility .Op Fl -write-ip .Op Fl -write-proxy .Ar certificate.pem @@ -100,6 +102,8 @@ Set shared cache size in sessions. By default, no shared cache is used. Chroot to the given path. By default, no chroot is done. .It Fl u Ar username Set GID/UID after binding the socket. By default, no privilege is dropped. +.It Fl -max-open-files Ns =num +Set the maximum number of open files before switching user id. .It Fl q Be quiet. Only emit error messages. .It Fl s @@ -107,7 +111,7 @@ Send messages to syslog in addition to .Em stderr and .Em stdout . -.It Fl -syslog-facility Ar facility +.It Fl -syslog-facility Ns =facility Syslog facility to use. Default is .Ar daemon . .It Fl -write-ip diff --git a/stud.c b/stud.c index 0ed6581..0d49839 100644 --- a/stud.c +++ b/stud.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -1497,6 +1498,14 @@ int main(int argc, char **argv) { /* load certificate, pass to handle_connections */ ssl_ctx = init_openssl(); + if (CONFIG->MAXFDS >= 0) { + struct rlimit nof; + nof.rlim_cur = CONFIG->MAXFDS; + nof.rlim_max = CONFIG->MAXFDS; + if (setrlimit(RLIMIT_NOFILE, &nof)) + fail("setrlimit failed"); + } + if (CONFIG->CHROOT && CONFIG->CHROOT[0]) change_root();