Remplace kern.shortcorename sysctl with a more flexible sheme,
core filename format, which allow to change the name of the core dump, and to relocate it in a directory. Credits to Bill Sommerfeld for giving me the idea :) The default core filename format can be changed by options DEFCORENAME and/or kern.defcorename Create a new sysctl tree, proc, which holds per-process values (for now the corename format, and resources limits). Process is designed by its pid at the second level name. These values are inherited on fork, and the corename fomat is reset to defcorename on suid/sgid exec. Create a p_sugid() function, to take appropriate actions on suid/sgid exec (for now set the P_SUGID flag and reset the per-proc corename). Adjust dosetrlimit() to allow changing limits of one proc by another, with credential controls.
This commit is contained in:
parent
bb54953b63
commit
52497e180a
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: kern_resource_43.c,v 1.5 1997/10/15 17:03:52 mycroft Exp $ */
|
||||
/* $NetBSD: kern_resource_43.c,v 1.6 1999/09/28 14:47:00 bouyer Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1982, 1986, 1991, 1993
|
||||
|
@ -101,5 +101,5 @@ compat_43_sys_setrlimit(p, v, retval)
|
|||
return (error);
|
||||
lim.rlim_cur = olim.rlim_cur;
|
||||
lim.rlim_max = olim.rlim_max;
|
||||
return (dosetrlimit(p, which, &lim));
|
||||
return (dosetrlimit(p, p->p_cred, which, &lim));
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: netbsd32_netbsd.c,v 1.17 1999/08/05 18:08:15 thorpej Exp $ */
|
||||
/* $NetBSD: netbsd32_netbsd.c,v 1.18 1999/09/28 14:47:02 bouyer Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1998 Matthew R. Green
|
||||
|
@ -3591,7 +3591,7 @@ compat_netbsd32_setrlimit(p, v, retval)
|
|||
error = copyin((caddr_t)(u_long)SCARG(uap, rlp), &alim, sizeof(struct rlimit));
|
||||
if (error)
|
||||
return (error);
|
||||
return (dosetrlimit(p, which, &alim));
|
||||
return (dosetrlimit(p, p->p_cred, which, &alim));
|
||||
}
|
||||
|
||||
int
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: svr4_resource.c,v 1.4 1999/09/07 18:20:19 christos Exp $ */
|
||||
/* $NetBSD: svr4_resource.c,v 1.5 1999/09/28 14:47:02 bouyer Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1998 The NetBSD Foundation, Inc.
|
||||
|
@ -185,7 +185,7 @@ svr4_sys_setrlimit(p, v, retval)
|
|||
else if (slim.rlim_cur == SVR4_RLIM_SAVED_CUR)
|
||||
blim.rlim_cur = limp->rlim_cur;
|
||||
|
||||
return dosetrlimit(p, rl, &blim);
|
||||
return dosetrlimit(p, p->p_cred, rl, &blim);
|
||||
}
|
||||
|
||||
|
||||
|
@ -283,5 +283,5 @@ svr4_sys_setrlimit64(p, v, retval)
|
|||
else if (slim.rlim_cur == SVR4_RLIM64_SAVED_CUR)
|
||||
blim.rlim_cur = limp->rlim_cur;
|
||||
|
||||
return dosetrlimit(p, rl, &blim);
|
||||
return dosetrlimit(p, p->p_cred, rl, &blim);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# $NetBSD: files,v 1.318 1999/09/27 23:44:27 ad Exp $
|
||||
# $NetBSD: files,v 1.319 1999/09/28 14:47:02 bouyer Exp $
|
||||
|
||||
# @(#)files.newconf 7.5 (Berkeley) 5/10/93
|
||||
|
||||
|
@ -9,7 +9,7 @@ defopt KMEMSTATS
|
|||
defopt KTRACE
|
||||
defopt LOCKDEBUG
|
||||
defopt RTC_OFFSET
|
||||
defopt SHORTCORENAME
|
||||
defopt DEFCORENAME
|
||||
defopt UCONSOLE
|
||||
|
||||
defopt MULTIPROCESSOR
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: init_main.c,v 1.156 1999/09/17 20:11:56 thorpej Exp $ */
|
||||
/* $NetBSD: init_main.c,v 1.157 1999/09/28 14:47:03 bouyer Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1995 Christopher G. Demetriou. All rights reserved.
|
||||
|
@ -286,6 +286,7 @@ main()
|
|||
limit0.pl_rlimit[RLIMIT_RSS].rlim_max = i;
|
||||
limit0.pl_rlimit[RLIMIT_MEMLOCK].rlim_max = i;
|
||||
limit0.pl_rlimit[RLIMIT_MEMLOCK].rlim_cur = i / 3;
|
||||
limit0.pl_corename = defcorename;
|
||||
limit0.p_refcnt = 1;
|
||||
|
||||
/*
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: kern_exec.c,v 1.102 1999/08/09 02:42:20 ross Exp $ */
|
||||
/* $NetBSD: kern_exec.c,v 1.103 1999/09/28 14:47:03 bouyer Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (C) 1993, 1994, 1996 Christopher G. Demetriou
|
||||
|
@ -457,7 +457,7 @@ sys_execve(p, v, retval)
|
|||
p->p_ucred->cr_uid = attr.va_uid;
|
||||
if (attr.va_mode & S_ISGID)
|
||||
p->p_ucred->cr_gid = attr.va_gid;
|
||||
p->p_flag |= P_SUGID;
|
||||
p_sugid(p);
|
||||
} else
|
||||
p->p_flag &= ~P_SUGID;
|
||||
p->p_cred->p_svuid = p->p_ucred->cr_uid;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: kern_exit.c,v 1.73 1999/07/22 21:08:31 thorpej Exp $ */
|
||||
/* $NetBSD: kern_exit.c,v 1.74 1999/09/28 14:47:03 bouyer Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1998, 1999 The NetBSD Foundation, Inc.
|
||||
|
@ -326,8 +326,7 @@ exit1(p, rv)
|
|||
* Other substructures are freed from wait().
|
||||
*/
|
||||
curproc = NULL;
|
||||
if (--p->p_limit->p_refcnt == 0)
|
||||
pool_put(&plimit_pool, p->p_limit);
|
||||
limfree(p->p_limit);
|
||||
|
||||
/*
|
||||
* Finally, call machine-dependent code to switch to a new
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: kern_proc.c,v 1.34 1999/07/25 06:30:34 thorpej Exp $ */
|
||||
/* $NetBSD: kern_proc.c,v 1.35 1999/09/28 14:47:03 bouyer Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1999 The NetBSD Foundation, Inc.
|
||||
|
@ -519,6 +519,29 @@ orphanpg(pg)
|
|||
}
|
||||
}
|
||||
|
||||
/* mark process as suid/sgid, reset some values do defaults */
|
||||
void
|
||||
p_sugid(p)
|
||||
struct proc *p;
|
||||
{
|
||||
struct plimit *newlim;
|
||||
|
||||
p->p_flag |= P_SUGID;
|
||||
/* reset what needs to be reset in plimit */
|
||||
if (p->p_limit->pl_corename != defcorename) {
|
||||
if (p->p_limit->p_refcnt > 1 &&
|
||||
(p->p_limit->p_lflags & PL_SHAREMOD) == 0) {
|
||||
newlim = limcopy(p->p_limit);
|
||||
limfree(p->p_limit);
|
||||
p->p_limit = newlim;
|
||||
} else {
|
||||
free(p->p_limit->pl_corename, M_TEMP);
|
||||
}
|
||||
p->p_limit->pl_corename = defcorename;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifdef DEBUG
|
||||
void
|
||||
pgrpdump()
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: kern_prot.c,v 1.54 1999/04/30 05:30:32 cgd Exp $ */
|
||||
/* $NetBSD: kern_prot.c,v 1.55 1999/09/28 14:47:03 bouyer Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1982, 1986, 1989, 1990, 1991, 1993
|
||||
|
@ -335,7 +335,7 @@ sys_setuid(p, v, retval)
|
|||
pc->pc_ucred->cr_uid = uid;
|
||||
pc->p_ruid = uid;
|
||||
pc->p_svuid = uid;
|
||||
p->p_flag |= P_SUGID;
|
||||
p_sugid(p);
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
@ -363,7 +363,7 @@ sys_seteuid(p, v, retval)
|
|||
*/
|
||||
pc->pc_ucred = crcopy(pc->pc_ucred);
|
||||
pc->pc_ucred->cr_uid = euid;
|
||||
p->p_flag |= P_SUGID;
|
||||
p_sugid(p);
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
@ -408,7 +408,7 @@ sys_setreuid(p, v, retval)
|
|||
}
|
||||
|
||||
if (euid != (uid_t)-1 && ruid != (uid_t)-1)
|
||||
p->p_flag |= P_SUGID;
|
||||
p_sugid(p);
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
@ -434,7 +434,7 @@ sys_setgid(p, v, retval)
|
|||
pc->pc_ucred->cr_gid = gid;
|
||||
pc->p_rgid = gid;
|
||||
pc->p_svgid = gid;
|
||||
p->p_flag |= P_SUGID;
|
||||
p_sugid(p);
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
@ -458,7 +458,7 @@ sys_setegid(p, v, retval)
|
|||
return (error);
|
||||
pc->pc_ucred = crcopy(pc->pc_ucred);
|
||||
pc->pc_ucred->cr_gid = egid;
|
||||
p->p_flag |= P_SUGID;
|
||||
p_sugid(p);
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
@ -501,7 +501,7 @@ sys_setregid(p, v, retval)
|
|||
}
|
||||
|
||||
if (egid != (gid_t)-1 && rgid != (gid_t)-1)
|
||||
p->p_flag |= P_SUGID;
|
||||
p_sugid(p);
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
@ -531,7 +531,7 @@ sys_setgroups(p, v, retval)
|
|||
if (error)
|
||||
return (error);
|
||||
pc->pc_ucred->cr_ngroups = ngrp;
|
||||
p->p_flag |= P_SUGID;
|
||||
p_sugid(p);
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: kern_resource.c,v 1.52 1999/07/25 06:30:34 thorpej Exp $ */
|
||||
/* $NetBSD: kern_resource.c,v 1.53 1999/09/28 14:47:03 bouyer Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1982, 1986, 1991, 1993
|
||||
|
@ -56,7 +56,6 @@
|
|||
|
||||
#include <uvm/uvm_extern.h>
|
||||
|
||||
void limfree __P((struct plimit *));
|
||||
/*
|
||||
* Resource controls and accounting.
|
||||
*/
|
||||
|
@ -225,17 +224,19 @@ sys_setrlimit(p, v, retval)
|
|||
error = copyin(SCARG(uap, rlp), &alim, sizeof(struct rlimit));
|
||||
if (error)
|
||||
return (error);
|
||||
return (dosetrlimit(p, which, &alim));
|
||||
return (dosetrlimit(p, p->p_cred, which, &alim));
|
||||
}
|
||||
|
||||
int
|
||||
dosetrlimit(p, which, limp)
|
||||
dosetrlimit(p, cred, which, limp)
|
||||
struct proc *p;
|
||||
struct pcred *cred;
|
||||
int which;
|
||||
struct rlimit *limp;
|
||||
{
|
||||
register struct rlimit *alimp;
|
||||
extern unsigned maxdmap, maxsmap;
|
||||
struct plimit *newplim;
|
||||
int error;
|
||||
|
||||
if ((u_int)which >= RLIM_NLIMITS)
|
||||
|
@ -245,16 +246,22 @@ dosetrlimit(p, which, limp)
|
|||
return (EINVAL);
|
||||
|
||||
alimp = &p->p_rlimit[which];
|
||||
/* if we don't change the value, no need to limcopy() */
|
||||
if (limp->rlim_cur == alimp->rlim_cur &&
|
||||
limp->rlim_max == alimp->rlim_max)
|
||||
return 0;
|
||||
|
||||
if (limp->rlim_cur > alimp->rlim_max ||
|
||||
limp->rlim_max > alimp->rlim_max)
|
||||
if ((error = suser(p->p_ucred, &p->p_acflag)) != 0)
|
||||
if ((error = suser(cred->pc_ucred, &p->p_acflag)) != 0)
|
||||
return (error);
|
||||
if (limp->rlim_cur > limp->rlim_max)
|
||||
limp->rlim_cur = limp->rlim_max;
|
||||
if (p->p_limit->p_refcnt > 1 &&
|
||||
(p->p_limit->p_lflags & PL_SHAREMOD) == 0) {
|
||||
p->p_limit->p_refcnt--;
|
||||
p->p_limit = limcopy(p->p_limit);
|
||||
newplim = limcopy(p->p_limit);
|
||||
limfree(p->p_limit);
|
||||
p->p_limit = newplim;
|
||||
alimp = &p->p_rlimit[which];
|
||||
}
|
||||
|
||||
|
@ -458,6 +465,13 @@ limcopy(lim)
|
|||
newlim = pool_get(&plimit_pool, PR_WAITOK);
|
||||
memcpy(newlim->pl_rlimit, lim->pl_rlimit,
|
||||
sizeof(struct rlimit) * RLIM_NLIMITS);
|
||||
if (lim->pl_corename == defcorename) {
|
||||
newlim->pl_corename = defcorename;
|
||||
} else {
|
||||
newlim->pl_corename = malloc(strlen(lim->pl_corename)+1,
|
||||
M_TEMP, M_WAITOK);
|
||||
strcpy(newlim->pl_corename, lim->pl_corename);
|
||||
}
|
||||
newlim->p_lflags = 0;
|
||||
newlim->p_refcnt = 1;
|
||||
return (newlim);
|
||||
|
@ -470,5 +484,11 @@ limfree(lim)
|
|||
|
||||
if (--lim->p_refcnt > 0)
|
||||
return;
|
||||
#ifdef DIAGNOSTIC
|
||||
if (lim->p_refcnt < 0)
|
||||
panic("limfree");
|
||||
#endif
|
||||
if (lim->pl_corename != defcorename)
|
||||
free(lim->pl_corename, M_TEMP);
|
||||
pool_put(&plimit_pool, lim);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: kern_sig.c,v 1.93 1999/08/31 12:30:35 bouyer Exp $ */
|
||||
/* $NetBSD: kern_sig.c,v 1.94 1999/09/28 14:47:03 bouyer Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1982, 1986, 1989, 1991, 1993
|
||||
|
@ -79,6 +79,7 @@
|
|||
|
||||
void stop __P((struct proc *p));
|
||||
void killproc __P((struct proc *, char *));
|
||||
static int build_corename __P((char *));
|
||||
|
||||
sigset_t contsigmask, stopsigmask, sigcantmask;
|
||||
|
||||
|
@ -1264,9 +1265,8 @@ coredump(p)
|
|||
struct nameidata nd;
|
||||
struct vattr vattr;
|
||||
int error, error1;
|
||||
char name[MAXCOMLEN+6]; /* progname.core */
|
||||
char name[MAXPATHLEN];
|
||||
struct core core;
|
||||
extern int shortcorename;
|
||||
|
||||
/*
|
||||
* Make sure the process has not set-id, to prevent data leaks.
|
||||
|
@ -1293,11 +1293,10 @@ coredump(p)
|
|||
(vp->v_mount->mnt_flag & MNT_NOCOREDUMP) != 0)
|
||||
return (EPERM);
|
||||
|
||||
if (shortcorename)
|
||||
sprintf(name, "core");
|
||||
else
|
||||
sprintf(name, "%s.core", p->p_comm);
|
||||
|
||||
error = build_corename(name);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
NDINIT(&nd, LOOKUP, NOFOLLOW, UIO_SYSSPACE, name, p);
|
||||
error = vn_open(&nd, O_CREAT | FWRITE | FNOSYMLINK, S_IRUSR | S_IWUSR);
|
||||
if (error)
|
||||
|
@ -1394,3 +1393,51 @@ sys_nosys(p, v, retval)
|
|||
psignal(p, SIGSYS);
|
||||
return (ENOSYS);
|
||||
}
|
||||
|
||||
static int
|
||||
build_corename(dst)
|
||||
char *dst;
|
||||
{
|
||||
const char *s;
|
||||
char *d;
|
||||
int len, i;
|
||||
|
||||
for (s = curproc->p_limit->pl_corename, len = 0, d = dst;
|
||||
*s != '\0'; s++) {
|
||||
if (*s == '%') {
|
||||
switch (*(s+1)) {
|
||||
case 'n':
|
||||
i = snprintf(d,MAXPATHLEN - 1 - len, "%s",
|
||||
curproc->p_comm);
|
||||
break;
|
||||
case 'p':
|
||||
i = snprintf(d, MAXPATHLEN - 1 - len, "%d",
|
||||
curproc->p_pid);
|
||||
break;
|
||||
case 'u':
|
||||
i = snprintf(d, MAXPATHLEN - 1 - len, "%s",
|
||||
curproc->p_pgrp->pg_session->s_login);
|
||||
break;
|
||||
case 't':
|
||||
i = snprintf(d, MAXPATHLEN - 1 - len, "%ld",
|
||||
curproc->p_stats->p_start.tv_sec);
|
||||
break;
|
||||
default:
|
||||
goto copy;
|
||||
}
|
||||
if (i >= MAXPATHLEN - 1 - len)
|
||||
return ENAMETOOLONG;
|
||||
len += i;
|
||||
d += i;
|
||||
s++;
|
||||
} else {
|
||||
copy: *d = *s;
|
||||
d++;
|
||||
len++;
|
||||
if (len >= MAXPATHLEN - 1)
|
||||
return ENAMETOOLONG;
|
||||
}
|
||||
}
|
||||
*d = '\0';
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: kern_sysctl.c,v 1.51 1999/09/27 16:24:40 kleink Exp $ */
|
||||
/* $NetBSD: kern_sysctl.c,v 1.52 1999/09/28 14:47:04 bouyer Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1982, 1986, 1989, 1993
|
||||
|
@ -44,13 +44,14 @@
|
|||
|
||||
#include "opt_ddb.h"
|
||||
#include "opt_insecure.h"
|
||||
#include "opt_shortcorename.h"
|
||||
#include "opt_defcorename.h"
|
||||
#include "opt_sysv.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/pool.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/file.h>
|
||||
#include <sys/vnode.h>
|
||||
|
@ -68,6 +69,8 @@
|
|||
|
||||
#include <sys/mount.h>
|
||||
#include <sys/syscallargs.h>
|
||||
#include <sys/resource.h>
|
||||
#include <sys/resourcevar.h>
|
||||
|
||||
|
||||
#if defined(DDB)
|
||||
|
@ -102,9 +105,6 @@ sys___sysctl(p, v, retval)
|
|||
sysctlfn *fn;
|
||||
int name[CTL_MAXNAME];
|
||||
|
||||
if (SCARG(uap, new) != NULL &&
|
||||
(error = suser(p->p_ucred, &p->p_acflag)))
|
||||
return (error);
|
||||
/*
|
||||
* all top-level sysctl names are non-terminal
|
||||
*/
|
||||
|
@ -115,6 +115,15 @@ sys___sysctl(p, v, retval)
|
|||
if (error)
|
||||
return (error);
|
||||
|
||||
/*
|
||||
* For all but CTL_PROC, must be root to change a value.
|
||||
* For CTL_PROC, must be root, or owner of the proc (and not suid),
|
||||
* this is checked in proc_sysctl() (once we know the targer proc).
|
||||
*/
|
||||
if (SCARG(uap, new) != NULL && name[0] != CTL_PROC &&
|
||||
(error = suser(p->p_ucred, &p->p_acflag)))
|
||||
return error;
|
||||
|
||||
switch (name[0]) {
|
||||
case CTL_KERN:
|
||||
fn = kern_sysctl;
|
||||
|
@ -146,6 +155,9 @@ sys___sysctl(p, v, retval)
|
|||
fn = ddb_sysctl;
|
||||
break;
|
||||
#endif
|
||||
case CTL_PROC:
|
||||
fn = proc_sysctl;
|
||||
break;
|
||||
default:
|
||||
return (EOPNOTSUPP);
|
||||
}
|
||||
|
@ -210,10 +222,12 @@ int securelevel = -1;
|
|||
#else
|
||||
int securelevel = 0;
|
||||
#endif
|
||||
#ifdef SHORTCORENAME
|
||||
int shortcorename = 1;
|
||||
#ifdef DEFCORENAME
|
||||
char defcorename[MAXPATHLEN] = DEFCORENAME;
|
||||
int defcorenamelen = sizeof(DEFCORENAME);
|
||||
#else
|
||||
int shortcorename = 0;
|
||||
char defcorename[MAXPATHLEN] = "%n.core";
|
||||
int defcorenamelen = sizeof("%n.core");
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
@ -232,7 +246,6 @@ kern_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p)
|
|||
int error, level, inthostid;
|
||||
int old_autonicetime;
|
||||
int old_vnodes;
|
||||
int old_shortcorename;
|
||||
extern char ostype[], osrelease[], version[];
|
||||
|
||||
/* All sysctl names at this level, except for a few, are terminal. */
|
||||
|
@ -304,7 +317,7 @@ kern_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p)
|
|||
case KERN_VNODE:
|
||||
return (sysctl_vnode(oldp, oldlenp, p));
|
||||
case KERN_PROC:
|
||||
return (sysctl_doproc(name + 1, namelen - 1, oldp, oldlenp));
|
||||
return (sysctl_doeproc(name + 1, namelen - 1, oldp, oldlenp));
|
||||
case KERN_FILE:
|
||||
return (sysctl_file(oldp, oldlenp));
|
||||
#ifdef GPROF
|
||||
|
@ -380,16 +393,14 @@ kern_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p)
|
|||
#else
|
||||
return (sysctl_rdint(oldp, oldlenp, newp, 0));
|
||||
#endif
|
||||
case KERN_SHORTCORENAME:
|
||||
/* Only allow values of zero or one. */
|
||||
old_shortcorename = shortcorename;
|
||||
error = sysctl_int(oldp, oldlenp, newp, newlen,
|
||||
&shortcorename);
|
||||
if (shortcorename != 0 && shortcorename != 1) {
|
||||
shortcorename = old_shortcorename;
|
||||
return (EINVAL);
|
||||
}
|
||||
return (error);
|
||||
case KERN_DEFCORENAME:
|
||||
if (newp && newlen < 1)
|
||||
return (EINVAL);
|
||||
error = sysctl_string(oldp, oldlenp, newp, newlen,
|
||||
defcorename, sizeof(defcorename));
|
||||
if (newp && !error)
|
||||
defcorenamelen = newlen;
|
||||
return (error);
|
||||
case KERN_SYNCHRONIZED_IO:
|
||||
return (sysctl_rdint(oldp, oldlenp, newp, 1));
|
||||
case KERN_IOV_MAX:
|
||||
|
@ -500,6 +511,152 @@ debug_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p)
|
|||
}
|
||||
#endif /* DEBUG */
|
||||
|
||||
int
|
||||
proc_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p)
|
||||
int *name;
|
||||
u_int namelen;
|
||||
void *oldp;
|
||||
size_t *oldlenp;
|
||||
void *newp;
|
||||
size_t newlen;
|
||||
struct proc *p;
|
||||
{
|
||||
struct proc *ptmp;
|
||||
const struct proclist_desc *pd;
|
||||
int error = 0;
|
||||
struct rlimit alim;
|
||||
struct plimit *newplim;
|
||||
char *tmps = NULL;
|
||||
int i, curlen, len;
|
||||
|
||||
if (namelen < 2)
|
||||
return EINVAL;
|
||||
|
||||
if (name[0] == PROC_CURPROC) {
|
||||
ptmp = p;
|
||||
} else {
|
||||
proclist_lock_read();
|
||||
for (pd = proclists; pd->pd_list != NULL; pd++) {
|
||||
for (ptmp = LIST_FIRST(pd->pd_list); ptmp != NULL;
|
||||
ptmp = LIST_NEXT(ptmp, p_list)) {
|
||||
/* Skip embryonic processes. */
|
||||
if (ptmp->p_stat == SIDL)
|
||||
continue;
|
||||
if (ptmp->p_pid == (pid_t)name[0])
|
||||
break;
|
||||
}
|
||||
if (ptmp != NULL)
|
||||
break;
|
||||
}
|
||||
proclist_unlock_read();
|
||||
if (ptmp == NULL)
|
||||
return(ESRCH);
|
||||
if (p->p_ucred->cr_uid != 0) {
|
||||
if(p->p_cred->p_ruid != ptmp->p_cred->p_ruid ||
|
||||
p->p_cred->p_ruid != ptmp->p_cred->p_svuid)
|
||||
return EPERM;
|
||||
if (ptmp->p_cred->p_rgid != ptmp->p_cred->p_svgid)
|
||||
return EPERM; /* sgid proc */
|
||||
for (i = 0; i < p->p_ucred->cr_ngroups; i++) {
|
||||
if (p->p_ucred->cr_groups[i] ==
|
||||
ptmp->p_cred->p_rgid)
|
||||
break;
|
||||
}
|
||||
if (i == p->p_ucred->cr_ngroups)
|
||||
return EPERM;
|
||||
}
|
||||
}
|
||||
if (name[1] == PROC_PID_CORENAME) {
|
||||
if (namelen != 2)
|
||||
return EINVAL;
|
||||
/*
|
||||
* Can't use sysctl_string() here because we may malloc a new
|
||||
* area during the process, so we have to do it by hand.
|
||||
*/
|
||||
curlen = strlen(ptmp->p_limit->pl_corename) + 1;
|
||||
if (oldp && *oldlenp < curlen)
|
||||
return (ENOMEM);
|
||||
if (newp) {
|
||||
if (securelevel > 2)
|
||||
return EPERM;
|
||||
if (newlen > MAXPATHLEN)
|
||||
return ENAMETOOLONG;
|
||||
tmps = malloc(newlen + 1, M_TEMP, M_WAITOK);
|
||||
if (tmps == NULL)
|
||||
return ENOMEM;
|
||||
error = copyin(newp, tmps, newlen + 1);
|
||||
tmps[newlen] = '\0';
|
||||
if (error)
|
||||
goto cleanup;
|
||||
/* Enforce to be either 'core' for end with '.core' */
|
||||
if (newlen < 4) { /* c.o.r.e */
|
||||
error = EINVAL;
|
||||
goto cleanup;
|
||||
}
|
||||
len = newlen - 4;
|
||||
if (len > 0) {
|
||||
if (tmps[len - 1] != '.' &&
|
||||
tmps[len - 1] != '/') {
|
||||
error = EINVAL;
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
if (strcmp(&tmps[len], "core") != 0) {
|
||||
error = EINVAL;
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
if (oldp) {
|
||||
*oldlenp = curlen;
|
||||
error = copyout(ptmp->p_limit->pl_corename, oldp,
|
||||
curlen);
|
||||
}
|
||||
if (newp && error == 0) {
|
||||
/* if the 2 strings are identical, don't limcopy() */
|
||||
if (strcmp(tmps, ptmp->p_limit->pl_corename) == 0) {
|
||||
error = 0;
|
||||
goto cleanup;
|
||||
}
|
||||
if (ptmp->p_limit->p_refcnt > 1 &&
|
||||
(ptmp->p_limit->p_lflags & PL_SHAREMOD) == 0) {
|
||||
newplim = limcopy(ptmp->p_limit);
|
||||
limfree(ptmp->p_limit);
|
||||
ptmp->p_limit = newplim;
|
||||
} else if (ptmp->p_limit->pl_corename != defcorename) {
|
||||
free(ptmp->p_limit->pl_corename, M_TEMP);
|
||||
}
|
||||
ptmp->p_limit->pl_corename = tmps;
|
||||
return (0);
|
||||
}
|
||||
cleanup:
|
||||
if (tmps)
|
||||
free(tmps, M_TEMP);
|
||||
return (error);
|
||||
}
|
||||
if (name[1] == PROC_PID_LIMIT) {
|
||||
if (namelen != 4 || name[2] >= PROC_PID_LIMIT_MAXID)
|
||||
return EINVAL;
|
||||
memcpy(&alim, &ptmp->p_rlimit[name[2] - 1], sizeof(alim));
|
||||
if (name[3] == PROC_PID_LIMIT_TYPE_HARD)
|
||||
error = sysctl_quad(oldp, oldlenp, newp, newlen,
|
||||
&alim.rlim_max);
|
||||
else if (name[3] == PROC_PID_LIMIT_TYPE_SOFT)
|
||||
error = sysctl_quad(oldp, oldlenp, newp, newlen,
|
||||
&alim.rlim_cur);
|
||||
else
|
||||
error = EINVAL;
|
||||
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
if (newp)
|
||||
error = dosetrlimit(ptmp, p->p_cred,
|
||||
name[2] - 1, &alim);
|
||||
return error;
|
||||
}
|
||||
return (EINVAL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Validate parameters and get old / set new parameters
|
||||
* for an integer-valued sysctl function.
|
||||
|
@ -548,6 +705,55 @@ sysctl_rdint(oldp, oldlenp, newp, val)
|
|||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
* Validate parameters and get old / set new parameters
|
||||
* for an quad-valued sysctl function.
|
||||
*/
|
||||
int
|
||||
sysctl_quad(oldp, oldlenp, newp, newlen, valp)
|
||||
void *oldp;
|
||||
size_t *oldlenp;
|
||||
void *newp;
|
||||
size_t newlen;
|
||||
quad_t *valp;
|
||||
{
|
||||
int error = 0;
|
||||
|
||||
if (oldp && *oldlenp < sizeof(quad_t))
|
||||
return (ENOMEM);
|
||||
if (newp && newlen != sizeof(quad_t))
|
||||
return (EINVAL);
|
||||
*oldlenp = sizeof(quad_t);
|
||||
if (oldp)
|
||||
error = copyout(valp, oldp, sizeof(quad_t));
|
||||
if (error == 0 && newp)
|
||||
error = copyin(newp, valp, sizeof(quad_t));
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
* As above, but read-only.
|
||||
*/
|
||||
int
|
||||
sysctl_rdquad(oldp, oldlenp, newp, val)
|
||||
void *oldp;
|
||||
size_t *oldlenp;
|
||||
void *newp;
|
||||
quad_t val;
|
||||
{
|
||||
int error = 0;
|
||||
|
||||
if (oldp && *oldlenp < sizeof(quad_t))
|
||||
return (ENOMEM);
|
||||
if (newp)
|
||||
return (EPERM);
|
||||
*oldlenp = sizeof(quad_t);
|
||||
if (oldp)
|
||||
error = copyout((caddr_t)&val, oldp, sizeof(quad_t));
|
||||
return (error);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Validate parameters and get old / set new parameters
|
||||
* for a string-valued sysctl function.
|
||||
|
@ -711,7 +917,7 @@ sysctl_file(where, sizep)
|
|||
#define KERN_PROCSLOP (5 * sizeof(struct kinfo_proc))
|
||||
|
||||
int
|
||||
sysctl_doproc(name, namelen, where, sizep)
|
||||
sysctl_doeproc(name, namelen, where, sizep)
|
||||
int *name;
|
||||
u_int namelen;
|
||||
char *where;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: proc.h,v 1.83 1999/08/10 23:33:27 thorpej Exp $ */
|
||||
/* $NetBSD: proc.h,v 1.84 1999/09/28 14:47:04 bouyer Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1986, 1989, 1991, 1993
|
||||
|
@ -392,5 +392,6 @@ void proclist_lock_read __P((void));
|
|||
void proclist_unlock_read __P((void));
|
||||
int proclist_lock_write __P((void));
|
||||
void proclist_unlock_write __P((int));
|
||||
void p_sugid __P((struct proc*));
|
||||
#endif /* _KERNEL */
|
||||
#endif /* !_SYS_PROC_H_ */
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: resource.h,v 1.19 1998/12/09 14:39:09 christos Exp $ */
|
||||
/* $NetBSD: resource.h,v 1.20 1999/09/28 14:47:04 bouyer Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1982, 1986, 1993
|
||||
|
@ -120,7 +120,8 @@ struct loadavg {
|
|||
|
||||
#ifdef _KERNEL
|
||||
extern struct loadavg averunnable;
|
||||
int dosetrlimit __P((struct proc *, int, struct rlimit *));
|
||||
struct pcred;
|
||||
int dosetrlimit __P((struct proc *, struct pcred *, int, struct rlimit *));
|
||||
int donice __P((struct proc *, struct proc *, int));
|
||||
|
||||
#else
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: resourcevar.h,v 1.13 1998/03/01 02:24:14 fvdl Exp $ */
|
||||
/* $NetBSD: resourcevar.h,v 1.14 1999/09/28 14:47:04 bouyer Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1991, 1993
|
||||
|
@ -73,6 +73,7 @@ struct pstats {
|
|||
*/
|
||||
struct plimit {
|
||||
struct rlimit pl_rlimit[RLIM_NLIMITS];
|
||||
char *pl_corename;
|
||||
#define PL_SHAREMOD 0x01 /* modifications are shared */
|
||||
int p_lflags;
|
||||
int p_refcnt; /* number of references */
|
||||
|
@ -84,12 +85,13 @@ struct plimit {
|
|||
(p)->p_stats->p_prof.pr_addr, (p)->p_stats->p_prof.pr_ticks)
|
||||
|
||||
#ifdef _KERNEL
|
||||
extern char defcorename[];
|
||||
void addupc_intr __P((struct proc *p, u_long pc, u_int ticks));
|
||||
void addupc_task __P((struct proc *p, u_long pc, u_int ticks));
|
||||
void calcru __P((struct proc *p, struct timeval *up, struct timeval *sp,
|
||||
struct timeval *ip));
|
||||
struct plimit
|
||||
*limcopy __P((struct plimit *lim));
|
||||
struct plimit *limcopy __P((struct plimit *lim));
|
||||
void limfree __P((struct plimit *));
|
||||
void ruadd __P((struct rusage *ru, struct rusage *ru2));
|
||||
#endif
|
||||
#endif /* !_SYS_RESOURCEVAR_H_ */
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: sysctl.h,v 1.36 1999/09/27 16:24:40 kleink Exp $ */
|
||||
/* $NetBSD: sysctl.h,v 1.37 1999/09/28 14:47:04 bouyer Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1989, 1993
|
||||
|
@ -92,7 +92,8 @@ struct ctlname {
|
|||
#define CTL_MACHDEP 7 /* machine dependent */
|
||||
#define CTL_USER 8 /* user-level */
|
||||
#define CTL_DDB 9 /* in-kernel debugger */
|
||||
#define CTL_MAXID 10 /* number of valid top-level ids */
|
||||
#define CTL_PROC 10 /* per-proc attr */
|
||||
#define CTL_MAXID 11 /* number of valid top-level ids */
|
||||
|
||||
#define CTL_NAMES { \
|
||||
{ 0, 0 }, \
|
||||
|
@ -105,6 +106,7 @@ struct ctlname {
|
|||
{ "machdep", CTLTYPE_NODE }, \
|
||||
{ "user", CTLTYPE_NODE }, \
|
||||
{ "ddb", CTLTYPE_NODE }, \
|
||||
{ "proc", CTLTYPE_NODE }, \
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -145,7 +147,7 @@ struct ctlname {
|
|||
#define KERN_SYSVMSG 33 /* int: SysV message queue suppoprt */
|
||||
#define KERN_SYSVSEM 34 /* int: SysV semaphore support */
|
||||
#define KERN_SYSVSHM 35 /* int: SysV shared memory support */
|
||||
#define KERN_SHORTCORENAME 36 /* int: programs dump core as "core" */
|
||||
#define KERN_DEFCORENAME 36 /* string: default corename format */
|
||||
#define KERN_SYNCHRONIZED_IO 37 /* int: POSIX synchronized I/O */
|
||||
#define KERN_IOV_MAX 38 /* int: max iovec's for readv(2) etc. */
|
||||
#define KERN_MBUF 39 /* node: mbuf parameters */
|
||||
|
@ -193,7 +195,7 @@ struct ctlname {
|
|||
{ "sysvmsg", CTLTYPE_INT }, \
|
||||
{ "sysvsem", CTLTYPE_INT }, \
|
||||
{ "sysvshm", CTLTYPE_INT }, \
|
||||
{ "shortcorename", CTLTYPE_INT }, \
|
||||
{ "defcorename", CTLTYPE_STRING }, \
|
||||
{ "synchronized_io", CTLTYPE_INT }, \
|
||||
{ "iov_max", CTLTYPE_INT }, \
|
||||
{ "mbuf", CTLTYPE_NODE }, \
|
||||
|
@ -358,6 +360,61 @@ struct kinfo_proc {
|
|||
#define CTL_DEBUG_VALUE 1 /* int: variable value */
|
||||
#define CTL_DEBUG_MAXID 20
|
||||
|
||||
/*
|
||||
* CTL_PROC subtype. Either a PID, or a magic value for the current proc.
|
||||
*/
|
||||
|
||||
#define PROC_CURPROC (~((u_int)1 << 31))
|
||||
|
||||
/*
|
||||
* CTL_PROC tree: either corename (string), or a limit
|
||||
* (rlimit.<type>.{hard,soft}, int).
|
||||
*/
|
||||
#define PROC_PID_CORENAME 1
|
||||
#define PROC_PID_LIMIT 2
|
||||
#define PROC_PID_MAXID 3
|
||||
|
||||
#define PROC_PID_NAMES { \
|
||||
{ 0, 0 }, \
|
||||
{ "corename", CTLTYPE_STRING }, \
|
||||
{ "rlimit", CTLTYPE_NODE }, \
|
||||
}
|
||||
|
||||
/* Limit types from <sys/resources.h> */
|
||||
#define PROC_PID_LIMIT_CPU (RLIMIT_CPU+1)
|
||||
#define PROC_PID_LIMIT_FSIZE (RLIMIT_FSIZE+1)
|
||||
#define PROC_PID_LIMIT_DATA (RLIMIT_DATA+1)
|
||||
#define PROC_PID_LIMIT_STACK (RLIMIT_STACK+1)
|
||||
#define PROC_PID_LIMIT_CORE (RLIMIT_CORE+1)
|
||||
#define PROC_PID_LIMIT_RSS (RLIMIT_RSS+1)
|
||||
#define PROC_PID_LIMIT_MEMLOCK (RLIMIT_MEMLOCK+1)
|
||||
#define PROC_PID_LIMIT_NPROC (RLIMIT_NPROC+1)
|
||||
#define PROC_PID_LIMIT_NOFILE (RLIMIT_NOFILE+1)
|
||||
#define PROC_PID_LIMIT_MAXID 10
|
||||
|
||||
#define PROC_PID_LIMIT_NAMES { \
|
||||
{ 0, 0 }, \
|
||||
{ "cputime", CTLTYPE_NODE }, \
|
||||
{ "filesize", CTLTYPE_NODE }, \
|
||||
{ "datasize", CTLTYPE_NODE }, \
|
||||
{ "stacksize", CTLTYPE_NODE }, \
|
||||
{ "coredumpsize", CTLTYPE_NODE }, \
|
||||
{ "memoryuse", CTLTYPE_NODE }, \
|
||||
{ "memorylocked", CTLTYPE_NODE }, \
|
||||
{ "maxproc", CTLTYPE_NODE }, \
|
||||
{ "descriptors", CTLTYPE_NODE }, \
|
||||
}
|
||||
/* for each type, either hard or soft value */
|
||||
#define PROC_PID_LIMIT_TYPE_SOFT 1
|
||||
#define PROC_PID_LIMIT_TYPE_HARD 2
|
||||
#define PROC_PID_LIMIT_TYPE_MAXID 3
|
||||
|
||||
#define PROC_PID_LIMIT_TYPE_NAMES { \
|
||||
{0, 0}, \
|
||||
{ "soft", CTLTYPE_QUAD }, \
|
||||
{ "hard", CTLTYPE_QUAD }, \
|
||||
}
|
||||
|
||||
#ifdef _KERNEL
|
||||
/*
|
||||
* CTL_DEBUG variables.
|
||||
|
@ -396,12 +453,14 @@ typedef int (sysctlfn)
|
|||
|
||||
int sysctl_int __P((void *, size_t *, void *, size_t, int *));
|
||||
int sysctl_rdint __P((void *, size_t *, void *, int));
|
||||
int sysctl_quad __P((void *, size_t *, void *, size_t, quad_t *));
|
||||
int sysctl_rdquad __P((void *, size_t *, void *, quad_t));
|
||||
int sysctl_string __P((void *, size_t *, void *, size_t, char *, int));
|
||||
int sysctl_rdstring __P((void *, size_t *, void *, char *));
|
||||
int sysctl_rdstruct __P((void *, size_t *, void *, void *, int));
|
||||
int sysctl_struct __P((void *, size_t *, void *, size_t, void *, int));
|
||||
int sysctl_file __P((char *, size_t *));
|
||||
int sysctl_doproc __P((int *, u_int, char *, size_t *));
|
||||
int sysctl_doeproc __P((int *, u_int, char *, size_t *));
|
||||
struct radix_node;
|
||||
struct walkarg;
|
||||
int sysctl_dumpentry __P((struct radix_node *, void *));
|
||||
|
@ -423,6 +482,8 @@ int kern_sysctl __P((int *, u_int, void *, size_t *, void *, size_t,
|
|||
struct proc *));
|
||||
int hw_sysctl __P((int *, u_int, void *, size_t *, void *, size_t,
|
||||
struct proc *));
|
||||
int proc_sysctl __P((int *, u_int, void *, size_t *, void *, size_t,
|
||||
struct proc *));
|
||||
#ifdef DEBUG
|
||||
int debug_sysctl __P((int *, u_int, void *, size_t *, void *, size_t,
|
||||
struct proc *));
|
||||
|
|
Loading…
Reference in New Issue