Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 639739b5 authored by Hannes Frederic Sowa's avatar Hannes Frederic Sowa Committed by David S. Miller
Browse files

ipv6: fix null pointer dereference in __ip6addrlbl_add



Commit b67bfe0d ("hlist: drop
the node parameter from iterators") changed the behavior of
hlist_for_each_entry_safe to leave the p argument NULL.

Fix this up by tracking the last argument.

Reported-by: default avatarMichele Baldessari <michele@acksyn.org>
Cc: Hideaki YOSHIFUJI <yoshfuji@linux-ipv6.org>
Cc: Sasha Levin <sasha.levin@oracle.com>
Signed-off-by: default avatarHannes Frederic Sowa <hannes@stressinduktion.org>
Tested-by: default avatarMichele Baldessari <michele@acksyn.org>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent a8e9fd0f
Loading
Loading
Loading
Loading
+23 −25
Original line number Diff line number Diff line
@@ -251,19 +251,14 @@ static struct ip6addrlbl_entry *ip6addrlbl_alloc(struct net *net,
/* add a label */
static int __ip6addrlbl_add(struct ip6addrlbl_entry *newp, int replace)
{
	struct hlist_node *n;
	struct ip6addrlbl_entry *last = NULL, *p = NULL;
	int ret = 0;

	ADDRLABEL(KERN_DEBUG "%s(newp=%p, replace=%d)\n",
			__func__,
			newp, replace);
	ADDRLABEL(KERN_DEBUG "%s(newp=%p, replace=%d)\n", __func__, newp,
		  replace);

	if (hlist_empty(&ip6addrlbl_table.head)) {
		hlist_add_head_rcu(&newp->list, &ip6addrlbl_table.head);
	} else {
		struct hlist_node *n;
		struct ip6addrlbl_entry *p = NULL;
		hlist_for_each_entry_safe(p, n,
					  &ip6addrlbl_table.head, list) {
	hlist_for_each_entry_safe(p, n,	&ip6addrlbl_table.head, list) {
		if (p->prefixlen == newp->prefixlen &&
		    net_eq(ip6addrlbl_net(p), ip6addrlbl_net(newp)) &&
		    p->ifindex == newp->ifindex &&
@@ -280,9 +275,12 @@ static int __ip6addrlbl_add(struct ip6addrlbl_entry *newp, int replace)
			hlist_add_before_rcu(&newp->list, &p->list);
			goto out;
		}
		last = p;
	}
		hlist_add_after_rcu(&p->list, &newp->list);
	}
	if (last)
		hlist_add_after_rcu(&last->list, &newp->list);
	else
		hlist_add_head_rcu(&newp->list, &ip6addrlbl_table.head);
out:
	if (!ret)
		ip6addrlbl_table.seq++;