On Thu, May 25, 2023 at 03:06:05PM +0200, Claudio Jeker wrote: > sthen@ reported a bgpd SE crash to me and after inspection of the report > it looks like he managed to trigger a mistake in session_process_msg(). > When for example a NOTIFICATION message is received then the state change > clears the rbuf. Now normally the for loop starts over afterwards and the > if (p->rbuf == NULL) at the top causes the function to return. > In his case the peer had enough messages queued that the if (++processed > > MSG_PROCESS_LIMIT) limit triggered after the NOTIFICATION was processed. > This hits a break from the for loop and the code at the end of the > function adjusting the rbuf trips over the NULL rbuf pointer. > > This can be fixed in many ways, I decided to just check at the end of the > loop that rbuf is still valid. > > Triggering this bug is not trivial so it is hard test but the problem is > obvious.
Indeed. ok > -- > :wq Claudio > > Index: session.c > =================================================================== > RCS file: /cvs/src/usr.sbin/bgpd/session.c,v > retrieving revision 1.444 > diff -u -p -r1.444 session.c > --- session.c 5 May 2023 07:28:08 -0000 1.444 > +++ session.c 25 May 2023 09:32:11 -0000 > @@ -1998,6 +1998,8 @@ session_process_msg(struct peer *p) > } > } > > + if (p->rbuf == NULL) > + return; > if (rpos < av) { > left = av - rpos; > memmove(&p->rbuf->buf, p->rbuf->buf + rpos, left); >