Messages in this thread Patch in this message |  | | | Date | Fri, 16 Jan 1998 14:52:48 -0500 | | From | Bill Hawes <> | | Subject | Re: SLIP / ARP oops in 2.1.79 SMP. |
| |
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--- 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: |  |