[kernel] bug#109: kernel] bug#109: iptables causes trap 27


None


X-PA-RISC Linux-PR-Message: report 109
X-PA-RISC Linux-PR-Package: kernel
X-Loop: daniel_frazier@hp.com
Received: via spool by 109-bugs@bugs.parisc-linux.org id=B109.98767763922886
          (code B ref 109); Thu, 19 Apr 2001 11:03:01 GMT
Date: Thu, 19 Apr 2001 11:53:58 +0100
From: Richard Hirst <rhirst@linuxcare.com>
To: Grant Grundler <grundler@puffin.external.hp.com>,
	109@bugs.parisc-linux.org
Message-ID: <20010419115358.C11226@linuxcare.com>
Mime-Version: 1.0
Content-Type: text/plain; charset=us-ascii
X-Mailer: Mutt 1.0us
In-Reply-To: <no.id>; from kernel-admin@lists.parisc-linux.org on Thu, Apr 19, 2001 at 04:42:06AM +0000

On Thu, Apr 19, 2001 at 04:42:06AM +0000, kernel-admin@lists.parisc-linux.org wrote:
> X-PA-RISC Linux-PR-Message: report 109
> X-PA-RISC Linux-PR-Package: kernel
> X-Loop: daniel_frazier@hp.com
> Received: via spool by 109-bugs@bugs.parisc-linux.org id=B109.98765449418885
>           (code B ref 109); Thu, 19 Apr 2001 04:33:01 GMT
> Message-Id: <200104190421.WAA21523@puffin.external.hp.com>
> To: Richard Hirst <rhirst@linuxcare.com>
> Cc: 109@bugs.parisc-linux.org
> In-Reply-To: Your message of "Wed, 18 Apr 2001 22:41:44 BST."
>              <20010418224144.Y11226@linuxcare.com> 
> Date: Wed, 18 Apr 2001 22:21:37 -0600
> From: Grant Grundler <grundler@puffin.external.hp.com>
> 
> Richard Hirst wrote:
> > > 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...
> > 
> > I'd guess gr26 was screwed.  Surely the top half should be zero?
> 
> I thought so too. But then thought I have no clue how we copy from
> kernel to user space and have sr1 == sr0. Hopefully jsm or willy
> can comment on this ASAP.
> 
> I haven't traced the syscall path.
> This could be a 32-user/64-kernel issue.
> 0x00011980 would be a valid user app address while 0xe9d4 would not.

Spot on.  do_replace() copies a struct ipt_replace from user space and
the tries to use a (32 bit) pointer from that struct as somewhere to
copy the old counter values to.  I think this means we need a syscall
wrapper for at least sys_setsockopt, if I've understood how do_replace()
gets called.

In the meantime, I did this very ugly hack, which should work given
the layout of the struct, and the fact that 32 bit userland adds 4
bytes of padding after the counter anyway.  counters is at offset
88, struct size is 96 (which explains why the len check at the
start of do_replace didn't fail).

With this, I could run your firewall script without any obvious problems.


Index: net/ipv4/netfilter/ip_tables.c
===================================================================
RCS file: /home/cvs/parisc/linux/net/ipv4/netfilter/ip_tables.c,v
retrieving revision 1.3
diff -u -r1.3 ip_tables.c
--- ip_tables.c 2001/01/25 00:03:55     1.3
+++ ip_tables.c 2001/04/19 10:41:17
@@ -1107,8 +1107,13 @@
        IPT_ENTRY_ITERATE(oldinfo->entries, oldinfo->size, cleanup_entry,NULL);
        vfree(oldinfo);
        /* Silent error: too late now. */
+#if defined(__hppa__) && defined(__LP64__)
+       copy_to_user((void *)((long)tmp.counters >> 32), counters,
+                    sizeof(struct ipt_counters) * tmp.num_counters);
+#else
        copy_to_user(tmp.counters, counters,
                     sizeof(struct ipt_counters) * tmp.num_counters);
+#endif
        vfree(counters);
        up(&ipt_mutex);
        return 0;