Date: Sun, 31 May 2009 18:01:13 GMT From: Edward Tomasz Napierala <trasz@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 163184 for review Message-ID: <200905311801.n4VI1DKm016109@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=163184 Change 163184 by trasz@trasz_victim on 2009/05/31 18:01:07 Put limits set via rlimit(2) into hrl. Affected files ... .. //depot/projects/soc2009/trasz_limits/sys/kern/kern_hrl.c#2 edit .. //depot/projects/soc2009/trasz_limits/sys/kern/kern_resource.c#2 edit .. //depot/projects/soc2009/trasz_limits/sys/sys/hrl.h#3 edit .. //depot/projects/soc2009/trasz_limits/usr.sbin/hrl/hrl.c#3 edit Differences ... ==== //depot/projects/soc2009/trasz_limits/sys/kern/kern_hrl.c#2 (text+ko) ==== @@ -32,22 +32,85 @@ #include <sys/malloc.h> #include <sys/kernel.h> #include <sys/priv.h> +#include <sys/proc.h> #include <sys/sysent.h> #include <sys/sysproto.h> #include <sys/systm.h> #include <sys/types.h> +#include <sys/eventhandler.h> +#include <sys/lock.h> +#include <sys/mutex.h> MALLOC_DEFINE(M_HRL, "hrl", "Hierarchical Resource Limits"); /* - * XXX: Locking. + * XXX: Need a better way to store stuff; rbtree? */ -static struct hrl_limit **limits = NULL; +static struct hrl_limit *limits = NULL; static int nlimits = 0; +static struct mtx hrllock; + +static void hrl_init(void); +SYSINIT(hrl, SI_SUB_RUN_SCHEDULER, SI_ORDER_SECOND, hrl_init, NULL); + +int +hrl_alloc(int object, uint64_t amount) +{ + + KASSERT(amount > 0, ("invalid amount")); + + return (0); +} + +void +hrl_free(int object, uint64_t amount) +{ + + KASSERT(amount > 0, ("invalid amount")); +} + +void +hrl_adjust(int subject, id_t subject_id, int per, int object, int action, int64_t amount) +{ + mtx_lock(&hrllock); + + nlimits++; + /* + * XXX: Make it possible to remove and overwrite limits, not just add them. + */ + limits = realloc(limits, sizeof(struct hrl_limit) * nlimits, M_HRL, M_WAITOK); + + limits[nlimits - 1].hl_subject = subject; + limits[nlimits - 1].hl_subject_id = subject_id; + limits[nlimits - 1].hl_per = per; + limits[nlimits - 1].hl_object = object; + limits[nlimits - 1].hl_action = action; + limits[nlimits - 1].hl_amount = amount; + + mtx_unlock(&hrllock); +} + +/* + * System calls. + */ static int -hrl_check(struct hrl_limit **limits, int nlimits) +hrl_check(struct hrl_limit *limits, int nlimits) { + int i; + + for (i = 0; i < nlimits; i++) { + if (limits[i].hl_subject <= 0 || limits[i].hl_subject > HRL_SUBJECT_MAX) + return (EINVAL); + if (limits[i].hl_per <= 0 || limits[i].hl_per > HRL_SUBJECT_MAX) + return (EINVAL); + if (limits[i].hl_object <= 0 || limits[i].hl_object > HRL_OBJECT_MAX) + return (EINVAL); + if (limits[i].hl_action <= 0 || limits[i].hl_action > HRL_ACTION_MAX) + return (EINVAL); + if (limits[i].hl_amount <= 0) + return (EINVAL); + } return (0); } @@ -57,7 +120,7 @@ { int error; size_t buflen; - struct hrl_limit **newlimits; + struct hrl_limit *newlimits; error = priv_check(td, PRIV_HRL_GET); if (error) @@ -74,9 +137,11 @@ * Removing all the limits? */ if (uap->nentries == 0) { + mtx_lock(&hrllock); free(limits, M_HRL); limits = NULL; nlimits = 0; + mtx_unlock(&hrllock); return (0); } @@ -92,12 +157,16 @@ if (error) goto out; + mtx_lock(&hrllock); + if (limits != NULL) free(limits, M_HRL); limits = newlimits; nlimits = uap->nentries; + mtx_unlock(&hrllock); + return (0); out: @@ -119,17 +188,48 @@ * XXX: Check for being in jail? */ - if (suword(uap->required, nlimits) != 0) - return (EINVAL); + mtx_lock(&hrllock); + + if (suword(uap->required, nlimits) != 0) { + error = EINVAL; + goto out; + } + + if (uap->nentries == 0 && uap->bufp == NULL) { + error = 0; + goto out; + } - if (uap->nentries == 0 && uap->bufp == NULL) - return (0); + if (uap->nentries < nlimits) { + error = EFBIG; + goto out; + } - if (uap->nentries < nlimits) - return (EFBIG); + if (nlimits == 0) { + error = 0; + goto out; + } buflen = sizeof(struct hrl_limit) * nlimits; error = copyout(limits, uap->bufp, buflen); +out: + mtx_unlock(&hrllock); + return (error); } + +static void +hrl_proc_exit(void *arg __unused, struct proc *p) +{ + /* + * XXX: Remove per-process limits here. + */ +} + +static void +hrl_init(void) +{ + mtx_init(&hrllock, "hrl lock", NULL, MTX_DEF); + EVENTHANDLER_REGISTER(process_exit, hrl_proc_exit, NULL, EVENTHANDLER_PRI_ANY); +} ==== //depot/projects/soc2009/trasz_limits/sys/kern/kern_resource.c#2 (text+ko) ==== @@ -43,6 +43,7 @@ #include <sys/systm.h> #include <sys/sysproto.h> #include <sys/file.h> +#include <sys/hrl.h> #include <sys/kernel.h> #include <sys/lock.h> #include <sys/malloc.h> @@ -642,6 +643,82 @@ callout_reset(&p->p_limco, hz, lim_cb, p); } +static void +hrl_handle_setrlimit(u_int which, struct rlimit *lim, struct thread *td) +{ + int object, subject, soft_action, hard_action; + id_t id; + + /* + * XXX: Locking. + */ + subject = HRL_SUBJECT_PROCESS; + id = td->td_proc->p_pid; + soft_action = HRL_ACTION_LOG; + hard_action = HRL_ACTION_DENY; + + switch (which) { + case RLIMIT_CPU: + object = HRL_OBJECT_CPUTIME; + soft_action = HRL_ACTION_SIGXCPU; + break; + case RLIMIT_FSIZE: + object = HRL_OBJECT_FILESIZE; + break; + case RLIMIT_DATA: + object = HRL_OBJECT_DATASIZE; + break; + case RLIMIT_STACK: + object = HRL_OBJECT_STACKSIZE; + soft_action = HRL_ACTION_SIGSEGV; + break; + case RLIMIT_CORE: + object = HRL_OBJECT_COREDUMPSIZE; + break; + case RLIMIT_RSS: + object = HRL_OBJECT_MEMORYUSE; + break; + case RLIMIT_MEMLOCK: + object = HRL_OBJECT_MEMORYLOCKED; + break; + case RLIMIT_NPROC: + object = HRL_OBJECT_MAXPROCESSES; + subject = HRL_SUBJECT_USER; + id = td->td_ucred->cr_uid; + break; + case RLIMIT_NOFILE: + object = HRL_OBJECT_OPENFILES; + soft_action = HRL_ACTION_SIGXFSZ; + break; + case RLIMIT_SBSIZE: + object = HRL_OBJECT_SBSIZE; + subject = HRL_SUBJECT_USER; + id = td->td_ucred->cr_uid; + break; + case RLIMIT_VMEM: + object = HRL_OBJECT_VMEMORYUSE; + break; + case RLIMIT_NPTS: + object = HRL_OBJECT_PTY; + subject = HRL_SUBJECT_USER; + id = td->td_ucred->cr_uid; + break; + default: + panic("hrl_handle_setrlimit: unknown limit"); + } + + if (lim->rlim_cur != RLIM_INFINITY) + hrl_adjust(subject, id, subject, object, soft_action, + lim->rlim_cur); + else + hrl_adjust(subject, id, subject, object, soft_action, 0); + if (lim->rlim_max != RLIM_INFINITY) + hrl_adjust(subject, id, subject, object, hard_action, + lim->rlim_max); + else + hrl_adjust(subject, id, subject, object, hard_action, 0); +} + int kern_setrlimit(td, which, limp) struct thread *td; @@ -763,6 +840,8 @@ } } + hrl_handle_setrlimit(which, alimp, td); + return (0); } ==== //depot/projects/soc2009/trasz_limits/sys/sys/hrl.h#3 (text+ko) ==== @@ -45,7 +45,6 @@ int64_t hl_amount; }; -#define HRL_SUBJECT_UNDEFINED 0x0000 #define HRL_SUBJECT_PROCESS 0x0001 #define HRL_SUBJECT_USER 0x0002 #define HRL_SUBJECT_GROUP 0x0003 @@ -57,7 +56,6 @@ * 'hl_per' takes the same flags as 'hl_subject'. */ -#define HRL_OBJECT_UNDEFINED 0x0000 #define HRL_OBJECT_CPUTIME 0x0001 #define HRL_OBJECT_FILESIZE 0x0002 #define HRL_OBJECT_DATASIZE 0x0003 @@ -72,27 +70,31 @@ #define HRL_OBJECT_PTY 0x000c #define HRL_OBJECT_MAX HRL_OBJECT_PTY -#define HRL_ACTION_UNDEFINED 0x0000 #define HRL_ACTION_DENY 0x0001 #define HRL_ACTION_DELAY 0x0002 #define HRL_ACTION_LOG 0x0003 #define HRL_ACTION_SIGHUP 0x0004 #define HRL_ACTION_SIGINT 0x0005 #define HRL_ACTION_SIGKILL 0x0006 -#define HRL_ACTION_SIGXCPU 0x0007 -#define HRL_ACTION_SIGXFSZ 0x0008 +#define HRL_ACTION_SIGSEGV 0x0007 +#define HRL_ACTION_SIGXCPU 0x0008 +#define HRL_ACTION_SIGXFSZ 0x0009 #define HRL_ACTION_MAX HRL_ACTION_SIGXFSZ #define HRL_MAX_LIMITS 128 -int hrl_alloc(int tag, int amount); -void hrl_free(int tag, int amount); +#ifdef _KERNEL + +int hrl_alloc(int object, uint64_t amount); +void hrl_free(int object, uint64_t amount); + +void hrl_adjust(int subject, id_t subject_id, int per, int object, int action, int64_t amount); -#ifndef _KERNEL +#else /* !_KERNEL */ __BEGIN_DECLS -int hrl_get(struct hrl_limit **bufp, int nentries, int *count); -int hrl_set(struct hrl_limit **bufp, int nentries); +int hrl_get(struct hrl_limit *bufp, int nentries, int *count); +int hrl_set(struct hrl_limit *bufp, int nentries); __END_DECLS #endif /* !_KERNEL */ ==== //depot/projects/soc2009/trasz_limits/usr.sbin/hrl/hrl.c#3 (text+ko) ==== @@ -30,21 +30,33 @@ #include <err.h> #include <stdio.h> #include <stdlib.h> +#include <pwd.h> +#include <grp.h> #include <sys/hrl.h> static void print_subject(int subject, id_t id) { + struct passwd *pwd; + struct group *grp; switch (subject) { case HRL_SUBJECT_PROCESS: printf("process:%u", (unsigned int)id); break; case HRL_SUBJECT_USER: - printf("user:%u", (unsigned int)id); + pwd = getpwuid(id); + if (pwd != NULL) + printf("user:%s", pwd->pw_name); + else + printf("user:%u", (unsigned int)id); break; case HRL_SUBJECT_GROUP: - printf("group:%u", (unsigned int)id); + grp = getgrgid(id); + if (grp != NULL) + printf("group:%s", grp->gr_name); + else + printf("group:%u", (unsigned int)id); break; case HRL_SUBJECT_LOGINCLASS: printf("class:%u", (unsigned int)id); @@ -127,6 +139,9 @@ case HRL_ACTION_SIGKILL: printf("sigkill"); break; + case HRL_ACTION_SIGSEGV: + printf("sigsegv"); + break; case HRL_ACTION_SIGXCPU: printf("sigxcpu"); break; @@ -168,7 +183,7 @@ main(int argc __unused, char **argv __unused) { int error, nentries, i; - struct hrl_limit **limits; + struct hrl_limit *limits; error = hrl_get(NULL, 0, &nentries); if (error) @@ -190,16 +205,16 @@ printf("Defined resource limits:\n"); for (i = 0; i < nentries; i++) { - print_subject(limits[i]->hl_subject, limits[i]->hl_subject_id); + print_subject(limits[i].hl_subject, limits[i].hl_subject_id); printf(":"); - print_object(limits[i]->hl_object); + print_object(limits[i].hl_object); printf(":"); - print_action(limits[i]->hl_action); + print_action(limits[i].hl_action); printf(":"); - printf("%jd", limits[i]->hl_amount); - if (limits[i]->hl_subject != limits[i]->hl_per) { + printf("%jd", limits[i].hl_amount); + if (limits[i].hl_subject != limits[i].hl_per) { printf("/"); - print_per(limits[i]->hl_per); + print_per(limits[i].hl_per); } printf("\n"); }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200905311801.n4VI1DKm016109>