git: d532d9926ee7 - stable/14 - pipes: reserve configured percentage of buffers zone to superuser
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Sat, 05 Oct 2024 07:11:16 UTC
The branch stable/14 has been updated by kib: URL: https://cgit.FreeBSD.org/src/commit/?id=d532d9926ee74a05b03db9064196b3831c082bee commit d532d9926ee74a05b03db9064196b3831c082bee Author: Konstantin Belousov <kib@FreeBSD.org> AuthorDate: 2024-09-15 06:57:34 +0000 Commit: Konstantin Belousov <kib@FreeBSD.org> CommitDate: 2024-10-05 07:08:55 +0000 pipes: reserve configured percentage of buffers zone to superuser (cherry picked from commit 7672cbef2c1e1267e42bb3aad6a6da9380f4347f) --- sys/kern/sys_pipe.c | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/sys/kern/sys_pipe.c b/sys/kern/sys_pipe.c index dc8b9ca2c9af..2e5eafee9fa6 100644 --- a/sys/kern/sys_pipe.c +++ b/sys/kern/sys_pipe.c @@ -104,6 +104,7 @@ #include <sys/stat.h> #include <sys/malloc.h> #include <sys/poll.h> +#include <sys/priv.h> #include <sys/selinfo.h> #include <sys/signalvar.h> #include <sys/syscallsubr.h> @@ -207,6 +208,7 @@ static int pipeallocfail; static int piperesizefail; static int piperesizeallowed = 1; static long pipe_mindirect = PIPE_MINDIRECT; +static int pipebuf_reserv = 2; SYSCTL_LONG(_kern_ipc, OID_AUTO, maxpipekva, CTLFLAG_RDTUN | CTLFLAG_NOFETCH, &maxpipekva, 0, "Pipe KVA limit"); @@ -220,6 +222,9 @@ SYSCTL_INT(_kern_ipc, OID_AUTO, piperesizefail, CTLFLAG_RD, &piperesizefail, 0, "Pipe resize failures"); SYSCTL_INT(_kern_ipc, OID_AUTO, piperesizeallowed, CTLFLAG_RW, &piperesizeallowed, 0, "Pipe resizing allowed"); +SYSCTL_INT(_kern_ipc, OID_AUTO, pipebuf_reserv, CTLFLAG_RW, + &pipebuf_reserv, 0, + "Superuser-reserved percentage of the pipe buffers space"); static void pipeinit(void *dummy __unused); static void pipeclose(struct pipe *cpipe); @@ -587,8 +592,22 @@ 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); + vm_map_lock(pipe_map); + if (priv_check(curthread, PRIV_PIPEBUF) != 0 && + (vm_map_max(pipe_map) - vm_map_min(pipe_map)) * + (100 - pipebuf_reserv) / 100 < pipe_map->size + size) { + vm_map_unlock(pipe_map); + if (cpipe->pipe_buffer.buffer == NULL && + size > SMALL_PIPE_SIZE) { + size = SMALL_PIPE_SIZE; + pipefragretry++; + goto retry; + } + return (ENOMEM); + } + error = vm_map_find_locked(pipe_map, NULL, 0, (vm_offset_t *)&buffer, + size, 0, VMFS_ANY_SPACE, VM_PROT_RW, VM_PROT_RW, 0); + vm_map_unlock(pipe_map); if (error != KERN_SUCCESS) { chgpipecnt(cpipe->pipe_pair->pp_owner->cr_ruidinfo, -size, 0); if (cpipe->pipe_buffer.buffer == NULL &&