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.
-- 
: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);

Reply via email to