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 &&