Source-Changes-HG archive

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

[src/trunk]: src Limit the amount of kernel memory a posix_spawn syscall can ...



details:   https://anonhg.NetBSD.org/src/rev/5bb602a70b05
branches:  trunk
changeset: 793291:5bb602a70b05
user:      martin <martin%NetBSD.org@localhost>
date:      Sun Feb 02 14:48:57 2014 +0000

description:
Limit the amount of kernel memory a posix_spawn syscall can use (for handling
the file action list) by limiting the maximum number of file actions to
twice the current file descriptor limit.
Fix a few bugs in the support functions and document the new limit.
>From Maxime Villard.

diffstat:

 lib/libc/gen/posix_spawn.3                      |  13 ++++-
 lib/libc/gen/posix_spawn_file_actions_addopen.3 |   6 +-
 lib/libc/gen/posix_spawn_file_actions_init.3    |   6 +-
 lib/libc/gen/posix_spawn_fileactions.c          |  67 +++++++++++++-----------
 sys/compat/netbsd32/netbsd32_execve.c           |  17 ++++-
 sys/kern/kern_exec.c                            |  18 +++++-
 6 files changed, 86 insertions(+), 41 deletions(-)

diffs (truncated from 341 to 300 lines):

diff -r 3311a0e8fe49 -r 5bb602a70b05 lib/libc/gen/posix_spawn.3
--- a/lib/libc/gen/posix_spawn.3        Sun Feb 02 08:34:39 2014 +0000
+++ b/lib/libc/gen/posix_spawn.3        Sun Feb 02 14:48:57 2014 +0000
@@ -1,4 +1,4 @@
-.\" $NetBSD: posix_spawn.3,v 1.4 2013/07/20 21:39:57 wiz Exp $
+.\" $NetBSD: posix_spawn.3,v 1.5 2014/02/02 14:48:57 martin Exp $
 .\"
 .\" Copyright (c) 2008 Ed Schouten <ed%FreeBSD.org@localhost>
 .\" All rights reserved.
@@ -182,6 +182,12 @@
 is closed.
 .El
 .Pp
+The maximum number of
+.Fa file_actions
+objects is limited to the
+.Dv RLIMIT_NOFILE
+rlimit times 2.
+.Pp
 The
 .Vt posix_spawnattr_t
 spawn attributes object type is defined in
@@ -420,6 +426,11 @@
 .Fn dup2 ,
 in addition to those described by
 .Fn open .
+Finally, if the number of
+.Fa file_actions
+objects exceeds the allowed limit,
+.Er EINVAL
+is returned.
 .El
 .Sh SEE ALSO
 .Xr close 2 ,
diff -r 3311a0e8fe49 -r 5bb602a70b05 lib/libc/gen/posix_spawn_file_actions_addopen.3
--- a/lib/libc/gen/posix_spawn_file_actions_addopen.3   Sun Feb 02 08:34:39 2014 +0000
+++ b/lib/libc/gen/posix_spawn_file_actions_addopen.3   Sun Feb 02 14:48:57 2014 +0000
@@ -1,4 +1,4 @@
-.\" $NetBSD: posix_spawn_file_actions_addopen.3,v 1.3 2013/07/20 21:39:57 wiz Exp $
+.\" $NetBSD: posix_spawn_file_actions_addopen.3,v 1.4 2014/02/02 14:48:57 martin Exp $
 .\"
 .\" Copyright (c) 2008 Ed Schouten <ed%FreeBSD.org@localhost>
 .\" All rights reserved.
@@ -149,6 +149,10 @@
 .Bl -tag -width Er
 .It Bq Er EINVAL
 The value specified by
+.Fa file_actions
+is invalid.
+.It Bq Er EBADF
+The value specified by
 .Fa fildes
 or
 .Fa newfildes
diff -r 3311a0e8fe49 -r 5bb602a70b05 lib/libc/gen/posix_spawn_file_actions_init.3
--- a/lib/libc/gen/posix_spawn_file_actions_init.3      Sun Feb 02 08:34:39 2014 +0000
+++ b/lib/libc/gen/posix_spawn_file_actions_init.3      Sun Feb 02 14:48:57 2014 +0000
@@ -1,4 +1,4 @@
-.\" $NetBSD: posix_spawn_file_actions_init.3,v 1.3 2013/07/20 21:39:57 wiz Exp $
+.\" $NetBSD: posix_spawn_file_actions_init.3,v 1.4 2014/02/02 14:48:57 martin Exp $
 .\"
 .\" Copyright (c) 2008 Ed Schouten <ed%FreeBSD.org@localhost>
 .\" All rights reserved.
@@ -81,6 +81,10 @@
 .Bl -tag -width Er
 .It Bq Er ENOMEM
 Insufficient memory exists to initialize the spawn file actions object.
+.It Bq Er EINVAL
+The value specified by
+.Fa file_actions
+is invalid.
 .El
 .Sh SEE ALSO
 .Xr posix_spawn 3 ,
diff -r 3311a0e8fe49 -r 5bb602a70b05 lib/libc/gen/posix_spawn_fileactions.c
--- a/lib/libc/gen/posix_spawn_fileactions.c    Sun Feb 02 08:34:39 2014 +0000
+++ b/lib/libc/gen/posix_spawn_fileactions.c    Sun Feb 02 14:48:57 2014 +0000
@@ -25,7 +25,7 @@
  */
 
 #include <sys/cdefs.h>
-__RCSID("$NetBSD: posix_spawn_fileactions.c,v 1.2 2012/04/08 11:27:44 martin Exp $");
+__RCSID("$NetBSD: posix_spawn_fileactions.c,v 1.3 2014/02/02 14:48:57 martin Exp $");
 
 #include "namespace.h"
 
@@ -48,11 +48,11 @@
 posix_spawn_file_actions_init(posix_spawn_file_actions_t *fa)
 {
        if (fa == NULL)
-               return (-1);
+               return (EINVAL);
 
        fa->fae = malloc(MIN_SIZE * sizeof(struct posix_spawn_file_actions_entry));
        if (fa->fae == NULL)
-               return (-1);
+               return (ENOMEM);
        fa->size = MIN_SIZE;
        fa->len = 0;
 
@@ -65,7 +65,7 @@
        unsigned int i;
 
        if (fa == NULL)
-               return (-1);
+               return (EINVAL);
 
        for (i = 0; i < fa->len; i++) {
                if (fa->fae[i].fae_action == FAE_OPEN)
@@ -77,48 +77,53 @@
 }
 
 static int
-posix_spawn_file_actions_getentry(posix_spawn_file_actions_t *fa)
+posix_spawn_file_actions_getentry(posix_spawn_file_actions_t *fa,
+    unsigned int *i)
 {
+       posix_spawn_file_actions_entry_t *fae;
+
        if (fa == NULL)
-               return -1;
+               return (EINVAL);
 
        if (fa->len < fa->size)
-               return fa->len;
-       
-       fa->fae = realloc(fa->fae, (fa->size + MIN_SIZE) * 
-                       sizeof(struct posix_spawn_file_actions_entry));
+               goto out;
 
-       if (fa->fae == NULL)
-               return -1;
+       fae = realloc(fa->fae, (fa->size + MIN_SIZE) * sizeof(*fa->fae));
+       if (fae == NULL)
+               return (ENOMEM);
 
+       fa->fae = fae;
        fa->size += MIN_SIZE;
 
-       return fa->len;
+out:
+       *i = fa->len;
+       return (0);
 }
 
 int
 posix_spawn_file_actions_addopen(posix_spawn_file_actions_t * __restrict fa,
     int fildes, const char * __restrict path, int oflag, mode_t mode)
 {
-       int i, error;
+       char *faepath;
+       unsigned int i;
+       int error;
 
        if (fildes < 0)
                return (EBADF);
 
-       i = posix_spawn_file_actions_getentry(fa);
-       if (i < 0)
+       error = posix_spawn_file_actions_getentry(fa, &i);
+       if (error)
+               return (error);
+
+       faepath = strdup(path);
+       if (faepath == NULL)
                return (ENOMEM);
 
        fa->fae[i].fae_action = FAE_OPEN;
-       fa->fae[i].fae_path = strdup(path);
-       if (fa->fae[i].fae_path == NULL) {
-               error = errno;
-               return (error);
-       }
+       fa->fae[i].fae_path = faepath;
        fa->fae[i].fae_fildes = fildes;
        fa->fae[i].fae_oflag = oflag;
        fa->fae[i].fae_mode = mode;
-       
        fa->len++;
 
        return (0);
@@ -128,14 +133,15 @@
 posix_spawn_file_actions_adddup2(posix_spawn_file_actions_t *fa,
     int fildes, int newfildes)
 {
-       int i;
+       unsigned int i;
+       int error;
 
        if (fildes < 0 || newfildes < 0)
                return (EBADF);
 
-       i = posix_spawn_file_actions_getentry(fa);
-       if (i < 0)
-               return (ENOMEM);
+       error = posix_spawn_file_actions_getentry(fa, &i);
+       if (error)
+               return (error);
 
        fa->fae[i].fae_action = FAE_DUP2;
        fa->fae[i].fae_fildes = fildes;
@@ -149,14 +155,15 @@
 posix_spawn_file_actions_addclose(posix_spawn_file_actions_t *fa,
     int fildes)
 {
-       int i;
+       unsigned int i;
+       int error;
 
        if (fildes < 0)
                return (EBADF);
 
-       i = posix_spawn_file_actions_getentry(fa);
-       if (i < 0)
-               return (ENOMEM);
+       error = posix_spawn_file_actions_getentry(fa, &i);
+       if (error)
+               return (error);
 
        fa->fae[i].fae_action = FAE_CLOSE;
        fa->fae[i].fae_fildes = fildes;
diff -r 3311a0e8fe49 -r 5bb602a70b05 sys/compat/netbsd32/netbsd32_execve.c
--- a/sys/compat/netbsd32/netbsd32_execve.c     Sun Feb 02 08:34:39 2014 +0000
+++ b/sys/compat/netbsd32/netbsd32_execve.c     Sun Feb 02 14:48:57 2014 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: netbsd32_execve.c,v 1.37 2013/01/15 17:14:11 hannken Exp $     */
+/*     $NetBSD: netbsd32_execve.c,v 1.38 2014/02/02 14:48:57 martin Exp $      */
 
 /*
  * Copyright (c) 1998, 2001 Matthew R. Green
@@ -28,7 +28,7 @@
 
 #include <sys/cdefs.h>
 
-__KERNEL_RCSID(0, "$NetBSD: netbsd32_execve.c,v 1.37 2013/01/15 17:14:11 hannken Exp $");
+__KERNEL_RCSID(0, "$NetBSD: netbsd32_execve.c,v 1.38 2014/02/02 14:48:57 martin Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -97,7 +97,7 @@
 
 static int
 netbsd32_posix_spawn_fa_alloc(struct posix_spawn_file_actions **fap,
-    const struct netbsd32_posix_spawn_file_actions *ufa)
+    const struct netbsd32_posix_spawn_file_actions *ufa, rlim_t lim)
 {
        struct posix_spawn_file_actions *fa;
        struct netbsd32_posix_spawn_file_actions fa32;
@@ -117,6 +117,11 @@
        fa = kmem_alloc(sizeof(*fa), KM_SLEEP);
        fa->len = fa->size = fa32.len;
 
+       if (fa->len > lim) {
+               kmem_free(fa, sizeof(*fa));
+               return EINVAL;
+       }
+
        fal = fa->len * sizeof(*fae);
        fal32 = fa->len * sizeof(*fae32);
 
@@ -179,6 +184,8 @@
        struct posix_spawnattr *sa = NULL;
        pid_t pid;
        bool child_ok = false;
+       rlim_t max_fileactions;
+       proc_t *p = l->l_proc;
 
        error = check_posix_spawn(l);
        if (error) {
@@ -188,8 +195,10 @@
 
        /* copy in file_actions struct */
        if (SCARG_P32(uap, file_actions) != NULL) {
+               max_fileactions = 2 * min(p->p_rlimit[RLIMIT_NOFILE].rlim_cur,
+                   maxfiles);
                error = netbsd32_posix_spawn_fa_alloc(&fa,
-                   SCARG_P32(uap, file_actions));
+                   SCARG_P32(uap, file_actions), max_fileactions);
                if (error)
                        goto error_exit;
        }
diff -r 3311a0e8fe49 -r 5bb602a70b05 sys/kern/kern_exec.c
--- a/sys/kern/kern_exec.c      Sun Feb 02 08:34:39 2014 +0000
+++ b/sys/kern/kern_exec.c      Sun Feb 02 14:48:57 2014 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: kern_exec.c,v 1.372 2014/02/02 08:25:23 dogcow Exp $   */
+/*     $NetBSD: kern_exec.c,v 1.373 2014/02/02 14:48:57 martin Exp $   */
 
 /*-
  * Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -59,7 +59,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_exec.c,v 1.372 2014/02/02 08:25:23 dogcow Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_exec.c,v 1.373 2014/02/02 14:48:57 martin Exp $");
 
 #include "opt_exec.h"
 #include "opt_execfmt.h"
@@ -2065,7 +2065,7 @@



Home | Main Index | Thread Index | Old Index