bug in mips32 gcc-3.0.1 doing copy_to_user in 2.4.17 linux affects ip_tables-1.2.5 firewall code

DJ Barrow dj.barrow@asitatech.com
Wed Apr 24 08:30:00 GMT 2002


Hi,
I beleive I found a bug in the mips32 gcc compiler when compiling
/usr/src/linux/net/ipv4/netfilter/ip_tables.c

I just posted it on bugzilla on oss.sig.com


The bug shows up as confusion between the source
& dest variables being passed into a copy_to_user
inline assembly as usual for kernel compiles the
code is compiled -O2.


It manifests itself with the following error
while running iptables-1.2.5 built from the sources 
at from netfilter.samba.org
bash-2.04# ./iptables -L
iptables v1.2.5: can't initialize iptables table `filter': Bad address
Perhaps iptables or your kernel needs to be upgraded.

The kernel I am using is a broadcom kernel for a bcm_12500a board
which is a slightly modifed 2.4.17 linux kernel
as supplied from oss.sgi.com

mips-linux-gcc -v 
gives the following output, yes it is a very recent gcc.
Reading specs from 
/usr/local/sbtools/x86-linux-rh7.2/mips-linux-2.1.1/bin/../lib/gcc-lib/mips-linux/3.0.1/specs
Configured with: 
/home/cgd/proj/sb/systemsw-2.1.1/lin.x/systemsw/tools/src/gcc/configure 
--target=mips-linux 
--prefix=/usr/local/sbtools/x86-linux-rh6.0/mips-linux-2.1.1 --disable-nls 
--enable-threads --with-gnu-as --with-gnu-ld
Thread model: posix
gcc version 3.0.1 with SiByte modifications

With my slight compiler bug workaround
with the #define MIPS32_GCC_BUG   1
defined in ip_tables.c I get the correct output.
bash-2.04# ./iptables -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

The files below should highlight the
bug adequetely it might also be wise
to verify the the copy_to_user inline
in uaccess.h is good.

-------------- next part --------------
A non-text attachment was scrubbed...
Name: ip_tables.c
Type: text/x-c
Size: 43925 bytes
Desc: not available
URL: <http://gcc.gnu.org/pipermail/gcc-bugs/attachments/20020424/7bc5bf21/attachment.bin>
-------------- next part --------------
Here is a disassembly from gdb of the output
from line 1009 on in ip_tables.c with
#define MIPS32_GCC_BUG   1


The __memcpy is the actual copy_to_user
code the code prior to it is the access_ok
check.

0x80216768 <copy_entries_to_user+564>:  addu    s0,s3,a0
0x8021676c <copy_entries_to_user+568>:  addiu   s0,s0,2
0x80216770 <copy_entries_to_user+572>:  addiu   s1,s1,8
0x80216774 <copy_entries_to_user+576>:  jal     0x802373ac <strlen>
0x80216778 <copy_entries_to_user+580>:  move    a0,s1
0x8021677c <copy_entries_to_user+584>:  addiu   v0,v0,1
0x80216780 <copy_entries_to_user+588>:  sw      v0,16(sp)
0x80216784 <copy_entries_to_user+592>:  lw      a2,16(sp)
0x80216788 <copy_entries_to_user+596>:  move    a0,s0
0x8021678c <copy_entries_to_user+600>:  lw      a3,1204(gp)
0x80216790 <copy_entries_to_user+604>:  addu    v1,a0,a2
0x80216794 <copy_entries_to_user+608>:  or      v0,a0,v1
0x80216798 <copy_entries_to_user+612>:  or      v0,v0,a2
0x8021679c <copy_entries_to_user+616>:  and     a3,a3,v0
0x802167a0 <copy_entries_to_user+620>:
    bltz        a3,0x802167b0 <copy_entries_to_user+636>
0x802167a4 <copy_entries_to_user+624>:  move    a1,s1
0x802167a8 <copy_entries_to_user+628>:  jal     0x80236664 <__memcpy>
0x802167ac <copy_entries_to_user+632>:  nop
0x802167b0 <copy_entries_to_user+636>:
    bnez        a2,0x80216660 <copy_entries_to_user+300>
0x802167b4 <copy_entries_to_user+640>:  nop
0x802167b8 <copy_entries_to_user+644>:  lhu     v1,90(s2)
---Type <return> to continue, or q <return> to quit---
0x802167bc <copy_entries_to_user+648>:  addu    s4,s4,v1
0x802167c0 <copy_entries_to_user+652>:  lw      v1,72(sp)
0x802167c4 <copy_entries_to_user+656>:  sltu    v0,s4,v1
0x802167c8 <copy_entries_to_user+660>:
    bnez        v0,0x802166ac <copy_entries_to_user+376>
0x802167cc <copy_entries_to_user+664>:  addiu   s5,s5,16
0x802167d0 <copy_entries_to_user+668>:
    j   0x80216664 <copy_entries_to_user+304>
0x802167d4 <copy_entries_to_user+672>:  nop
0x802167d8 <copy_entries_to_user+676>:  lw      v0,0(v0)
0x802167dc <copy_entries_to_user+680>:
    beqz        v0,0x80216628 <copy_entries_to_user+244>
0x802167e0 <copy_entries_to_user+684>:  nop
0x802167e4 <copy_entries_to_user+688>:  jal     0x80117b00 <do_softirq>
0x802167e8 <copy_entries_to_user+692>:  nop
0x802167ec <copy_entries_to_user+696>:
    j   0x8021662c <copy_entries_to_user+248>
0x802167f0 <copy_entries_to_user+700>:  lw      a0,80(sp)
-------------- next part --------------
Here is a disassembly from gdb of the output
from line 1009 on in ip_tables.c with
#define MIPS32_GCC_BUG   0


The __memcpy is the actual copy_to_user
code the code prior to it is the access_ok
check.

From what I can tell it seems to
be getting messed up with the source
& dest registers when doing the
copy to user.


0x80216750 <copy_entries_to_user+540>:  addu    s1,s1,v1
0x80216754 <copy_entries_to_user+544>:  sltu    v0,s1,a0
0x80216758 <copy_entries_to_user+548>:
    bnez        v0,0x80216704 <copy_entries_to_user+464>
0x8021675c <copy_entries_to_user+552>:  addu    s0,s2,s1
0x80216760 <copy_entries_to_user+556>:  addu    v0,s2,a0
0x80216764 <copy_entries_to_user+560>:  lw      a0,4(v0)
0x80216768 <copy_entries_to_user+564>:  jal     0x802373ac <strlen>
0x8021676c <copy_entries_to_user+568>:  addiu   a0,a0,8
0x80216770 <copy_entries_to_user+572>:  addiu   v0,v0,1
0x80216774 <copy_entries_to_user+576>:  move    a2,v0
0x80216778 <copy_entries_to_user+580>:  addu    a0,a0,a2
0x8021677c <copy_entries_to_user+584>:  lw      v0,1204(gp)
0x80216780 <copy_entries_to_user+588>:  or      a0,a0,a0
0x80216784 <copy_entries_to_user+592>:  or      a0,a0,a2
0x80216788 <copy_entries_to_user+596>:  and     v0,v0,a0
0x8021678c <copy_entries_to_user+600>:
    bltz        v0,0x802167a0 <copy_entries_to_user+620>
0x80216790 <copy_entries_to_user+604>:  nop
0x80216794 <copy_entries_to_user+608>:  nop
0x80216798 <copy_entries_to_user+612>:  jal     0x80236664 <__memcpy>
0x8021679c <copy_entries_to_user+616>:  nop
0x802167a0 <copy_entries_to_user+620>:
---Type <return> to continue, or q <return> to quit---
    bnez        a2,0x80216660 <copy_entries_to_user+300>
0x802167a4 <copy_entries_to_user+624>:  nop
0x802167a8 <copy_entries_to_user+628>:  lhu     v1,90(s2)
0x802167ac <copy_entries_to_user+632>:  addu    s3,s3,v1
0x802167b0 <copy_entries_to_user+636>:  sltu    v0,s3,s8
0x802167b4 <copy_entries_to_user+640>:
    bnez        v0,0x802166ac <copy_entries_to_user+376>
0x802167b8 <copy_entries_to_user+644>:  addiu   s4,s4,16
0x802167bc <copy_entries_to_user+648>:
    j   0x80216664 <copy_entries_to_user+304>
0x802167c0 <copy_entries_to_user+652>:  nop
0x802167c4 <copy_entries_to_user+656>:  lw      v0,0(v0)
0x802167c8 <copy_entries_to_user+660>:
    beqz        v0,0x80216628 <copy_entries_to_user+244>
0x802167cc <copy_entries_to_user+664>:  nop
0x802167d0 <copy_entries_to_user+668>:  jal     0x80117b00 <do_softirq>
0x802167d4 <copy_entries_to_user+672>:  nop
0x802167d8 <copy_entries_to_user+676>:
    j   0x8021662c <copy_entries_to_user+248>
0x802167dc <copy_entries_to_user+680>:  lw      a0,72(sp)
0x802167e0 <get_entries>:       addiu   sp,sp,-48
0x802167e4 <get_entries+4>:     sw      s0,32(sp)
0x802167e8 <get_entries+8>:     move    s0,a0
---Type <return> to continue, or q <return> to quit---
0x802167ec <get_entries+12>:    sw      s1,36(sp)
0x802167f0 <get_entries+16>:    lui     v0,0x8028
0x802167f4 <get_entries+20>:    addiu   v0,v0,24768
0x802167f8 <get_entries+24>:    move    s1,a1
0x802167fc <get_entries+28>:    addiu   a3,sp,24
0x80216800 <get_entries+32>:    move    a1,s0
0x80216804 <get_entries+36>:    lui     a0,0x8028
0x80216808 <get_entries+40>:    addiu   a0,a0,24808
0x8021680c <get_entries+44>:    lui     a2,0x8025
0x80216810 <get_entries+48>:    addiu   a2,a2,-2004
0x80216814 <get_entries+52>:    sw      ra,40(sp)
-------------- next part --------------
A non-text attachment was scrubbed...
Name: uaccess.h
Type: text/x-c
Size: 12791 bytes
Desc: not available
URL: <http://gcc.gnu.org/pipermail/gcc-bugs/attachments/20020424/7bc5bf21/attachment-0001.bin>


More information about the Gcc-bugs mailing list