Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/kern Avoid leaking a mutex_obj when pipe_create() fails ...



details:   https://anonhg.NetBSD.org/src/rev/2b53cbc26eef
branches:  trunk
changeset: 749844:2b53cbc26eef
user:      dsl <dsl%NetBSD.org@localhost>
date:      Thu Dec 10 20:55:17 2009 +0000

description:
Avoid leaking a mutex_obj when pipe_create() fails for the read pipe.
Remove the unused argument from pipeclose().

diffstat:

 sys/kern/sys_pipe.c |  44 +++++++++++++++++++++++---------------------
 1 files changed, 23 insertions(+), 21 deletions(-)

diffs (139 lines):

diff -r 46e19dfc81e0 -r 2b53cbc26eef sys/kern/sys_pipe.c
--- a/sys/kern/sys_pipe.c       Thu Dec 10 20:20:59 2009 +0000
+++ b/sys/kern/sys_pipe.c       Thu Dec 10 20:55:17 2009 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: sys_pipe.c,v 1.121 2009/12/09 21:32:59 dsl Exp $       */
+/*     $NetBSD: sys_pipe.c,v 1.122 2009/12/10 20:55:17 dsl Exp $       */
 
 /*-
  * Copyright (c) 2003, 2007, 2008, 2009 The NetBSD Foundation, Inc.
@@ -68,7 +68,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: sys_pipe.c,v 1.121 2009/12/09 21:32:59 dsl Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sys_pipe.c,v 1.122 2009/12/10 20:55:17 dsl Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -157,9 +157,9 @@
  */
 static u_int   amountpipekva = 0;
 
-static void    pipeclose(file_t *, struct pipe *);
+static void    pipeclose(struct pipe *);
 static void    pipe_free_kmem(struct pipe *);
-static int     pipe_create(struct pipe **, pool_cache_t, kmutex_t *);
+static int     pipe_create(struct pipe **, pool_cache_t);
 static int     pipelock(struct pipe *, int);
 static inline void pipeunlock(struct pipe *);
 static void    pipeselwakeup(struct pipe *, struct pipe *, int);
@@ -247,22 +247,19 @@
 {
        struct pipe *rpipe, *wpipe;
        file_t *rf, *wf;
-       kmutex_t *mutex;
        int fd, error;
        proc_t *p;
 
        p = curproc;
        rpipe = wpipe = NULL;
-       mutex = mutex_obj_alloc(MUTEX_DEFAULT, IPL_NONE);
-       if (mutex == NULL)
-               return (ENOMEM);
-       mutex_obj_hold(mutex);
-       if (pipe_create(&rpipe, pipe_rd_cache, mutex) ||
-           pipe_create(&wpipe, pipe_wr_cache, mutex)) {
-               pipeclose(NULL, rpipe);
-               pipeclose(NULL, wpipe);
-               return (ENFILE);
+       if (pipe_create(&rpipe, pipe_rd_cache) ||
+           pipe_create(&wpipe, pipe_wr_cache)) {
+               error = ENOMEM;
+               goto free2;
        }
+       rpipe->pipe_lock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_NONE);
+       wpipe->pipe_lock = rpipe->pipe_lock;
+       mutex_obj_hold(wpipe->pipe_lock);
 
        error = fd_allocfile(&rf, &fd);
        if (error)
@@ -291,8 +288,8 @@
 free3:
        fd_abort(p, rf, (int)retval[0]);
 free2:
-       pipeclose(NULL, wpipe);
-       pipeclose(NULL, rpipe);
+       pipeclose(wpipe);
+       pipeclose(rpipe);
 
        return (error);
 }
@@ -336,7 +333,7 @@
  * Initialize and allocate VM and memory for pipe.
  */
 static int
-pipe_create(struct pipe **pipep, pool_cache_t cache, kmutex_t *mutex)
+pipe_create(struct pipe **pipep, pool_cache_t cache)
 {
        struct pipe *pipe;
        int error;
@@ -347,7 +344,7 @@
        error = 0;
        getnanotime(&pipe->pipe_btime);
        pipe->pipe_atime = pipe->pipe_mtime = pipe->pipe_btime;
-       pipe->pipe_lock = mutex;
+       pipe->pipe_lock = NULL;
        if (cache == pipe_rd_cache) {
                error = pipespace(pipe, PIPE_SIZE);
        } else {
@@ -1202,7 +1199,7 @@
        struct pipe *pipe = fp->f_data;
 
        fp->f_data = NULL;
-       pipeclose(fp, pipe);
+       pipeclose(pipe);
        return (0);
 }
 
@@ -1238,7 +1235,7 @@
  * Shutdown the pipe.
  */
 static void
-pipeclose(file_t *fp, struct pipe *pipe)
+pipeclose(struct pipe *pipe)
 {
        kmutex_t *lock;
        struct pipe *ppipe;
@@ -1252,6 +1249,10 @@
        KASSERT(cv_is_valid(&pipe->pipe_lkcv));
 
        lock = pipe->pipe_lock;
+       if (lock == NULL)
+               /* Must have failed during create */
+               goto free_resources;
+
        mutex_enter(lock);
        pipeselwakeup(pipe, pipe, POLL_HUP);
 
@@ -1286,10 +1287,12 @@
 
        KASSERT((pipe->pipe_state & PIPE_LOCKFL) == 0);
        mutex_exit(lock);
+       mutex_obj_free(lock);
 
        /*
         * Free resources.
         */
+    free_resources:
        pipe->pipe_pgid = 0;
        pipe->pipe_state = PIPE_SIGNALR;
        pipe_free_kmem(pipe);
@@ -1298,7 +1301,6 @@
        } else {
                pool_cache_put(pipe_wr_cache, pipe);
        }
-       mutex_obj_free(lock);
 }
 
 static void



Home | Main Index | Thread Index | Old Index