kernel: add RLIMIT_PIPEBUF

(cherry picked from commit 3458bbd397783f3bb62713c54ae87f19eeb98dc0)
This commit is contained in:
Konstantin Belousov 2024-09-10 06:57:58 +03:00
parent 4cb8ec6c6f
commit b7eecc86c3
5 changed files with 28 additions and 1 deletions

View file

@ -1610,3 +1610,10 @@ chgumtxcnt(struct uidinfo *uip, int diff, rlim_t max)
return (chglimit(uip, &uip->ui_umtxcnt, diff, max, "umtxcnt"));
}
int
chgpipecnt(struct uidinfo *uip, int diff, rlim_t max)
{
return (chglimit(uip, &uip->ui_pipecnt, diff, max, "pipecnt"));
}

View file

@ -376,6 +376,7 @@ pipe_paircreate(struct thread *td, struct pipepair **p_pp)
#endif
rpipe = &pp->pp_rpipe;
wpipe = &pp->pp_wpipe;
pp->pp_owner = crhold(td->td_ucred);
knlist_init_mtx(&rpipe->pipe_sel.si_note, PIPE_MTX(rpipe));
knlist_init_mtx(&wpipe->pipe_sel.si_note, PIPE_MTX(wpipe));
@ -409,6 +410,7 @@ pipe_paircreate(struct thread *td, struct pipepair **p_pp)
fail:
knlist_destroy(&rpipe->pipe_sel.si_note);
knlist_destroy(&wpipe->pipe_sel.si_note);
crfree(pp->pp_owner);
#ifdef MAC
mac_pipe_destroy(pp);
#endif
@ -575,9 +577,20 @@ retry:
size = round_page(size);
buffer = (caddr_t) vm_map_min(pipe_map);
if (!chgpipecnt(cpipe->pipe_pair->pp_owner->cr_ruidinfo,
size, lim_cur(curthread, RLIMIT_PIPEBUF))) {
if (cpipe->pipe_buffer.buffer == NULL &&
size > SMALL_PIPE_SIZE) {
size = SMALL_PIPE_SIZE;
goto retry;
}
return (ENOMEM);
}
error = vm_map_find(pipe_map, NULL, 0, (vm_offset_t *)&buffer, size, 0,
VMFS_ANY_SPACE, VM_PROT_RW, VM_PROT_RW, 0);
if (error != KERN_SUCCESS) {
chgpipecnt(cpipe->pipe_pair->pp_owner->cr_ruidinfo, -size, 0);
if (cpipe->pipe_buffer.buffer == NULL &&
size > SMALL_PIPE_SIZE) {
size = SMALL_PIPE_SIZE;
@ -1646,6 +1659,8 @@ pipe_free_kmem(struct pipe *cpipe)
if (cpipe->pipe_buffer.buffer != NULL) {
atomic_subtract_long(&amountpipekva, cpipe->pipe_buffer.size);
chgpipecnt(cpipe->pipe_pair->pp_owner->cr_uidinfo,
-cpipe->pipe_buffer.size, 0);
vm_map_remove(pipe_map,
(vm_offset_t)cpipe->pipe_buffer.buffer,
(vm_offset_t)cpipe->pipe_buffer.buffer + cpipe->pipe_buffer.size);
@ -1732,6 +1747,7 @@ pipeclose(struct pipe *cpipe)
*/
if (ppipe->pipe_present == PIPE_FINALIZED) {
PIPE_UNLOCK(cpipe);
crfree(cpipe->pipe_pair->pp_owner);
#ifdef MAC
mac_pipe_destroy(pp);
#endif

View file

@ -136,6 +136,7 @@ struct pipepair {
struct pipe pp_wpipe;
struct mtx pp_mtx;
struct label *pp_label;
struct ucred *pp_owner; /* to dec pipe usage count */
};
#define PIPE_MTX(pipe) (&(pipe)->pipe_pair->pp_mtx)

View file

@ -116,8 +116,9 @@ struct __wrusage {
#define RLIMIT_SWAP 12 /* swap used */
#define RLIMIT_KQUEUES 13 /* kqueues allocated */
#define RLIMIT_UMTXP 14 /* process-shared umtx */
#define RLIMIT_PIPEBUF 15 /* pipes/fifos buffers */
#define RLIM_NLIMITS 15 /* number of resource limits */
#define RLIM_NLIMITS 16 /* number of resource limits */
#define RLIM_INFINITY ((rlim_t)(((__uint64_t)1 << 63) - 1))
#define RLIM_SAVED_MAX RLIM_INFINITY

View file

@ -123,6 +123,7 @@ struct uidinfo {
long ui_ptscnt; /* (b) number of pseudo-terminals */
long ui_kqcnt; /* (b) number of kqueues */
long ui_umtxcnt; /* (b) number of shared umtxs */
long ui_pipecnt; /* (b) consumption of pipe buffers */
uid_t ui_uid; /* (a) uid */
u_int ui_ref; /* (b) reference count */
#ifdef RACCT
@ -144,6 +145,7 @@ int chgsbsize(struct uidinfo *uip, u_int *hiwat, u_int to,
rlim_t maxval);
int chgptscnt(struct uidinfo *uip, int diff, rlim_t maxval);
int chgumtxcnt(struct uidinfo *uip, int diff, rlim_t maxval);
int chgpipecnt(struct uidinfo *uip, int diff, rlim_t max);
int kern_proc_setrlimit(struct thread *td, struct proc *p, u_int which,
struct rlimit *limp);
struct plimit