Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 11 Jan 2001 02:03:08 -0800 (PST)
From:      simon@simon.org.ua
To:        freebsd-gnats-submit@FreeBSD.org
Subject:   kern/24248: Broken getsockopt(IPV6_FW_GET) with IPv6 Firewall on FreeBSD 4.1-STABLE and 4.2-STABLE locks system
Message-ID:  <200101111003.f0BA38o28626@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help

>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




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200101111003.f0BA38o28626>