Remove the rnewprocp argument from fork1(9)

It's now unused and it can cause use-after-free scenarios as noted by
<Mateusz Guzik>.

Reference: http://mail-index.netbsd.org/tech-kern/2017/09/08/msg022267.html

Sponsored by <The NetBSD Foundation>
This commit is contained in:
kamil 2018-04-16 14:51:59 +00:00
parent 3c41a2b898
commit d20c39ee39
6 changed files with 21 additions and 35 deletions

View File

@ -1,4 +1,4 @@
.\" $NetBSD: fork1.9,v 1.14 2008/04/30 13:10:58 martin Exp $
.\" $NetBSD: fork1.9,v 1.15 2018/04/16 14:51:59 kamil Exp $
.\"
.\" Copyright (c) 1998 The NetBSD Foundation, Inc.
.\" All rights reserved.
@ -28,7 +28,7 @@
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
.\" POSSIBILITY OF SUCH DAMAGE.
.\"
.Dd January 4, 2008
.Dd April 16, 2018
.Dt FORK1 9
.Os
.Sh NAME
@ -38,7 +38,7 @@
.In sys/types.h
.In sys/proc.h
.Ft int
.Fn "fork1" "struct lwp *l1" "int flags" "int exitsig" "void *stack" "size_t stacksize" "void (*func)(void *)" "void *arg" "register_t *retval" "struct proc **rnewprocp"
.Fn "fork1" "struct lwp *l1" "int flags" "int exitsig" "void *stack" "size_t stacksize" "void (*func)(void *)" "void *arg" "register_t *retval"
.Sh DESCRIPTION
.Fn fork1
creates a new process out of the process behind
@ -132,13 +132,6 @@ User level system call stubs typically subtract 1 from
and bitwise-AND it with
.Ar retval[0] ,
thus returning the pid to the parent process and 0 to the child.
.Pp
If
.Ar rnewprocp
is not NULL,
.Ar *rnewprocp
will point to the newly created process upon successful completion of
the fork operation.
.Sh RETURN VALUES
Upon successful completion of the fork operation,
.Fn fork1

View File

@ -1,4 +1,4 @@
/* $NetBSD: freebsd_fork.c,v 1.8 2017/08/08 08:04:06 maxv Exp $ */
/* $NetBSD: freebsd_fork.c,v 1.9 2018/04/16 14:51:59 kamil Exp $ */
/*-
* Copyright (c) 2002 The NetBSD Foundation, Inc.
@ -27,7 +27,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: freebsd_fork.c,v 1.8 2017/08/08 08:04:06 maxv Exp $");
__KERNEL_RCSID(0, "$NetBSD: freebsd_fork.c,v 1.9 2018/04/16 14:51:59 kamil Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -81,5 +81,5 @@ freebsd_sys_rfork(struct lwp *l, const struct freebsd_sys_rfork_args *uap, regis
return (fork1(l, flags,
SCARG(uap, flags) & FREEBSD_RFLINUXTHPN ? SIGUSR1 : SIGCHLD,
NULL, 0, NULL, NULL, retval, NULL));
NULL, 0, NULL, NULL, retval));
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: linux_sched.c,v 1.70 2018/04/15 03:25:25 kamil Exp $ */
/* $NetBSD: linux_sched.c,v 1.71 2018/04/16 14:51:59 kamil Exp $ */
/*-
* Copyright (c) 1999 The NetBSD Foundation, Inc.
@ -35,7 +35,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: linux_sched.c,v 1.70 2018/04/15 03:25:25 kamil Exp $");
__KERNEL_RCSID(0, "$NetBSD: linux_sched.c,v 1.71 2018/04/16 14:51:59 kamil Exp $");
#include <sys/param.h>
#include <sys/mount.h>
@ -158,7 +158,7 @@ linux_sys_clone(struct lwp *l, const struct linux_sys_clone_args *uap,
* that makes this adjustment is a noop.
*/
if ((error = fork1(l, flags, sig, SCARG(uap, stack), 0,
linux_child_return, NULL, retval, NULL)) != 0) {
linux_child_return, NULL, retval)) != 0) {
DPRINTF(("%s: fork1: error %d\n", __func__, error));
return error;
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: init_main.c,v 1.496 2018/04/16 14:18:16 kamil Exp $ */
/* $NetBSD: init_main.c,v 1.497 2018/04/16 14:51:59 kamil Exp $ */
/*-
* Copyright (c) 2008, 2009 The NetBSD Foundation, Inc.
@ -97,7 +97,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: init_main.c,v 1.496 2018/04/16 14:18:16 kamil Exp $");
__KERNEL_RCSID(0, "$NetBSD: init_main.c,v 1.497 2018/04/16 14:51:59 kamil Exp $");
#include "opt_ddb.h"
#include "opt_inet.h"
@ -608,7 +608,7 @@ main(void)
* wait for us to inform it that the root file system has been
* mounted.
*/
if (fork1(l, 0, SIGCHLD, NULL, 0, start_init, NULL, NULL, NULL))
if (fork1(l, 0, SIGCHLD, NULL, 0, start_init, NULL, NULL))
panic("fork init");
/*

View File

@ -1,4 +1,4 @@
/* $NetBSD: kern_fork.c,v 1.203 2017/11/07 19:44:04 christos Exp $ */
/* $NetBSD: kern_fork.c,v 1.204 2018/04/16 14:51:59 kamil Exp $ */
/*-
* Copyright (c) 1999, 2001, 2004, 2006, 2007, 2008 The NetBSD Foundation, Inc.
@ -67,7 +67,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: kern_fork.c,v 1.203 2017/11/07 19:44:04 christos Exp $");
__KERNEL_RCSID(0, "$NetBSD: kern_fork.c,v 1.204 2018/04/16 14:51:59 kamil Exp $");
#include "opt_ktrace.h"
#include "opt_dtrace.h"
@ -117,7 +117,7 @@ int
sys_fork(struct lwp *l, const void *v, register_t *retval)
{
return fork1(l, 0, SIGCHLD, NULL, 0, NULL, NULL, retval, NULL);
return fork1(l, 0, SIGCHLD, NULL, 0, NULL, NULL, retval);
}
/*
@ -129,7 +129,7 @@ sys_vfork(struct lwp *l, const void *v, register_t *retval)
{
return fork1(l, FORK_PPWAIT, SIGCHLD, NULL, 0, NULL, NULL,
retval, NULL);
retval);
}
/*
@ -141,7 +141,7 @@ sys___vfork14(struct lwp *l, const void *v, register_t *retval)
{
return fork1(l, FORK_PPWAIT|FORK_SHAREVM, SIGCHLD, NULL, 0,
NULL, NULL, retval, NULL);
NULL, NULL, retval);
}
/*
@ -194,7 +194,7 @@ sys___clone(struct lwp *l, const struct sys___clone_args *uap,
* code that makes this adjustment is a noop.
*/
return fork1(l, flags, sig, SCARG(uap, stack), 0,
NULL, NULL, retval, NULL);
NULL, NULL, retval);
}
/*
@ -209,8 +209,7 @@ static struct timeval fork_tfmrate = { 10, 0 };
*/
int
fork1(struct lwp *l1, int flags, int exitsig, void *stack, size_t stacksize,
void (*func)(void *), void *arg, register_t *retval,
struct proc **rnewprocp)
void (*func)(void *), void *arg, register_t *retval)
{
struct proc *p1, *p2, *parent;
struct plimit *p1_lim;
@ -524,12 +523,6 @@ fork1(struct lwp *l1, int flags, int exitsig, void *stack, size_t stacksize,
if (flags & FORK_SHAREVM)
uvmexp.forks_sharevm++;
/*
* Pass a pointer to the new process to the caller.
*/
if (rnewprocp != NULL)
*rnewprocp = p2;
if (ktrpoint(KTR_EMUL))
p2->p_traceflag |= KTRFAC_TRC_EMUL;

View File

@ -1,4 +1,4 @@
/* $NetBSD: proc.h,v 1.344 2018/01/09 20:55:43 maya Exp $ */
/* $NetBSD: proc.h,v 1.345 2018/04/16 14:51:59 kamil Exp $ */
/*-
* Copyright (c) 2006, 2007, 2008 The NetBSD Foundation, Inc.
@ -522,7 +522,7 @@ void proc_free_pid(pid_t);
void proc_free_mem(struct proc *);
void exit_lwps(struct lwp *l);
int fork1(struct lwp *, int, int, void *, size_t,
void (*)(void *), void *, register_t *, struct proc **);
void (*)(void *), void *, register_t *);
int pgid_in_session(struct proc *, pid_t);
void cpu_lwp_fork(struct lwp *, struct lwp *, void *, size_t,
void (*)(void *), void *);