[kernel] bug#109: marked as done (iptables causes trap 27)

PA-RISC Linux bug Tracking System daniel_frazier@hp.com
Thu, 3 May 2001 10:48:01 -0600 (MDT)

X-PA-RISC Linux-PR-Message: closed 109

Your message dated Thu, 3 May 2001 09:43:52 -0700 (PDT)
with message-id <200105031643.JAA12762@milano.cup.hp.com>
and subject line setsockopt() syscall wrapper committed
has caused the attached bug report to be marked as done.

This means that you claim that the problem has been dealt with.
If this is not the case it is now your responsibility to reopen the
bug report if necessary, and/or fix the problem forthwith.

(NB: If you are a system administrator and have no idea what I am
talking about this indicates a serious mail system misconfiguration
somewhere.  Please contact me immediately.)

dann frazier
(administrator, PA-RISC Linux bugs database)

Received: (at submit) by bugs.parisc-linux.org; 18 Apr 2001 20:48:08 +0000
>From grundler@puffin.external.hp.com  Wed Apr 18 14:48:08 2001
Received: from puffin.external.hp.com (puffin.external.hp.com [])
	by dsl2.external.hp.com (Postfix) with ESMTP id 38032482A
	for <submit@bugs.parisc-linux.org>; Wed, 18 Apr 2001 14:48:08 -0600 (MDT)
Received: from puffin (IDENT:grundler@localhost [])
	by puffin.external.hp.com (8.9.3/8.9.3) with ESMTP id OAA20296
	for <submit@bugs.parisc-linux.org>; Wed, 18 Apr 2001 14:41:27 -0600
Message-Id: <200104182041.OAA20296@puffin.external.hp.com>
To: submit@bugs.parisc-linux.org
Subject: iptables causes trap 27
Date: Wed, 18 Apr 2001 14:41:27 -0600
From: Grant Grundler <grundler@puffin.external.hp.com>

Package: kernel
Version: 20010418 64-bit
Severity: grave

Tried to run iptables on my A500 from /etc/init.d/firewall script.
Resulted in a "Segementation fault" (trap 27 on console output).
Kernel spewed register state at that point and locked up.

I'll submit the firewall script and .config I was using in seperate e-mails.
Notes of what I've looked at so far are appended. Out of time at the
moment to track this further.


a500:/etc/init.d# ./firewall start
Starting firewall (iptables):firewall INPUT -i eth0 -j LOG -s localhost
firewall INPUT -i eth0 -j DROP -s localhost
firewall INPUT -i eth0 -j LOG -s a500
firewall INPUT -i eth0 -j DROP -s a500
firewall INPUT -i eth1 -j ACCEPT
firewall INPUT -i eth2 -j ACCEPT
firewall INPUT -i eth3 -j ACCEPT
firewall INPUT -s localhost -j ACCEPT
firewall INPUT -s a500 -j ACCEPT
firewall INPUT -s -j ACCEPT
firewall INPUT -j ACCEPT -p tcp --syn -d 0/0 --dport 22
firewall INPUT -j ACCEPT -p tcp --syn -d 0/0 --dport http
firewall INPUT -j ACCEPT -p tcp --syn -d 0/0 --dport smtp
firewall INPUT -j ACCEPT -p tcp --syn -d 0/0 --dport ident
./firewall: line 3:   724 Segmentation fault      iptables -A $*
firewall INPUT -j ACCEPT -p tcp --syn -d 0/0 --dport ftp

iptables[724]: Protection Id Trap 27

PSW: 00001000000011000000000000001111
r0-3     0000000000000000 0000000000000040 00000000102a316c 000000000008da58
r4-7     0000000010373600 0000000000000070 000000000008d9e8 000000000008d000
r8-11    0000000010373600 0000000000000a58 0000000010373600 000000000008f000
r12-15   0000000000000000 00000000ffffffff 00000000000aee70 0000000000000000
r16-19   0000000000000000 0000000000007514 0000000000005000 000000000000003b
r20-23   0000000000000020 000000000000001f 0000000000000001 0000000000098000
r24-27   00000000000000ff 000000000008f001 000119800000e9d4 0000000010373600
r28-31   0000000000000013 00000000fcae8e30 00000000fcae9180 0000000000000000
sr0-3    0000000000000180 0000000000000180 0000000000000000 0000000000000180
sr4-7    0000000000000000 0000000000000000 0000000000000000 0000000000000000

IASQ: 0000000000000000 0000000000000000 IAOQ: 00000000102c43a8 00000000102c43a0
 IIR: 0f415222    ISR: 0000000000011980  IOR: 000000000000e9d4
ORIG_R28: 0000000010150e14

IAOQ 0x102c43a8 $lctu_loop+8
GR02 0x102a316c do_replace+51c

No stack trace *sigh*

lctu_loop seems related to copy_to_user
<willy> ggg: no... someone called copy_to_user with an invalid address to
  copy _from_, i think.

static int
do_replace(void *user, unsigned int len)
	struct ipt_replace tmp;
        struct ipt_counters *counters;
	if (copy_from_user(&tmp, user, sizeof(tmp)) != 0)
		return -EFAULT;
	counters = vmalloc(tmp.num_counters * sizeof(struct ipt_counters));
	if (!counters) {
		ret = -ENOMEM;
		goto free_newinfo;
	memset(counters, 0, tmp.num_counters * sizeof(struct ipt_counters));
	/* Get the old counters. */
	get_counters(oldinfo, counters);

        copy_to_user(tmp.counters, counters,
			sizeof(struct ipt_counters) * tmp.num_counters);

	102a3140:   37 dd 3f e1     ldo -10(sp),ret1
	102a3144:   eb 53 ad c9     b,l 10149830 <vfree>,%r2
	102a3148:   08 07 02 5a     copy r7,r26

	102a314c:   4b d8 3d c9     ldw -11c(sp),r24
	102a314c:   4b d8 3d c9     ldw -11c(sp),r24
	102a3150:   37 dd 3f e1     ldo -10(sp),ret1
	102a3154:   53 da 3d d1     ldd -118(sp),r26
	102a3158:   08 08 02 5b     copy r8,dp
	102a315c:   db 18 0b e0     extrd,u r24,63,32,r24
	102a3160:   08 0b 02 59     copy r11,r25
	102a3164:   e8 10 a4 2c     call 102c4380 <lcopy_to_user>
	102a3168:   f3 18 10 84     depd,z r24,59,60,r24

00000000102c4380 <lcopy_to_user>:
	102c4380:   87 00 20 4a     cmpib,=,n 0,r24,102c43ac <$lctu_done>
	102c4384:   08 1e 02 41     copy sp,r1
	102c4388:   f4 20 04 12     depdi 0,63,14,r1
	102c438c:   48 36 00 28     ldw 14(r1),r22
	102c4390:   00 00 c4 a1     mfsp sr3,r1
	102c4394:   08 16 32 40     or,<> r22,r0,r0
	102c4398:   08 00 02 41     copy r0,r1
	102c439c:   00 01 58 20     mtsp r1,sr1

00000000102c43a0 <$lctu_loop>:
	102c43a0:   0f 22 10 21     ldb,ma  1(sr0,r25),r1
	102c43a4:   af 1f 3f ed     addib,<> -1,r24,102c43a0 <$lctu_loop>
	102c43a8:   0f 41 52 22     stb,ma  r1,1(sr1,r26)	*** TRAP27 ***

00000000102c43ac <$lctu_done>:
	102c43ac:   e8 40 c0 00     bv r0(rp)
	102c43b0:   08 18 02 5c     copy r24,ret0
	102c43b4:   e8 1f 1f e5     b,l 102c43ac <$lctu_done>,r0
	102c43b8:   37 18 00 02     ldo 1(r24),r24

GR24 00000000000000ff
GR25 000000000008f001
GR26 000119800000e9d4
SR1  0000000000000180 	(SR0 is the same)

Looks like we tried to copyout the counters info but went past the
end of the page/space allocated by iptables. Not sure about this
conclusion though...

Received: (at 109-done) by bugs.parisc-linux.org; 3 May 2001 16:38:57 +0000
>From grundler@cup.hp.com  Thu May  3 10:38:57 2001
Received: from palrel2.hp.com (palrel2.hp.com [])
	by dsl2.external.hp.com (Postfix) with ESMTP id 114A1482A
	for <109-done@bugs.parisc-linux.org>; Thu,  3 May 2001 10:38:57 -0600 (MDT)
Received: from milano.cup.hp.com (milano.cup.hp.com [])
	by palrel2.hp.com (Postfix) with ESMTP id 66404775
	for <109-done@bugs.parisc-linux.org>; Thu,  3 May 2001 09:38:56 -0700 (PDT)
Received: (from grundler@localhost)
	by milano.cup.hp.com (8.9.3 (PHNE_18546)/8.9.3 SMKit7.02) id JAA12762
	for 109-done@bugs.parisc-linux.org; Thu, 3 May 2001 09:43:52 -0700 (PDT)
Date: Thu, 3 May 2001 09:43:52 -0700 (PDT)
From: Grant Grundler <grundler@cup.hp.com>
Message-Id: <200105031643.JAA12762@milano.cup.hp.com>
To: 109-done@bugs.parisc-linux.org
Subject: setsockopt() syscall wrapper committed
Mime-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

A syscall wrapper for setsockopt() syscall has been committed.
It "cheats" and takes advantage of padding in the struct (on 32-bit)
in order to convert the 32-bit pointer to 64-bit (and back) in user space.
No changes to iptables source package or the kernel header iptables.h
were needed.

Tested on a500 and firewall script is running with some minor changes
to permit DNS replies to pass (s/dport/sport/ in two locations).
Contact me, rbrad, or bame for a newer version of the script.