Re: SLIP / ARP oops in 2.1.79 SMP.

Bill Hawes (whawes@star.net)
Fri, 16 Jan 1998 14:52:48 -0500


This is a multi-part message in MIME format.
--------------84234D5DAFDD261FA497F9BC
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

David Woodhouse wrote:

> I've just rebooted after an oops caused by killing a sliplogin process. The
> syslog messages and the oops output are below.
>
> Sorry I can't investigate further - I've unfortunately cleaned the source tree
> since it was compiled, so I don't have the vmlinux file to investigate.

Hi David,

I appears that arp_ioctl is being called with invalid parameters so that
no device is specified. __neigh_lookup then oopses when it gets a NULL
dev pointer.

I've attached a patch that should detect the condition and return EINVAL
instead of oopsing.

Alexey, I've also made a minor change to call __neigh_lookup instead of
neigh_lookup, as it's already bh_atomic.

Regards,
Bill
--------------84234D5DAFDD261FA497F9BC
Content-Type: text/plain; charset=us-ascii; name="arp_79-patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="arp_79-patch"

--- net/ipv4/arp.c.old Tue Jan 13 10:38:37 1998
+++ net/ipv4/arp.c Fri Jan 16 15:39:53 1998
@@ -734,11 +734,9 @@
start_bh_atomic();
neigh = __neigh_lookup(&arp_tbl, &ip, dev, 1);
if (neigh) {
- unsigned state = 0;
- if (r->arp_flags&ATF_PERM)
+ unsigned state = NUD_STALE;
+ if (r->arp_flags & ATF_PERM)
state = NUD_PERMANENT;
- else
- state = NUD_STALE;
err = neigh_update(neigh, (r->arp_flags&ATF_COM) ?
r->arp_ha.sa_data : NULL, state, 1, 0);
neigh_release(neigh);
@@ -765,6 +763,7 @@
{
u32 ip = ((struct sockaddr_in *) &r->arp_pa)->sin_addr.s_addr;
struct neighbour *neigh = neigh_lookup(&arp_tbl, &ip, dev);
+ /* N.B. Do we need bh_atomic locking here? */
if (neigh) {
memcpy(r->arp_ha.sa_data, neigh->ha, dev->addr_len);
r->arp_ha.sa_family = dev->type;
@@ -802,7 +801,7 @@

err = -ENXIO;
start_bh_atomic();
- neigh = neigh_lookup(&arp_tbl, &ip, dev);
+ neigh = __neigh_lookup(&arp_tbl, &ip, dev, 0);
if (neigh) {
err = neigh_update(neigh, NULL, NUD_FAILED, 1, 0);
neigh_release(neigh);
@@ -856,6 +855,11 @@
err = -EINVAL;
if ((r.arp_flags & ATF_COM) && r.arp_ha.sa_family != dev->type)
goto out;
+ } else if (cmd != SIOCSARP) {
+ /* dev has not been set ... */
+ printk(KERN_ERR "arp_ioctl: invalid, null device\n");
+ err = -EINVAL;
+ goto out;
}

switch(cmd) {
@@ -863,6 +867,7 @@
err = arp_req_delete(&r, dev);
break;
case SIOCSARP:
+ /* This checks for dev == NULL */
err = arp_req_set(&r, dev);
break;
case SIOCGARP:

--------------84234D5DAFDD261FA497F9BC--