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