From 604f552e40a9a201162d6c070fd96bc504b30ff3 Mon Sep 17 00:00:00 2001 From: kib Date: Wed, 15 Aug 2012 15:56:21 +0000 Subject: Add a sysctl kern.pid_max, which limits the maximum pid the system is allowed to allocate, and corresponding tunable with the same name. Note that existing processes with higher pids are left intact. MFC after: 1 week --- sys/kern/init_main.c | 1 + sys/kern/kern_fork.c | 8 ++++---- sys/kern/kern_mib.c | 24 ++++++++++++++++++++++++ sys/kern/kern_thread.c | 6 +++++- sys/kern/subr_param.c | 13 +++++++++++-- sys/nlm/nlm_advlock.c | 1 + sys/sys/proc.h | 5 +++-- 7 files changed, 49 insertions(+), 9 deletions(-) (limited to 'sys') diff --git a/sys/kern/init_main.c b/sys/kern/init_main.c index ba905e0..3174a34 100644 --- a/sys/kern/init_main.c +++ b/sys/kern/init_main.c @@ -476,6 +476,7 @@ proc0_init(void *dummy __unused) knlist_init_mtx(&p->p_klist, &p->p_mtx); STAILQ_INIT(&p->p_ktr); p->p_nice = NZERO; + /* pid_max cannot be greater then PID_MAX */ td->td_tid = PID_MAX + 1; LIST_INSERT_HEAD(TIDHASH(td->td_tid), td, td_hash); td->td_state = TDS_RUNNING; diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c index 6cb95cd..46cdca1 100644 --- a/sys/kern/kern_fork.c +++ b/sys/kern/kern_fork.c @@ -209,8 +209,8 @@ sysctl_kern_randompid(SYSCTL_HANDLER_ARGS) pid = randompid; error = sysctl_handle_int(oidp, &pid, 0, req); if (error == 0 && req->newptr != NULL) { - if (pid < 0 || pid > PID_MAX - 100) /* out of range */ - pid = PID_MAX - 100; + if (pid < 0 || pid > pid_max - 100) /* out of range */ + pid = pid_max - 100; else if (pid < 2) /* NOP */ pid = 0; else if (pid < 100) /* Make it reasonable */ @@ -259,8 +259,8 @@ retry: * restart somewhat above 0, as the low-numbered procs * tend to include daemons that don't exit. */ - if (trypid >= PID_MAX) { - trypid = trypid % PID_MAX; + if (trypid >= pid_max) { + trypid = trypid % pid_max; if (trypid < 100) trypid += 100; pidchecked = 0; diff --git a/sys/kern/kern_mib.c b/sys/kern/kern_mib.c index 75b3af9..f6ab3a4 100644 --- a/sys/kern/kern_mib.c +++ b/sys/kern/kern_mib.c @@ -499,6 +499,30 @@ SYSCTL_INT(_debug_sizeof, OID_AUTO, vnode, CTLFLAG_RD, SYSCTL_INT(_debug_sizeof, OID_AUTO, proc, CTLFLAG_RD, 0, sizeof(struct proc), "sizeof(struct proc)"); +static int +sysctl_kern_pid_max(SYSCTL_HANDLER_ARGS) +{ + int error, pm; + + pm = pid_max; + error = sysctl_handle_int(oidp, &pm, 0, req); + if (error || !req->newptr) + return (error); + sx_xlock(&proctree_lock); + sx_xlock(&allproc_lock); + /* Only permit the values less then PID_MAX. */ + if (pm > PID_MAX) + error = EINVAL; + else + pid_max = pm; + sx_xunlock(&allproc_lock); + sx_xunlock(&proctree_lock); + return (error); +} +SYSCTL_PROC(_kern, OID_AUTO, pid_max, CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_TUN | + CTLFLAG_MPSAFE, 0, 0, sysctl_kern_pid_max, "I", + "Maximum allowed pid"); + #include #include SYSCTL_INT(_debug_sizeof, OID_AUTO, bio, CTLFLAG_RD, diff --git a/sys/kern/kern_thread.c b/sys/kern/kern_thread.c index 69a416e..d21763c 100644 --- a/sys/kern/kern_thread.c +++ b/sys/kern/kern_thread.c @@ -269,7 +269,11 @@ threadinit(void) { mtx_init(&tid_lock, "TID lock", NULL, MTX_DEF); - /* leave one number for thread0 */ + + /* + * pid_max cannot be greater then PID_MAX. + * leave one number for thread0. + */ tid_unrhdr = new_unrhdr(PID_MAX + 2, INT_MAX, &tid_lock); thread_zone = uma_zcreate("THREAD", sched_sizeof_thread(), diff --git a/sys/kern/subr_param.c b/sys/kern/subr_param.c index 8c13336..1c6b867 100644 --- a/sys/kern/subr_param.c +++ b/sys/kern/subr_param.c @@ -41,12 +41,13 @@ __FBSDID("$FreeBSD$"); #include "opt_msgbuf.h" #include "opt_maxusers.h" -#include #include #include #include -#include +#include #include +#include +#include #include #include @@ -92,6 +93,7 @@ int ncallout; /* maximum # of timer events */ int nbuf; int ngroups_max; /* max # groups per process */ int nswbuf; +pid_t pid_max = PID_MAX; long maxswzone; /* max swmeta KVA storage */ long maxbcache; /* max buffer cache KVA storage */ long maxpipekva; /* Limit on pipe KVA */ @@ -250,6 +252,13 @@ init_param1(void) TUNABLE_INT_FETCH("kern.ngroups", &ngroups_max); if (ngroups_max < NGROUPS_MAX) ngroups_max = NGROUPS_MAX; + + /* + * Only allow to lower the maximal pid. + */ + TUNABLE_INT_FETCH("kern.pid_max", &pid_max); + if (pid_max > PID_MAX) + pid_max = PID_MAX; } /* diff --git a/sys/nlm/nlm_advlock.c b/sys/nlm/nlm_advlock.c index 416cd1d..0c53be1 100644 --- a/sys/nlm/nlm_advlock.c +++ b/sys/nlm/nlm_advlock.c @@ -98,6 +98,7 @@ nlm_client_init(void *dummy) int i; mtx_init(&nlm_svid_lock, "NLM svid lock", NULL, MTX_DEF); + /* pid_max cannot be greater then PID_MAX */ nlm_svid_allocator = new_unrhdr(PID_MAX + 2, INT_MAX, &nlm_svid_lock); for (i = 0; i < NLM_SVID_HASH_SIZE; i++) LIST_INIT(&nlm_file_svids[i]); diff --git a/sys/sys/proc.h b/sys/sys/proc.h index 06df632..4c4aa2f 100644 --- a/sys/sys/proc.h +++ b/sys/sys/proc.h @@ -696,11 +696,12 @@ MALLOC_DECLARE(M_SUBPROC); #define FIRST_THREAD_IN_PROC(p) TAILQ_FIRST(&(p)->p_threads) /* - * We use process IDs <= PID_MAX; PID_MAX + 1 must also fit in a pid_t, - * as it is used to represent "no process group". + * We use process IDs <= pid_max <= PID_MAX; PID_MAX + 1 must also fit + * in a pid_t, as it is used to represent "no process group". */ #define PID_MAX 99999 #define NO_PID 100000 +extern pid_t pid_max; #define SESS_LEADER(p) ((p)->p_session->s_leader == (p)) -- cgit v1.1