diff --git a/include/lighttpd/angel_proc.h b/include/lighttpd/angel_proc.h index 14a30cd..57d7199 100644 --- a/include/lighttpd/angel_proc.h +++ b/include/lighttpd/angel_proc.h @@ -39,7 +39,7 @@ LI_API void li_error_pipe_use(liErrorPipe *epipe, int dest_fd); /** read remaining data from in-fd */ LI_API void li_error_pipe_flush(liErrorPipe *epipe); -LI_API liProc* li_proc_new(liServer *srv, gchar **args, gchar **env, uid_t uid, gid_t gid, gchar *username, liProcSetupCB cb, gpointer ctx); +LI_API liProc* li_proc_new(liServer *srv, gchar **args, gchar **env, uid_t uid, gid_t gid, gchar *username, gint64 rlim_core, gint64 rlim_nofile, liProcSetupCB cb, gpointer ctx); LI_API void li_proc_free(liProc *proc); #endif diff --git a/include/lighttpd/angel_server.h b/include/lighttpd/angel_server.h index 096a62d..b3f69cb 100644 --- a/include/lighttpd/angel_server.h +++ b/include/lighttpd/angel_server.h @@ -26,6 +26,8 @@ struct liInstanceConf { GString *username; uid_t uid; gid_t gid; + + gint64 rlim_core, rlim_nofile; /* < 0: don't change, G_MAXINT64: unlimited */ }; struct liInstance { @@ -68,7 +70,7 @@ LI_API void li_instance_replace(liInstance *oldi, liInstance *newi); LI_API void li_instance_set_state(liInstance *i, liInstanceState s); LI_API void li_instance_state_reached(liInstance *i, liInstanceState s); -LI_API liInstanceConf* li_instance_conf_new(gchar **cmd, gchar **env, GString *username, uid_t uid, gid_t gid); +LI_API liInstanceConf* li_instance_conf_new(gchar **cmd, gchar **env, GString *username, uid_t uid, gid_t gid, gint64 rlim_core, gint64 rlim_nofile); LI_API void li_instance_conf_release(liInstanceConf *ic); LI_API void li_instance_conf_acquire(liInstanceConf *ic); diff --git a/src/angel/angel_plugin_core.c b/src/angel/angel_plugin_core.c index b1708cc..b2db865 100644 --- a/src/angel/angel_plugin_core.c +++ b/src/angel/angel_plugin_core.c @@ -12,6 +12,7 @@ static void core_instance_parse(liServer *srv, liPlugin *p, liValue **options) { uid_t uid = -1; gid_t gid = -1; GString *user = NULL; + gint64 rlim_core = -1, rlim_nofile = -1; if (config->load_instconf) { ERROR(srv, "%s", "Already configure the instance"); @@ -160,10 +161,13 @@ static void core_instance_parse(liServer *srv, liPlugin *p, liValue **options) { g_ptr_array_add(cmd, g_strndup(CONST_STR_LEN("/usr/lib/lighttpd2/"))); } + if (options[9]) rlim_core = options[9]->data.number; + if (options[10]) rlim_nofile = options[10]->data.number; + g_ptr_array_add(cmd, NULL); cmdarr = (gchar**) g_ptr_array_free(cmd, FALSE); envarr = (gchar**) g_ptr_array_free(env, FALSE); - config->load_instconf = li_instance_conf_new(cmdarr, envarr, user, uid, gid); + config->load_instconf = li_instance_conf_new(cmdarr, envarr, user, uid, gid, -1, -1); } static const liPluginItemOption core_instance_options[] = { @@ -176,6 +180,8 @@ static const liPluginItemOption core_instance_options[] = { /* 6 */ { "wrapper", LI_VALUE_LIST, 0 }, /* 7 */ { "env", LI_VALUE_LIST, 0 }, /* 8 */ { "copy-env", LI_VALUE_LIST, 0 }, + /* 9 */ { "max-core-file-size", LI_VALUE_NUMBER, 0 }, + /* 10 */ { "max-open-files", LI_VALUE_NUMBER, 0 }, { NULL, 0, 0 } }; diff --git a/src/angel/angel_proc.c b/src/angel/angel_proc.c index 63ff81a..572cda4 100644 --- a/src/angel/angel_proc.c +++ b/src/angel/angel_proc.c @@ -3,6 +3,10 @@ #include +#ifdef HAVE_SYS_RESOURCE_H +# include +#endif + static void read_pipe(liServer *srv, liErrorPipe *epipe, gboolean flush) { const ssize_t max_read = 8192; ssize_t r, toread; @@ -137,7 +141,7 @@ static void proc_epipe_cb(liServer *srv, liErrorPipe *epipe, GString *msg) { BACKEND_LINES(srv, msg->str, "%s[%i]: ", proc->appname, proc->child_pid); } -liProc* li_proc_new(liServer *srv, gchar **args, gchar **env, uid_t uid, gid_t gid, gchar *username, liProcSetupCB cb, gpointer ctx) { +liProc* li_proc_new(liServer *srv, gchar **args, gchar **env, uid_t uid, gid_t gid, gchar *username, gint64 rlim_core, gint64 rlim_nofile, liProcSetupCB cb, gpointer ctx) { liProc *proc; pid_t pid; @@ -179,6 +183,23 @@ liProc* li_proc_new(liServer *srv, gchar **args, gchar **env, uid_t uid, gid_t g li_proc_free(proc); return NULL; default: +#ifdef HAVE_GETRLIMIT + { + struct rlimit rlim; + if (rlim_core >= 0) { + rlim.rlim_cur = rlim.rlim_max = ((guint64) rlim_core >= RLIM_INFINITY) ? RLIM_INFINITY : (guint64) rlim_core; + if (0 != setrlimit(RLIMIT_CORE, &rlim)) { + ERROR(srv, "couldn't set 'max core file size': %s", g_strerror(errno)); + } + } + if (rlim_nofile >= 0) { + rlim.rlim_cur = rlim.rlim_max = ((guint64) rlim_nofile >= RLIM_INFINITY) ? RLIM_INFINITY : (guint64) rlim_nofile; + if (0 != setrlimit(RLIMIT_NOFILE, &rlim)) { + ERROR(srv, "couldn't set 'max filedescriptors': %s", g_strerror(errno)); + } + } + } +#endif proc->child_pid = pid; li_error_pipe_activate(proc->epipe); break; diff --git a/src/angel/angel_server.c b/src/angel/angel_server.c index 85160c0..14e20c1 100644 --- a/src/angel/angel_server.c +++ b/src/angel/angel_server.c @@ -177,7 +177,7 @@ static void instance_spawn(liInstance *i) { li_fd_no_block(confd[1]); i->acon = li_angel_connection_new(i->srv->loop, confd[0], i, instance_angel_call_cb, instance_angel_close_cb); - i->proc = li_proc_new(i->srv, i->ic->cmd, i->ic->env, i->ic->uid, i->ic->gid, i->ic->username->str, instance_spawn_setup, confd); + i->proc = li_proc_new(i->srv, i->ic->cmd, i->ic->env, i->ic->uid, i->ic->gid, i->ic->username->str, i->ic->rlim_core, i->ic->rlim_nofile, instance_spawn_setup, confd); if (!i->proc) return; @@ -350,7 +350,7 @@ void li_instance_acquire(liInstance *i) { g_atomic_int_inc(&i->refcount); } -liInstanceConf* li_instance_conf_new(gchar **cmd, gchar **env, GString *username, uid_t uid, gid_t gid) { +liInstanceConf* li_instance_conf_new(gchar **cmd, gchar **env, GString *username, uid_t uid, gid_t gid, gint64 rlim_core, gint64 rlim_nofile) { liInstanceConf *ic = g_slice_new0(liInstanceConf); ic->refcount = 1; ic->cmd = cmd; @@ -360,6 +360,8 @@ liInstanceConf* li_instance_conf_new(gchar **cmd, gchar **env, GString *username } ic->uid = uid; ic->gid = gid; + ic->rlim_core = rlim_core; + ic->rlim_nofile = rlim_nofile; return ic; }