On 20/05/18(Sun) 21:10, Alexander Bluhm wrote:
> On Sun, May 20, 2018 at 07:24:05AM +0200, [email protected] wrote:
> > http://centroid.eu/private/p5200003.jpg
>
> ml_enqueue+0x11
> /usr/src/sys/kern/uipc_mbuf.c:1498
> * 33a1: 48 89 71 08 mov %rsi,0x8(%rcx)
> 33a5: eb 07 jmp 33ae <ml_enqueue+0x1e>
>
> 1492 void
> 1493 ml_enqueue(struct mbuf_list *ml, struct mbuf *m)
> 1494 {
> 1495 if (ml->ml_tail == NULL)
> 1496 ml->ml_head = ml->ml_tail = m;
> 1497 else {
> * 1498 ml->ml_tail->m_nextpkt = m;
> 1499 ml->ml_tail = m;
> 1500 }
> 1501
> 1502 m->m_nextpkt = NULL;
> 1503 ml->ml_len++;
> 1504 }
>
> arpresolve+0x1bf
> /usr/src/sys/netinet/if_ether.c:383
> 954: 4c 89 ff mov %r15,%rdi
> 957: 4c 89 e6 mov %r12,%rsi
> 95a: e8 00 00 00 00 callq 95f <arpresolve+0x1bf>
> /usr/src/sys/netinet/if_ether.c:384
> * 95f: 83 04 25 00 00 00 00 addl $0x1,0x0
>
> 373 la = (struct llinfo_arp *)rt->rt_llinfo;
> 374 KASSERT(la != NULL);
> 375 if (la_hold_total < LA_HOLD_TOTAL && la_hold_total < nmbclust
> /
> 64) {
> 376 struct mbuf *mh;
> 377
> 378 if (ml_len(&la->la_ml) >= LA_HOLD_QUEUE) {
> 379 mh = ml_dequeue(&la->la_ml);
> 380 la_hold_total--;
> 381 m_freem(mh);
> 382 }
> * 383 ml_enqueue(&la->la_ml, m);
> 384 la_hold_total++;
> 385 } else {
> 386 la_hold_total -= ml_purge(&la->la_ml);
> 387 m_freem(m);
> 388 }
>
> So the kernel crashes when it accesses the mbuf_list in the struct
> llinfo_arp.
>
> > route change default -inet6 2001:db8:0:40::300
>
> As the address families of the route is messed up, I guess that the
> cast in line 373 is wrong. The data structure is a llinfo_nd6 and
> not a llinfo_arp.
>
> I could not reproduce the crash, but my kernel accepts an IPv6
> gateway for the IPv4 default route. This kernel diff prevents that
> user land can add or change such routes.
>
> root@v74:.../~# route change default -inet6 fdd7:e83e:66bc:74::1234
> change net default: gateway fdd7:e83e:66bc:74::1234: Address family not
> supported by protocol family
Are you sure this change won't introduce a regression with L2 route
entries? These entries generally have a Ethernet address as gateway.
In any case it would be nice to add this problem to the route regression
test.
> Index: net/rtsock.c
> ===================================================================
> RCS file: /data/mirror/openbsd/cvs/src/sys/net/rtsock.c,v
> retrieving revision 1.265
> diff -u -p -r1.265 rtsock.c
> --- net/rtsock.c 14 May 2018 07:33:59 -0000 1.265
> +++ net/rtsock.c 20 May 2018 19:02:08 -0000
> @@ -718,6 +718,14 @@ route_output(struct mbuf *m, struct sock
> info.rti_flags |= RTF_LLINFO;
> }
>
> + if (info.rti_info[RTAX_DST] != NULL &&
> + info.rti_info[RTAX_GATEWAY] != NULL &&
> + info.rti_info[RTAX_DST]->sa_family !=
> + info.rti_info[RTAX_GATEWAY]->sa_family) {
> + error = EAFNOSUPPORT;
> + goto fail;
> + }
> +
> /*
> * Validate RTM_PROPOSAL and pass it along or error out.
> */
>