restrict-process-size.c revision b3f03a6a9232d4e5a8682eff8d37bbcf41c487ec
5e0ce63bb65db34d7f48b34bbb5545fa791781c4Timo Sirainen/* Copyright (c) 2002-2003 Timo Sirainen */
cfbab67e839000b57f32308dd26f9807b5dbe8e3Timo Sirainen
cfbab67e839000b57f32308dd26f9807b5dbe8e3Timo Sirainen#include "lib.h"
cfbab67e839000b57f32308dd26f9807b5dbe8e3Timo Sirainen#include "restrict-process-size.h"
cfbab67e839000b57f32308dd26f9807b5dbe8e3Timo Sirainen
cfbab67e839000b57f32308dd26f9807b5dbe8e3Timo Sirainen#include <unistd.h>
cfbab67e839000b57f32308dd26f9807b5dbe8e3Timo Sirainen#include <sys/time.h>
cfbab67e839000b57f32308dd26f9807b5dbe8e3Timo Sirainen#ifdef HAVE_SYS_RESOURCE_H
cfbab67e839000b57f32308dd26f9807b5dbe8e3Timo Sirainen# include <sys/resource.h>
cfbab67e839000b57f32308dd26f9807b5dbe8e3Timo Sirainen#endif
cfbab67e839000b57f32308dd26f9807b5dbe8e3Timo Sirainen
dc4127f13f2d5cf44577471123ae70b7772b2e8cTimo Sirainenvoid restrict_process_size(unsigned int size __attr_unused__,
dc4127f13f2d5cf44577471123ae70b7772b2e8cTimo Sirainen unsigned int max_processes __attr_unused__)
cfbab67e839000b57f32308dd26f9807b5dbe8e3Timo Sirainen{
cfbab67e839000b57f32308dd26f9807b5dbe8e3Timo Sirainen#ifdef HAVE_SETRLIMIT
cfbab67e839000b57f32308dd26f9807b5dbe8e3Timo Sirainen struct rlimit rlim;
cfbab67e839000b57f32308dd26f9807b5dbe8e3Timo Sirainen
dc4127f13f2d5cf44577471123ae70b7772b2e8cTimo Sirainen#ifdef HAVE_RLIMIT_NPROC
c0bb6a113c3e5f6af18fbd1b53caa134d20481b8Timo Sirainen if (max_processes < INT_MAX) {
c0bb6a113c3e5f6af18fbd1b53caa134d20481b8Timo Sirainen rlim.rlim_max = rlim.rlim_cur = max_processes;
c0bb6a113c3e5f6af18fbd1b53caa134d20481b8Timo Sirainen if (setrlimit(RLIMIT_NPROC, &rlim) < 0)
c0bb6a113c3e5f6af18fbd1b53caa134d20481b8Timo Sirainen i_fatal("setrlimit(RLIMIT_NPROC, %u): %m", size);
c0bb6a113c3e5f6af18fbd1b53caa134d20481b8Timo Sirainen }
dc4127f13f2d5cf44577471123ae70b7772b2e8cTimo Sirainen#endif
dc4127f13f2d5cf44577471123ae70b7772b2e8cTimo Sirainen
c0bb6a113c3e5f6af18fbd1b53caa134d20481b8Timo Sirainen if (size > 0 && size < INT_MAX/1024/1024) {
c0bb6a113c3e5f6af18fbd1b53caa134d20481b8Timo Sirainen rlim.rlim_max = rlim.rlim_cur = size*1024*1024;
e9d0f2284f3a82b9852e52787866cba6b9adbcb6Timo Sirainen
c0bb6a113c3e5f6af18fbd1b53caa134d20481b8Timo Sirainen if (setrlimit(RLIMIT_DATA, &rlim) < 0)
c0bb6a113c3e5f6af18fbd1b53caa134d20481b8Timo Sirainen i_fatal("setrlimit(RLIMIT_DATA, %u): %m", size);
e9d0f2284f3a82b9852e52787866cba6b9adbcb6Timo Sirainen
e9d0f2284f3a82b9852e52787866cba6b9adbcb6Timo Sirainen#ifdef HAVE_RLIMIT_AS
c0bb6a113c3e5f6af18fbd1b53caa134d20481b8Timo Sirainen if (setrlimit(RLIMIT_AS, &rlim) < 0)
c0bb6a113c3e5f6af18fbd1b53caa134d20481b8Timo Sirainen i_fatal("setrlimit(RLIMIT_AS, %u): %m", size);
e9d0f2284f3a82b9852e52787866cba6b9adbcb6Timo Sirainen#endif
c0bb6a113c3e5f6af18fbd1b53caa134d20481b8Timo Sirainen }
cfbab67e839000b57f32308dd26f9807b5dbe8e3Timo Sirainen#else
cfbab67e839000b57f32308dd26f9807b5dbe8e3Timo Sirainen if (size != 0) {
cfbab67e839000b57f32308dd26f9807b5dbe8e3Timo Sirainen i_warning("Can't restrict process size: "
cfbab67e839000b57f32308dd26f9807b5dbe8e3Timo Sirainen "setrlimit() not supported by system. "
cfbab67e839000b57f32308dd26f9807b5dbe8e3Timo Sirainen "Set the limit to 0 to hide this warning.");
cfbab67e839000b57f32308dd26f9807b5dbe8e3Timo Sirainen }
cfbab67e839000b57f32308dd26f9807b5dbe8e3Timo Sirainen#endif
cfbab67e839000b57f32308dd26f9807b5dbe8e3Timo Sirainen}
b3f03a6a9232d4e5a8682eff8d37bbcf41c487ecTimo Sirainen
b3f03a6a9232d4e5a8682eff8d37bbcf41c487ecTimo Sirainenvoid restrict_fd_limit(unsigned int count)
b3f03a6a9232d4e5a8682eff8d37bbcf41c487ecTimo Sirainen{
b3f03a6a9232d4e5a8682eff8d37bbcf41c487ecTimo Sirainen#ifdef HAVE_SETRLIMIT
b3f03a6a9232d4e5a8682eff8d37bbcf41c487ecTimo Sirainen struct rlimit rlim;
b3f03a6a9232d4e5a8682eff8d37bbcf41c487ecTimo Sirainen
b3f03a6a9232d4e5a8682eff8d37bbcf41c487ecTimo Sirainen rlim.rlim_cur = rlim.rlim_max = count;
b3f03a6a9232d4e5a8682eff8d37bbcf41c487ecTimo Sirainen if (setrlimit(RLIMIT_NOFILE, &rlim) < 0)
b3f03a6a9232d4e5a8682eff8d37bbcf41c487ecTimo Sirainen i_fatal("setrlimit(RLIMIT_NOFILE, %u): %m", count);
b3f03a6a9232d4e5a8682eff8d37bbcf41c487ecTimo Sirainen#endif
b3f03a6a9232d4e5a8682eff8d37bbcf41c487ecTimo Sirainen}
b3f03a6a9232d4e5a8682eff8d37bbcf41c487ecTimo Sirainen
b3f03a6a9232d4e5a8682eff8d37bbcf41c487ecTimo Sirainenbool restrict_raise_fd_limit(unsigned int count)
b3f03a6a9232d4e5a8682eff8d37bbcf41c487ecTimo Sirainen{
b3f03a6a9232d4e5a8682eff8d37bbcf41c487ecTimo Sirainen#ifdef HAVE_SETRLIMIT
b3f03a6a9232d4e5a8682eff8d37bbcf41c487ecTimo Sirainen struct rlimit rlim, new_rlim;
b3f03a6a9232d4e5a8682eff8d37bbcf41c487ecTimo Sirainen
b3f03a6a9232d4e5a8682eff8d37bbcf41c487ecTimo Sirainen if (getrlimit(RLIMIT_NOFILE, &rlim) < 0)
b3f03a6a9232d4e5a8682eff8d37bbcf41c487ecTimo Sirainen return FALSE;
b3f03a6a9232d4e5a8682eff8d37bbcf41c487ecTimo Sirainen
b3f03a6a9232d4e5a8682eff8d37bbcf41c487ecTimo Sirainen if (rlim.rlim_cur < count)
b3f03a6a9232d4e5a8682eff8d37bbcf41c487ecTimo Sirainen new_rlim.rlim_cur = new_rlim.rlim_max = count;
b3f03a6a9232d4e5a8682eff8d37bbcf41c487ecTimo Sirainen if (setrlimit(RLIMIT_NOFILE, &new_rlim) == 0)
b3f03a6a9232d4e5a8682eff8d37bbcf41c487ecTimo Sirainen return TRUE;
b3f03a6a9232d4e5a8682eff8d37bbcf41c487ecTimo Sirainen
b3f03a6a9232d4e5a8682eff8d37bbcf41c487ecTimo Sirainen /* raise as high as we can */
b3f03a6a9232d4e5a8682eff8d37bbcf41c487ecTimo Sirainen if (rlim.rlim_cur < rlim.rlim_max) {
b3f03a6a9232d4e5a8682eff8d37bbcf41c487ecTimo Sirainen rlim.rlim_cur = rlim.rlim_max;
b3f03a6a9232d4e5a8682eff8d37bbcf41c487ecTimo Sirainen (void)setrlimit(RLIMIT_NOFILE, &new_rlim);
b3f03a6a9232d4e5a8682eff8d37bbcf41c487ecTimo Sirainen }
b3f03a6a9232d4e5a8682eff8d37bbcf41c487ecTimo Sirainen#endif
b3f03a6a9232d4e5a8682eff8d37bbcf41c487ecTimo Sirainen return FALSE;
b3f03a6a9232d4e5a8682eff8d37bbcf41c487ecTimo Sirainen}