[PATCH][TRUSTY][SRU] UBUNTU: SAUCE: (no-up) net/packet: fix erroneous dev_add_pack usage in fanout
Khaled Elmously
khalid.elmously at canonical.com
Sun Oct 28 22:45:27 UTC 2018
On 2018-10-26 18:00:20 , Jay Vosburgh wrote:
> BugLink: http://bugs.launchpad.net/bugs/1800254
>
> Due to changes added as part of c108ac876c02 ("packet: hold bind lock when
> rebinding to fanout hook"), it is possible for fanout_add to add a
> packet_type handler via dev_add_pack and then kfree the memory backing the
> packet_type. This corrupts the ptype_all list, causing the system to
> panic when network packet processing next traverses ptype_all. The
> erroneous path is taken when a PACKET_FANOUT setsockopt is performed on a
> packet socket that is bound to an interface that is administratively down.
>
> This is not due to any flaw of c108ac876c02, but rather than the packet
> socket code base differs subtly in 3.13 as compared to 4.4.
>
> The remedy for this is to include additional changes in the management
> of the dev_add_pack calls from 4.4. This moves the dev_add_pack and
> dev_remove_pack calls from fanout_add and _release into __fanout_link
> and _unlink.
>
> These changes originate in 2bd624b4611f ("packet: Do not call
> fanout_release from atomic contexts"). We do not include that patch in
> its entirety as it has other dependencies, and this is the minimal
> change set to resolve the issue.
>
> Signed-off-by: Jay Vosburgh <jay.vosburgh at canonical.com>
>
> ---
> net/packet/af_packet.c | 6 ++++--
> 1 file changed, 4 insertions(+), 2 deletions(-)
>
> diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
> index c0230c7458df..fa02443df232 100644
> --- a/net/packet/af_packet.c
> +++ b/net/packet/af_packet.c
> @@ -1267,6 +1267,8 @@ static void __fanout_link(struct sock *sk, struct packet_sock *po)
> f->arr[f->num_members] = sk;
> smp_wmb();
> f->num_members++;
> + if (f->num_members == 1)
> + dev_add_pack(&f->prot_hook);
> spin_unlock(&f->lock);
> }
>
> @@ -1283,6 +1285,8 @@ static void __fanout_unlink(struct sock *sk, struct packet_sock *po)
> BUG_ON(i >= f->num_members);
> f->arr[i] = f->arr[f->num_members - 1];
> f->num_members--;
> + if (f->num_members == 0)
> + __dev_remove_pack(&f->prot_hook);
Should the above line be a call to dev_remove_pack() instead of __dev_remove_pack() ?
> spin_unlock(&f->lock);
> }
>
> @@ -1350,7 +1354,6 @@ static int fanout_add(struct sock *sk, u16 id, u16 type_flags)
> match->prot_hook.func = packet_rcv_fanout;
> match->prot_hook.af_packet_priv = match;
> match->prot_hook.id_match = match_fanout_group;
> - dev_add_pack(&match->prot_hook);
> list_add(&match->list, &fanout_list);
> }
> err = -EINVAL;
> @@ -1393,7 +1396,6 @@ static void fanout_release(struct sock *sk)
>
> if (atomic_dec_and_test(&f->sk_ref)) {
> list_del(&f->list);
> - dev_remove_pack(&f->prot_hook);
> kfree(f);
> }
> }
> --
> 2.7.4
>
> --
> kernel-team mailing list
> kernel-team at lists.ubuntu.com
> https://lists.ubuntu.com/mailman/listinfo/kernel-team
More information about the kernel-team
mailing list