]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blobdiff - net/sched/act_mirred.c
net: Prevent invalid access to skb->prev in __qdisc_drop_all
[mirror_ubuntu-bionic-kernel.git] / net / sched / act_mirred.c
index 416627c66f081f26ff9284de86411c3e05390b8e..08b61849c2a2f448fa0a29b0c93037ebbbafd0e7 100644 (file)
@@ -140,6 +140,7 @@ static int tcf_mirred_init(struct net *net, struct nlattr *nla,
        m->tcfm_eaction = parm->eaction;
        if (dev != NULL) {
                m->tcfm_ifindex = parm->ifindex;
+               m->net = net;
                if (ret != ACT_P_CREATED)
                        dev_put(rcu_dereference_protected(m->tcfm_dev, 1));
                dev_hold(dev);
@@ -238,7 +239,7 @@ static void tcf_stats_update(struct tc_action *a, u64 bytes, u32 packets,
        struct tcf_t *tm = &m->tcf_tm;
 
        _bstats_cpu_update(this_cpu_ptr(a->cpu_bstats), bytes, packets);
-       tm->lastuse = lastuse;
+       tm->lastuse = max_t(u64, tm->lastuse, lastuse);
 }
 
 static int tcf_mirred_dump(struct sk_buff *skb, struct tc_action *a, int bind,
@@ -313,15 +314,11 @@ static struct notifier_block mirred_device_notifier = {
        .notifier_call = mirred_device_event,
 };
 
-static int tcf_mirred_device(const struct tc_action *a, struct net *net,
-                            struct net_device **mirred_dev)
+static struct net_device *tcf_mirred_get_dev(const struct tc_action *a)
 {
-       int ifindex = tcf_mirred_ifindex(a);
+       struct tcf_mirred *m = to_mirred(a);
 
-       *mirred_dev = __dev_get_by_index(net, ifindex);
-       if (!*mirred_dev)
-               return -EINVAL;
-       return 0;
+       return __dev_get_by_index(m->net, m->tcfm_ifindex);
 }
 
 static struct tc_action_ops act_mirred_ops = {
@@ -336,7 +333,7 @@ static struct tc_action_ops act_mirred_ops = {
        .walk           =       tcf_mirred_walker,
        .lookup         =       tcf_mirred_search,
        .size           =       sizeof(struct tcf_mirred),
-       .get_dev        =       tcf_mirred_device,
+       .get_dev        =       tcf_mirred_get_dev,
 };
 
 static __net_init int mirred_init_net(struct net *net)