Index: sys/kern/kern_rctl.c =================================================================== --- sys/kern/kern_rctl.c +++ sys/kern/kern_rctl.c @@ -72,7 +72,6 @@ #define HRF_DONT_ACCUMULATE 2 /* Default buffer size for rctl_get_rules(2). */ -#define RCTL_DEFAULT_BUFSIZE 4096 #define RCTL_MAX_INBUFLEN 4096 #define RCTL_LOG_BUFSIZE 128 @@ -1435,7 +1434,7 @@ sys_rctl_get_rules(struct thread *td, struct rctl_get_rules_args *uap) { int error; - size_t bufsize = RCTL_DEFAULT_BUFSIZE; + size_t bufsize; char *inputstr, *buf; struct sbuf *sb; struct rctl_rule *filter; @@ -1461,12 +1460,11 @@ return (error); } -again: + bufsize = uap->outbuflen; buf = malloc(bufsize, M_RCTL, M_WAITOK); sb = sbuf_new(NULL, buf, bufsize, SBUF_FIXEDLEN); KASSERT(sb != NULL, ("sbuf_new failed")); - sx_assert(&allproc_lock, SA_LOCKED); FOREACH_PROC_IN_SYSTEM(p) { rw_rlock(&rctl_lock); LIST_FOREACH(link, &p->p_racct->r_rule_links, rrl_next) { @@ -1489,10 +1487,10 @@ ui_racct_foreach(rctl_get_rules_callback, filter, sb); prison_racct_foreach(rctl_get_rules_callback, filter, sb); if (sbuf_error(sb) == ENOMEM) { + sx_sunlock(&allproc_lock); sbuf_delete(sb); free(buf, M_RCTL); - bufsize *= 4; - goto again; + return (ERANGE); } /* @@ -1502,7 +1500,6 @@ sbuf_setpos(sb, sbuf_len(sb) - 1); error = rctl_write_outbuf(sb, uap->outbufp, uap->outbuflen); - rctl_rule_release(filter); sx_sunlock(&allproc_lock); free(buf, M_RCTL); @@ -1513,7 +1510,7 @@ sys_rctl_get_limits(struct thread *td, struct rctl_get_limits_args *uap) { int error; - size_t bufsize = RCTL_DEFAULT_BUFSIZE; + size_t bufsize; char *inputstr, *buf; struct sbuf *sb; struct rctl_rule *filter; @@ -1554,7 +1551,7 @@ return (EINVAL); } -again: + bufsize = uap->outbuflen; buf = malloc(bufsize, M_RCTL, M_WAITOK); sb = sbuf_new(NULL, buf, bufsize, SBUF_FIXEDLEN); KASSERT(sb != NULL, ("sbuf_new failed")); @@ -1567,10 +1564,10 @@ } rw_runlock(&rctl_lock); if (sbuf_error(sb) == ENOMEM) { + sx_sunlock(&allproc_lock); sbuf_delete(sb); free(buf, M_RCTL); - bufsize *= 4; - goto again; + return (ERANGE); } /* Index: usr.bin/rctl/rctl.c =================================================================== --- usr.bin/rctl/rctl.c +++ usr.bin/rctl/rctl.c @@ -48,7 +48,7 @@ #include #include -#define RCTL_DEFAULT_BUFSIZE 4096 +#define RCTL_DEFAULT_BUFSIZE 128 * 1024 static id_t parse_user(const char *s)