Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F115753905
D46472.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
5 KB
Referenced Files
None
Subscribers
None
D46472.diff
View Options
diff --git a/sys/fs/fifofs/fifo_vnops.c b/sys/fs/fifofs/fifo_vnops.c
--- a/sys/fs/fifofs/fifo_vnops.c
+++ b/sys/fs/fifofs/fifo_vnops.c
@@ -140,9 +140,7 @@
if (fp == NULL || (ap->a_mode & FEXEC) != 0)
return (EINVAL);
if ((fip = vp->v_fifoinfo) == NULL) {
- error = pipe_named_ctor(&fpipe, td);
- if (error != 0)
- return (error);
+ pipe_named_ctor(&fpipe, td);
fip = malloc(sizeof(*fip), M_VNODE, M_WAITOK | M_ZERO);
fip->fi_pipe = fpipe;
fpipe->pipe_wgen = 0;
diff --git a/sys/kern/sys_pipe.c b/sys/kern/sys_pipe.c
--- a/sys/kern/sys_pipe.c
+++ b/sys/kern/sys_pipe.c
@@ -114,6 +114,7 @@
#include <sys/uio.h>
#include <sys/user.h>
#include <sys/event.h>
+#include <sys/jail.h>
#include <security/mac/mac_framework.h>
@@ -223,8 +224,8 @@
static void pipeinit(void *dummy __unused);
static void pipeclose(struct pipe *cpipe);
static void pipe_free_kmem(struct pipe *cpipe);
-static int pipe_create(struct pipe *pipe, bool backing);
-static int pipe_paircreate(struct thread *td, struct pipepair **p_pp);
+static void pipe_create(struct pipe *pipe, bool backing);
+static void pipe_paircreate(struct thread *td, struct pipepair **p_pp);
static __inline int pipelock(struct pipe *cpipe, bool catch);
static __inline void pipeunlock(struct pipe *cpipe);
static void pipe_timestamp(struct timespec *tsp);
@@ -356,12 +357,11 @@
mtx_destroy(&pp->pp_mtx);
}
-static int
+static void
pipe_paircreate(struct thread *td, struct pipepair **p_pp)
{
struct pipepair *pp;
struct pipe *rpipe, *wpipe;
- int error;
*p_pp = pp = uma_zalloc(pipe_zone, M_WAITOK);
#ifdef MAC
@@ -383,50 +383,21 @@
* Only the forward direction pipe is backed by big buffer by
* default.
*/
- error = pipe_create(rpipe, true);
- if (error != 0)
- goto fail;
- error = pipe_create(wpipe, false);
- if (error != 0) {
- /*
- * This cleanup leaves the pipe inode number for rpipe
- * still allocated, but never used. We do not free
- * inode numbers for opened pipes, which is required
- * for correctness because numbers must be unique.
- * But also it avoids any memory use by the unr
- * allocator, so stashing away the transient inode
- * number is reasonable.
- */
- pipe_free_kmem(rpipe);
- goto fail;
- }
+ pipe_create(rpipe, true);
+ pipe_create(wpipe, false);
rpipe->pipe_state |= PIPE_DIRECTOK;
wpipe->pipe_state |= PIPE_DIRECTOK;
- return (0);
-
-fail:
- knlist_destroy(&rpipe->pipe_sel.si_note);
- knlist_destroy(&wpipe->pipe_sel.si_note);
-#ifdef MAC
- mac_pipe_destroy(pp);
-#endif
- uma_zfree(pipe_zone, pp);
- return (error);
}
-int
+void
pipe_named_ctor(struct pipe **ppipe, struct thread *td)
{
struct pipepair *pp;
- int error;
- error = pipe_paircreate(td, &pp);
- if (error != 0)
- return (error);
+ pipe_paircreate(td, &pp);
pp->pp_rpipe.pipe_type |= PIPE_TYPE_NAMED;
*ppipe = &pp->pp_rpipe;
- return (0);
}
void
@@ -470,9 +441,7 @@
struct pipepair *pp;
int fd, fflags, error;
- error = pipe_paircreate(td, &pp);
- if (error != 0)
- return (error);
+ pipe_paircreate(td, &pp);
rpipe = &pp->pp_rpipe;
wpipe = &pp->pp_wpipe;
error = falloc_caps(td, &rf, &fd, flags, fcaps1);
@@ -549,6 +518,20 @@
return (error);
}
+static void
+pipekva_enomem(void)
+{
+ static int curfail = 0;
+ static struct timeval lastfail;
+
+ pipeallocfail++;
+ if (!ppsratecheck(&lastfail, &curfail, 1))
+ return;
+ printf("pid %d (%s), jid %d, uid %d: kern.ipc.maxpipekva exceeded\n",
+ curproc->p_pid, curproc->p_comm, curproc->p_ucred->cr_prison->pr_id,
+ curproc->p_ucred->cr_uid);
+}
+
/*
* Allocate kva for pipe circular buffer, the space is pageable
* This routine will 'realloc' the size of a pipe safely, if it fails
@@ -560,8 +543,6 @@
{
caddr_t buffer;
int error, cnt, firstseg;
- static int curfail = 0;
- static struct timeval lastfail;
KASSERT(!mtx_owned(PIPE_MTX(cpipe)), ("pipespace: pipe mutex locked"));
KASSERT(!(cpipe->pipe_state & PIPE_DIRECTW),
@@ -584,9 +565,7 @@
goto retry;
}
if (cpipe->pipe_buffer.buffer == NULL) {
- pipeallocfail++;
- if (ppsratecheck(&lastfail, &curfail, 1))
- printf("kern.ipc.maxpipekva exceeded; see tuning(7)\n");
+ pipekva_enomem();
} else {
piperesizefail++;
}
@@ -694,16 +673,21 @@
* Initialize and allocate VM and memory for pipe. The structure
* will start out zero'd from the ctor, so we just manage the kmem.
*/
-static int
+static void
pipe_create(struct pipe *pipe, bool large_backing)
{
- int error;
- error = pipespace_new(pipe, !large_backing || amountpipekva >
+ /*
+ * Note that pipespace_new() can fail if pipe map is exhausted
+ * (as a result of too many pipes created), but we ignore the
+ * error here as it is not fatal and could be provoked by
+ * unprivileged users. The pipe will be unused in absolute majority
+ * of cases anyways, so it is not a big deal. If the condition
+ * persists, the write() will re-try allocation and report it then.
+ */
+ (void)pipespace_new(pipe, !large_backing || amountpipekva >
maxpipekva / 2 ? SMALL_PIPE_SIZE : PIPE_SIZE);
- if (error == 0)
- pipe->pipe_ino = alloc_unr64(&pipeino_unr);
- return (error);
+ pipe->pipe_ino = alloc_unr64(&pipeino_unr);
}
/* ARGSUSED */
@@ -1159,7 +1143,17 @@
pipespace(wpipe, desiredsize);
PIPE_LOCK(wpipe);
}
- MPASS(wpipe->pipe_buffer.size != 0);
+ if (wpipe->pipe_buffer.size == 0) {
+ /*
+ * This can only happen for reverse direction use of pipes
+ * in a complete OOM situation.
+ */
+ error = ENOMEM;
+ --wpipe->pipe_busy;
+ pipeunlock(wpipe);
+ PIPE_UNLOCK(wpipe);
+ return (error);
+ }
orig_resid = uio->uio_resid;
diff --git a/sys/sys/pipe.h b/sys/sys/pipe.h
--- a/sys/sys/pipe.h
+++ b/sys/sys/pipe.h
@@ -145,7 +145,7 @@
#ifdef _KERNEL
void pipe_dtor(struct pipe *dpipe);
-int pipe_named_ctor(struct pipe **ppipe, struct thread *td);
+void pipe_named_ctor(struct pipe **ppipe, struct thread *td);
void pipeselwakeup(struct pipe *cpipe);
#endif
#endif /* !_SYS_PIPE_H_ */
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Tue, Apr 29, 4:20 AM (3 h, 31 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
17836993
Default Alt Text
D46472.diff (5 KB)
Attached To
Mode
D46472: Make pipe(2) & Co bullet-proof again (PR 272332)
Attached
Detach File
Event Timeline
Log In to Comment