Mercurial > dovecot > original-hg > dovecot-1.2
changeset 722:0438621d25ff HEAD
Added virtual memory size limits to processes. Default values are pretty
high, this is mostly because I want it to prevent accidental infinite loops
eating memory or some integer overflows, not to actually restrict anything.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Sun, 01 Dec 2002 15:48:50 +0200 |
parents | b01cd1b30764 |
children | 2fc7cb5197b4 |
files | configure.in dovecot-example.conf src/lib/Makefile.am src/lib/restrict-process-size.c src/lib/restrict-process-size.h src/master/auth-process.c src/master/imap-process.c src/master/login-process.c src/master/settings.c src/master/settings.h |
diffstat | 10 files changed, 108 insertions(+), 3 deletions(-) [+] |
line wrap: on
line diff
--- a/configure.in Sun Dec 01 15:10:15 2002 +0200 +++ b/configure.in Sun Dec 01 15:48:50 2002 +0200 @@ -13,8 +13,8 @@ AC_ARG_PROGRAM AM_PROG_LIBTOOL -AC_CHECK_HEADERS(string.h stdlib.h stdint.h unistd.h dirent.h) -AC_CHECK_HEADERS(sys/uio.h sys/sysmacros.h iconv.h linux/mman.h) +AC_CHECK_HEADERS(string.h stdlib.h stdint.h unistd.h dirent.h iconv.h) +AC_CHECK_HEADERS(sys/uio.h sys/sysmacros.h sys/resource.h linux/mman.h) # check posix headers AC_CHECK_HEADERS(sys/time.h) @@ -161,7 +161,7 @@ dnl * after -lsocket and -lnsl tests, inet_aton() may be in them AC_CHECK_FUNCS(fcntl flock inet_aton sigaction getpagesize madvise setreuid) -AC_CHECK_FUNCS(strcasecmp stricmp vsnprintf memmove vsyslog writev) +AC_CHECK_FUNCS(strcasecmp stricmp vsnprintf memmove vsyslog writev setrlimit) dnl * poll/select?
--- a/dovecot-example.conf Sun Dec 01 15:10:15 2002 +0200 +++ b/dovecot-example.conf Sun Dec 01 15:48:50 2002 +0200 @@ -61,6 +61,10 @@ # User to use for imap-login process #login_user = imapd +# Set max. process size in megabytes. If you don't use +# login_process_per_connection you might need to grow this. +#login_process_size = 16 + # Directory where imap-auth places authentication UNIX sockets which login # needs to be able to connect to. The sockets are created when running as # root, so you don't need to give imap-auth any access for it. @@ -101,6 +105,10 @@ # Executable location #imap_executable = /usr/libexec/dovecot/imap +# Set max. process size in megabytes. Most of the memory goes to mmap()ing +# files, so it shouldn't harm much even if this limit is set pretty high. +#imap_process_size = 256 + # Maximum number of running imap processes. When this limit is reached, # new users aren't allowed to log in. #max_imap_processes = 1024 @@ -256,6 +264,9 @@ # Executable location #auth_executable = /usr/libexec/dovecot/imap-auth +# Set max. process size in megabytes. +#auth_process_size = 256 + # User to use for the process. Only shadow and pam authentication requires # roots, so use something else if possible. auth_user = root
--- a/src/lib/Makefile.am Sun Dec 01 15:10:15 2002 +0200 +++ b/src/lib/Makefile.am Sun Dec 01 15:48:50 2002 +0200 @@ -37,6 +37,7 @@ primes.c \ randgen.c \ restrict-access.c \ + restrict-process-size.c \ sendfile-util.c \ strfuncs.c \ temp-string.c \ @@ -77,6 +78,7 @@ primes.h \ randgen.h \ restrict-access.h \ + restrict-process-size.h \ sendfile-util.h \ strfuncs.h \ temp-string.h \
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/lib/restrict-process-size.c Sun Dec 01 15:48:50 2002 +0200 @@ -0,0 +1,50 @@ +/* + Copyright (c) 2002 Timo Sirainen + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#include "lib.h" +#include "restrict-process-size.h" + +#include <unistd.h> +#include <sys/time.h> +#ifdef HAVE_SYS_RESOURCE_H +# include <sys/resource.h> +#endif + +void restrict_process_size(unsigned int size __attr_unused__) +{ +#ifdef HAVE_SETRLIMIT + struct rlimit rlim; + + rlim.rlim_max = rlim.rlim_cur = + size > 0 && size < INT_MAX/1024/1024 ? + size*1024*1024 : RLIM_INFINITY; + if (setrlimit(RLIMIT_AS, &rlim) < 0) + i_fatal("setrlimit(RLIMIT_AS, %u): %m", size); +#else + if (size != 0) { + i_warning("Can't restrict process size: " + "setrlimit() not supported by system. " + "Set the limit to 0 to hide this warning."); + } +#endif +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/lib/restrict-process-size.h Sun Dec 01 15:48:50 2002 +0200 @@ -0,0 +1,8 @@ +#ifndef __RESTRICT_PROCESS_SIZE_H +#define __RESTRICT_PROCESS_SIZE_H + +/* Restrict max. process size. The size is in megabytes, setting it to + (unsigned int)-1 sets it unlimited. */ +void restrict_process_size(unsigned int size); + +#endif
--- a/src/master/auth-process.c Sun Dec 01 15:10:15 2002 +0200 +++ b/src/master/auth-process.c Sun Dec 01 15:48:50 2002 +0200 @@ -6,6 +6,7 @@ #include "network.h" #include "obuffer.h" #include "restrict-access.h" +#include "restrict-process-size.h" #include "auth-process.h" #include <stdlib.h> @@ -207,6 +208,9 @@ i_assert(listen_fd > 2); + if (net_accept(listen_fd, NULL, NULL) == -2) + i_fatal("net_accept(1) failed: %m"); + /* set correct permissions */ (void)chown(path, set_login_uid, set_login_gid); @@ -224,8 +228,14 @@ if (dup2(null_fd, 2) < 0) i_fatal("login: dup2() failed: %m"); + if (net_accept(listen_fd, NULL, NULL) == -2) + i_fatal("net_accept(2) failed: %m"); + clean_child_process(); + if (net_accept(listen_fd, NULL, NULL) == -2) + i_fatal("net_accept(3) failed: %m"); + /* move login communication handle to 3. do it last so we can be sure it's not closed afterwards. */ if (listen_fd != 3) { @@ -239,6 +249,9 @@ restrict_access_set_env(config->user, pwd->pw_uid, pwd->pw_gid, config->chroot); + if (net_accept(3, NULL, NULL) == -2) + i_fatal("net_accept(4) failed: %m"); + /* set other environment */ env_put(t_strdup_printf("AUTH_PROCESS=%d", (int) getpid())); env_put(t_strconcat("METHODS=", config->methods, NULL)); @@ -246,6 +259,9 @@ env_put(t_strconcat("USERINFO=", config->userinfo, NULL)); env_put(t_strconcat("USERINFO_ARGS=", config->userinfo_args, NULL)); + + restrict_process_size(config->process_size); + /* hide the path, it's ugly */ argv[0] = strrchr(config->executable, '/'); if (argv[0] == NULL) argv[0] = config->executable; else argv[0]++;
--- a/src/master/imap-process.c Sun Dec 01 15:10:15 2002 +0200 +++ b/src/master/imap-process.c Sun Dec 01 15:48:50 2002 +0200 @@ -3,6 +3,7 @@ #include "common.h" #include "env-util.h" #include "restrict-access.h" +#include "restrict-process-size.h" #include <stdlib.h> #include <unistd.h> @@ -151,6 +152,8 @@ clean_child_process() since it clears environment */ restrict_access_set_env(user, uid, gid, chroot ? home : NULL); + restrict_process_size(set_imap_process_size); + /* hide the path, it's ugly */ argv[0] = strrchr(set_imap_executable, '/'); if (argv[0] == NULL) argv[0] = set_imap_executable; else argv[0]++;
--- a/src/master/login-process.c Sun Dec 01 15:10:15 2002 +0200 +++ b/src/master/login-process.c Sun Dec 01 15:48:50 2002 +0200 @@ -7,6 +7,7 @@ #include "fdpass.h" #include "env-util.h" #include "restrict-access.h" +#include "restrict-process-size.h" #include "login-process.h" #include "auth-process.h" #include "master-interface.h" @@ -320,6 +321,8 @@ set_max_logging_users)); } + restrict_process_size(set_login_process_size); + /* hide the path, it's ugly */ argv[0] = strrchr(set_login_executable, '/'); if (argv[0] == NULL) argv[0] = set_login_executable; else argv[0]++;
--- a/src/master/settings.c Sun Dec 01 15:10:15 2002 +0200 +++ b/src/master/settings.c Sun Dec 01 15:48:50 2002 +0200 @@ -41,6 +41,7 @@ { "login_executable", SET_STR, &set_login_executable }, { "login_user", SET_STR, &set_login_user }, + { "login_process_size", SET_INT, &set_login_process_size }, { "login_dir", SET_STR, &set_login_dir }, { "login_chroot", SET_BOOL,&set_login_chroot }, { "login_process_per_connection", @@ -50,6 +51,7 @@ { "max_logging_users", SET_INT, &set_max_logging_users }, { "imap_executable", SET_STR, &set_imap_executable }, + { "imap_process_size", SET_INT, &set_imap_process_size }, { "valid_chroot_dirs", SET_STR, &set_valid_chroot_dirs }, { "max_imap_processes", SET_INT, &set_max_imap_processes }, { "verbose_proctitle", SET_BOOL,&set_verbose_proctitle }, @@ -99,6 +101,7 @@ /* login */ char *set_login_executable = PKG_LIBEXECDIR"/imap-login"; +unsigned int set_login_process_size = 16; char *set_login_user = "imapd"; char *set_login_dir = PKG_RUNDIR"/login"; @@ -113,6 +116,7 @@ /* imap */ char *set_imap_executable = PKG_LIBEXECDIR"/imap"; +unsigned int set_imap_process_size = 256; char *set_valid_chroot_dirs = NULL; unsigned int set_max_imap_processes = 1024; int set_verbose_proctitle = FALSE; @@ -330,6 +334,11 @@ return NULL; } + if (strcmp(key, "auth_process_size") == 0) { + if (!sscanf(value, "%i", &auth->process_size)) + return t_strconcat("Invalid number: ", value, NULL); + return NULL; + } return t_strconcat("Unknown setting: ", key, NULL); }
--- a/src/master/settings.h Sun Dec 01 15:10:15 2002 +0200 +++ b/src/master/settings.h Sun Dec 01 15:48:50 2002 +0200 @@ -21,6 +21,7 @@ /* login */ extern char *set_login_executable; extern char *set_login_user; +extern unsigned int set_login_process_size; extern char *set_login_dir; extern int set_login_chroot; extern int set_login_process_per_connection; @@ -33,6 +34,7 @@ /* imap */ extern char *set_imap_executable; +extern unsigned int set_imap_process_size; extern char *set_valid_chroot_dirs; extern unsigned int set_max_imap_processes; extern int set_verbose_proctitle; @@ -69,6 +71,7 @@ char *chroot; int count; + unsigned int process_size; }; extern AuthConfig *auth_processes_config;