@@ -562,7 +562,9 @@ void mrp_request_leave(const struct net_device *dev,
}
EXPORT_SYMBOL_GPL(mrp_request_leave);
-static void mrp_mad_event(struct mrp_applicant *app, enum mrp_event event)
+static void mrp_mad_event_helper(struct mrp_applicant *app,
+ enum mrp_event event,
+ int state)
{
struct rb_node *node, *next;
struct mrp_attr *attr;
@@ -571,10 +573,24 @@ static void mrp_mad_event(struct mrp_applicant *app, enum mrp_event event)
next = node ? rb_next(node) : NULL, node != NULL;
node = next) {
attr = rb_entry(node, struct mrp_attr, node);
+ if (state != -1)
+ attr->state = state;
mrp_attr_event(app, attr, event);
}
}
+static void mrp_mad_event(struct mrp_applicant *app, enum mrp_event event)
+{
+ mrp_mad_event_helper(app, event, -1);
+}
+
+static void mrp_mad_event_state(struct mrp_applicant *app,
+ enum mrp_event event,
+ enum mrp_applicant_state state)
+{
+ mrp_mad_event_helper(app, event, state);
+}
+
static void mrp_join_timer_arm(struct mrp_applicant *app)
{
unsigned long delay;
@@ -894,7 +910,7 @@ void mrp_uninit_applicant(struct net_device *dev, struct mrp_application *appl)
del_timer_sync(&app->periodic_timer);
spin_lock_bh(&app->lock);
- mrp_mad_event(app, MRP_EVENT_TX);
+ mrp_mad_event_state(app, MRP_EVENT_TX, MRP_APPLICANT_LA);
mrp_pdu_queue(app);
spin_unlock_bh(&app->lock);
[ I was investigating this bug and I sort of got carried away and wrote a patch. I'm going to see if I can find a test system to start testing these patches then I will resend the patch. - dan ] Syzbot discovered that mrp_attr attr structs are being leaked. They're supposed to be freed by mrp_attr_destroy() which is called from mrp_attr_event(). I think that when we close everything down, we're supposed to send one last disconnect event but the code for that wasn't fully implemented. Reported-by: syzbot+5cfab121b54dff775399@syzkaller.appspotmail.com Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com> --- Not tested. Idea only. net/802/mrp.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-)