From owner-freebsd-bugs Thu Jan 11 2:10:25 2001 Delivered-To: freebsd-bugs@hub.freebsd.org Received: from freefall.freebsd.org (freefall.FreeBSD.org [216.136.204.21]) by hub.freebsd.org (Postfix) with ESMTP id 8AC0F37B401 for ; Thu, 11 Jan 2001 02:10:03 -0800 (PST) Received: (from gnats@localhost) by freefall.freebsd.org (8.11.1/8.11.1) id f0BAA3Z31278; Thu, 11 Jan 2001 02:10:03 -0800 (PST) (envelope-from gnats) Received: from freefall.freebsd.org (freefall.FreeBSD.org [216.136.204.21]) by hub.freebsd.org (Postfix) with ESMTP id 4D1F137B401 for ; Thu, 11 Jan 2001 02:03:08 -0800 (PST) Received: (from nobody@localhost) by freefall.freebsd.org (8.11.1/8.11.1) id f0BA38o28626; Thu, 11 Jan 2001 02:03:08 -0800 (PST) (envelope-from nobody) Message-Id: <200101111003.f0BA38o28626@freefall.freebsd.org> Date: Thu, 11 Jan 2001 02:03:08 -0800 (PST) From: simon@simon.org.ua To: freebsd-gnats-submit@FreeBSD.org X-Send-Pr-Version: www-1.0 Subject: kern/24248: Broken getsockopt(IPV6_FW_GET) with IPv6 Firewall on FreeBSD 4.1-STABLE and 4.2-STABLE locks system Sender: owner-freebsd-bugs@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.org >Number: 24248 >Category: kern >Synopsis: Broken getsockopt(IPV6_FW_GET) with IPv6 Firewall on FreeBSD 4.1-STABLE and 4.2-STABLE locks system >Confidential: no >Severity: serious >Priority: medium >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Thu Jan 11 02:10:03 PST 2001 >Closed-Date: >Last-Modified: >Originator: Andrey Simonenko >Release: 4.1-STABLE i386, 4.2-STABLE i386 >Organization: >Environment: >Description: INET6 and IPv6 Firewall support is added to kernel. If I called getsockopt(sd, IPPROTO_IPV6, IPV6_FW_GET, rules, &bytes); and "bytes" isn't enough to hold whole IPv6 Firewall table in "rules", then next call or sometime just one call of such function will lock, block system. Keyboard works, but I can just switch consoles and can't ping my system over the network. This is simple test for this bug. Let's create shell script: ============================================================================ #!/bin/sh i=1 while [ ${i} -lt 1100 ] ; do ip6fw -q add ${i} allow all from any to any i=`expr ${i} + 1` done ============================================================================ This scripts create 1100 rules + 1 rule for IPv6 Firewall (+1 for default rule). If we run # ip6fw l then whole system will be blocked (sometimes I have to run this command more then one time). Let's look at source for it /usr/src/sbin/ip6fw/ip6fw.c. In function void list(ac, av) int ac; char **av; { struct ip6_fw *r; struct ip6_fw rules[1024]; int l,i; unsigned long rulenum; int bytes; /* extract rules from kernel */ memset(rules,0,sizeof rules); bytes = sizeof rules; i = getsockopt(s, IPPROTO_IPV6, IPV6_FW_GET, rules, &bytes); "rules" array can hold just 1024 rules and wee have 1100 rules. >How-To-Repeat: Don't know how to repeat bug with getsockopt(). I think that problem is in function ip6_ctloutput() in /usr/src/sys/netinet6/ip6_output.c. After "case IPV6_FW_GET" soopt_mcopyout() function is called and it doesn't check availble size of buffer passed to getsockopt(). Function like this but for IPv4 Firewall check size of buffer passed to getsockopt() and there evrything is correct. ip6fw can be simple fixed, but following change is only fast patch and really IPv6 Firewall should be fixed somewhere in kernel, as I understood. >Fix: Change size of "rules" to 65536 in following function in /usr/src/sbin/ip6fw/ip6fw.c (really kernel should be patched as I understand): void list(ac, av) int ac; char **av; { struct ip6_fw *r; struct ip6_fw rules[65536]; >Release-Note: >Audit-Trail: >Unformatted: To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-bugs" in the body of the message