From 1fee083a44bfa7ac1cadfb80561352e9c9d1e071 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 15 Jun 2017 12:26:46 +0200 Subject: [PATCH] 4.9-stable patches added patches: drm-nouveau-prevent-userspace-from-deleting-client-object.patch ethtool-do-not-vzalloc-0-on-registers-dump.patch fs-cache-initialise-stores_lock-in-netfs-cookie.patch fscache-clear-outstanding-writes-when-disabling-a-cookie.patch fscache-fix-dead-object-requeue.patch ipv6-fix-flow-labels-when-the-traffic-class-is-non-0.patch net-fix-ndo_features_check-ndo_fix_features-comment-ordering.patch net-phy-fix-lack-of-reference-count-on-phy-driver.patch net-phy-fix-phy-module-checks-and-null-deref-in-phy_attach_direct.patch --- ...serspace-from-deleting-client-object.patch | 29 +++ ...l-do-not-vzalloc-0-on-registers-dump.patch | 70 +++++++ ...itialise-stores_lock-in-netfs-cookie.patch | 34 ++++ ...nding-writes-when-disabling-a-cookie.patch | 82 ++++++++ .../fscache-fix-dead-object-requeue.patch | 189 ++++++++++++++++++ ...bels-when-the-traffic-class-is-non-0.patch | 88 ++++++++ ...ck-ndo_fix_features-comment-ordering.patch | 77 +++++++ ...ack-of-reference-count-on-phy-driver.patch | 101 ++++++++++ ...-and-null-deref-in-phy_attach_direct.patch | 117 +++++++++++ queue-4.9/series | 9 + 10 files changed, 796 insertions(+) create mode 100644 queue-4.9/drm-nouveau-prevent-userspace-from-deleting-client-object.patch create mode 100644 queue-4.9/ethtool-do-not-vzalloc-0-on-registers-dump.patch create mode 100644 queue-4.9/fs-cache-initialise-stores_lock-in-netfs-cookie.patch create mode 100644 queue-4.9/fscache-clear-outstanding-writes-when-disabling-a-cookie.patch create mode 100644 queue-4.9/fscache-fix-dead-object-requeue.patch create mode 100644 queue-4.9/ipv6-fix-flow-labels-when-the-traffic-class-is-non-0.patch create mode 100644 queue-4.9/net-fix-ndo_features_check-ndo_fix_features-comment-ordering.patch create mode 100644 queue-4.9/net-phy-fix-lack-of-reference-count-on-phy-driver.patch create mode 100644 queue-4.9/net-phy-fix-phy-module-checks-and-null-deref-in-phy_attach_direct.patch diff --git a/queue-4.9/drm-nouveau-prevent-userspace-from-deleting-client-object.patch b/queue-4.9/drm-nouveau-prevent-userspace-from-deleting-client-object.patch new file mode 100644 index 00000000000..78d66c43b1e --- /dev/null +++ b/queue-4.9/drm-nouveau-prevent-userspace-from-deleting-client-object.patch @@ -0,0 +1,29 @@ +From foo@baz Thu Jun 15 12:25:36 CEST 2017 +From: Ben Skeggs +Date: Tue, 23 May 2017 21:54:08 -0400 +Subject: drm/nouveau: prevent userspace from deleting client object + +From: Ben Skeggs + + +[ Upstream commit c966b6279f610a24ac1d42dcbe30e10fa61220b2 ] + +Signed-off-by: Ben Skeggs +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/nouveau/nouveau_usif.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/gpu/drm/nouveau/nouveau_usif.c ++++ b/drivers/gpu/drm/nouveau/nouveau_usif.c +@@ -313,7 +313,8 @@ usif_ioctl(struct drm_file *filp, void _ + if (!(ret = nvif_unpack(-ENOSYS, &data, &size, argv->v0, 0, 0, true))) { + /* block access to objects not created via this interface */ + owner = argv->v0.owner; +- if (argv->v0.object == 0ULL) ++ if (argv->v0.object == 0ULL && ++ argv->v0.type != NVIF_IOCTL_V0_DEL) + argv->v0.owner = NVDRM_OBJECT_ANY; /* except client */ + else + argv->v0.owner = NVDRM_OBJECT_USIF; diff --git a/queue-4.9/ethtool-do-not-vzalloc-0-on-registers-dump.patch b/queue-4.9/ethtool-do-not-vzalloc-0-on-registers-dump.patch new file mode 100644 index 00000000000..469bc3317db --- /dev/null +++ b/queue-4.9/ethtool-do-not-vzalloc-0-on-registers-dump.patch @@ -0,0 +1,70 @@ +From foo@baz Thu Jun 15 12:25:36 CEST 2017 +From: Stanislaw Gruszka +Date: Tue, 23 May 2017 21:53:59 -0400 +Subject: ethtool: do not vzalloc(0) on registers dump + +From: Stanislaw Gruszka + + +[ Upstream commit 3808d34838184fd29088d6b3a364ba2f1c018fb6 ] + +If ->get_regs_len() callback return 0, we allocate 0 bytes of memory, +what print ugly warning in dmesg, which can be found further below. + +This happen on mac80211 devices where ieee80211_get_regs_len() just +return 0 and driver only fills ethtool_regs structure and actually +do not provide any dump. However I assume this can happen on other +drivers i.e. when for some devices driver provide regs dump and for +others do not. Hence preventing to to print warning in ethtool code +seems to be reasonable. + +ethtool: vmalloc: allocation failure: 0 bytes, mode:0x24080c2(GFP_KERNEL|__GFP_HIGHMEM|__GFP_ZERO) + +Call Trace: +[] dump_stack+0x63/0x8c +[] warn_alloc+0x13f/0x170 +[] __vmalloc_node_range+0x1e6/0x2c0 +[] vzalloc+0x54/0x60 +[] dev_ethtool+0xb4c/0x1b30 +[] dev_ioctl+0x181/0x520 +[] sock_do_ioctl+0x42/0x50 + +Mem-Info: +active_anon:435809 inactive_anon:173951 isolated_anon:0 + active_file:835822 inactive_file:196932 isolated_file:0 + unevictable:0 dirty:8 writeback:0 unstable:0 + slab_reclaimable:157732 slab_unreclaimable:10022 + mapped:83042 shmem:306356 pagetables:9507 bounce:0 + free:130041 free_pcp:1080 free_cma:0 +Node 0 active_anon:1743236kB inactive_anon:695804kB active_file:3343288kB inactive_file:787728kB unevictable:0kB isolated(anon):0kB isolated(file):0kB mapped:332168kB dirty:32kB writeback:0kB shmem:0kB shmem_thp: 0kB shmem_pmdmapped: 0kB anon_thp: 1225424kB writeback_tmp:0kB unstable:0kB pages_scanned:0 all_unreclaimable? no +Node 0 DMA free:15900kB min:136kB low:168kB high:200kB active_anon:0kB inactive_anon:0kB active_file:0kB inactive_file:0kB unevictable:0kB writepending:0kB present:15984kB managed:15900kB mlocked:0kB slab_reclaimable:0kB slab_unreclaimable:0kB kernel_stack:0kB pagetables:0kB bounce:0kB free_pcp:0kB local_pcp:0kB free_cma:0kB +lowmem_reserve[]: 0 3187 7643 7643 +Node 0 DMA32 free:419732kB min:28124kB low:35152kB high:42180kB active_anon:541180kB inactive_anon:248988kB active_file:1466388kB inactive_file:389632kB unevictable:0kB writepending:0kB present:3370280kB managed:3290932kB mlocked:0kB slab_reclaimable:217184kB slab_unreclaimable:4180kB kernel_stack:160kB pagetables:984kB bounce:0kB free_pcp:2236kB local_pcp:660kB free_cma:0kB +lowmem_reserve[]: 0 0 4456 4456 + +Signed-off-by: Stanislaw Gruszka +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + net/core/ethtool.c | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +--- a/net/core/ethtool.c ++++ b/net/core/ethtool.c +@@ -1394,9 +1394,12 @@ static int ethtool_get_regs(struct net_d + if (regs.len > reglen) + regs.len = reglen; + +- regbuf = vzalloc(reglen); +- if (reglen && !regbuf) +- return -ENOMEM; ++ regbuf = NULL; ++ if (reglen) { ++ regbuf = vzalloc(reglen); ++ if (!regbuf) ++ return -ENOMEM; ++ } + + ops->get_regs(dev, ®s, regbuf); + diff --git a/queue-4.9/fs-cache-initialise-stores_lock-in-netfs-cookie.patch b/queue-4.9/fs-cache-initialise-stores_lock-in-netfs-cookie.patch new file mode 100644 index 00000000000..9faea9b146c --- /dev/null +++ b/queue-4.9/fs-cache-initialise-stores_lock-in-netfs-cookie.patch @@ -0,0 +1,34 @@ +From foo@baz Thu Jun 15 12:25:36 CEST 2017 +From: David Howells +Date: Tue, 23 May 2017 21:54:06 -0400 +Subject: FS-Cache: Initialise stores_lock in netfs cookie + +From: David Howells + + +[ Upstream commit 62deb8187d116581c88c69a2dd9b5c16588545d4 ] + +Initialise the stores_lock in fscache netfs cookies. Technically, it +shouldn't be necessary, since the netfs cookie is an index and stores no +data, but initialising it anyway adds insignificant overhead. + +Signed-off-by: David Howells +Reviewed-by: Jeff Layton +Acked-by: Steve Dickson +Signed-off-by: Al Viro +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + fs/fscache/netfs.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/fs/fscache/netfs.c ++++ b/fs/fscache/netfs.c +@@ -48,6 +48,7 @@ int __fscache_register_netfs(struct fsca + cookie->flags = 1 << FSCACHE_COOKIE_ENABLED; + + spin_lock_init(&cookie->lock); ++ spin_lock_init(&cookie->stores_lock); + INIT_HLIST_HEAD(&cookie->backing_objects); + + /* check the netfs type is not already present */ diff --git a/queue-4.9/fscache-clear-outstanding-writes-when-disabling-a-cookie.patch b/queue-4.9/fscache-clear-outstanding-writes-when-disabling-a-cookie.patch new file mode 100644 index 00000000000..8e379180fcb --- /dev/null +++ b/queue-4.9/fscache-clear-outstanding-writes-when-disabling-a-cookie.patch @@ -0,0 +1,82 @@ +From foo@baz Thu Jun 15 12:25:36 CEST 2017 +From: David Howells +Date: Tue, 23 May 2017 21:54:05 -0400 +Subject: fscache: Clear outstanding writes when disabling a cookie + +From: David Howells + + +[ Upstream commit 6bdded59c8933940ac7e5b416448276ac89d1144 ] + +fscache_disable_cookie() needs to clear the outstanding writes on the +cookie it's disabling because they cannot be completed after. + +Without this, fscache_nfs_open_file() gets stuck because it disables the +cookie when the file is opened for writing but can't uncache the pages till +afterwards - otherwise there's a race between the open routine and anyone +who already has it open R/O and is still reading from it. + +Looking in /proc/pid/stack of the offending process shows: + +[] __fscache_wait_on_page_write+0x82/0x9b [fscache] +[] __fscache_uncache_all_inode_pages+0x91/0xe1 [fscache] +[] nfs_fscache_open_file+0x59/0x9e [nfs] +[] nfs4_file_open+0x17f/0x1b8 [nfsv4] +[] do_dentry_open+0x16d/0x2b7 +[] vfs_open+0x5c/0x65 +[] path_openat+0x785/0x8fb +[] do_filp_open+0x48/0x9e +[] do_sys_open+0x13b/0x1cb +[] SyS_open+0x19/0x1b +[] do_syscall_64+0x80/0x17a +[] return_from_SYSCALL_64+0x0/0x7a +[] 0xffffffffffffffff + +Reported-by: Jianhong Yin +Signed-off-by: David Howells +Acked-by: Jeff Layton +Acked-by: Steve Dickson +Signed-off-by: Al Viro +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + fs/fscache/cookie.c | 5 +++++ + fs/fscache/object.c | 6 ++++++ + 2 files changed, 11 insertions(+) + +--- a/fs/fscache/cookie.c ++++ b/fs/fscache/cookie.c +@@ -542,6 +542,7 @@ void __fscache_disable_cookie(struct fsc + hlist_for_each_entry(object, &cookie->backing_objects, cookie_link) { + if (invalidate) + set_bit(FSCACHE_OBJECT_RETIRED, &object->flags); ++ clear_bit(FSCACHE_OBJECT_PENDING_WRITE, &object->flags); + fscache_raise_event(object, FSCACHE_OBJECT_EV_KILL); + } + } else { +@@ -560,6 +561,10 @@ void __fscache_disable_cookie(struct fsc + wait_on_atomic_t(&cookie->n_active, fscache_wait_atomic_t, + TASK_UNINTERRUPTIBLE); + ++ /* Make sure any pending writes are cancelled. */ ++ if (cookie->def->type != FSCACHE_COOKIE_TYPE_INDEX) ++ fscache_invalidate_writes(cookie); ++ + /* Reset the cookie state if it wasn't relinquished */ + if (!test_bit(FSCACHE_COOKIE_RELINQUISHED, &cookie->flags)) { + atomic_inc(&cookie->n_active); +--- a/fs/fscache/object.c ++++ b/fs/fscache/object.c +@@ -650,6 +650,12 @@ static const struct fscache_state *fscac + fscache_mark_object_dead(object); + object->oob_event_mask = 0; + ++ if (test_bit(FSCACHE_OBJECT_RETIRED, &object->flags)) { ++ /* Reject any new read/write ops and abort any that are pending. */ ++ clear_bit(FSCACHE_OBJECT_PENDING_WRITE, &object->flags); ++ fscache_cancel_all_ops(object); ++ } ++ + if (list_empty(&object->dependents) && + object->n_ops == 0 && + object->n_children == 0) diff --git a/queue-4.9/fscache-fix-dead-object-requeue.patch b/queue-4.9/fscache-fix-dead-object-requeue.patch new file mode 100644 index 00000000000..ffadbbe8003 --- /dev/null +++ b/queue-4.9/fscache-fix-dead-object-requeue.patch @@ -0,0 +1,189 @@ +From foo@baz Thu Jun 15 12:25:36 CEST 2017 +From: David Howells +Date: Tue, 23 May 2017 21:54:04 -0400 +Subject: fscache: Fix dead object requeue + +From: David Howells + + +[ Upstream commit e26bfebdfc0d212d366de9990a096665d5c0209a ] + +Under some circumstances, an fscache object can become queued such that it +fscache_object_work_func() can be called once the object is in the +OBJECT_DEAD state. This results in the kernel oopsing when it tries to +invoke the handler for the state (which is hard coded to 0x2). + +The way this comes about is something like the following: + + (1) The object dispatcher is processing a work state for an object. This + is done in workqueue context. + + (2) An out-of-band event comes in that isn't masked, causing the object to + be queued, say EV_KILL. + + (3) The object dispatcher finishes processing the current work state on + that object and then sees there's another event to process, so, + without returning to the workqueue core, it processes that event too. + It then follows the chain of events that initiates until we reach + OBJECT_DEAD without going through a wait state (such as + WAIT_FOR_CLEARANCE). + + At this point, object->events may be 0, object->event_mask will be 0 + and oob_event_mask will be 0. + + (4) The object dispatcher returns to the workqueue processor, and in due + course, this sees that the object's work item is still queued and + invokes it again. + + (5) The current state is a work state (OBJECT_DEAD), so the dispatcher + jumps to it - resulting in an OOPS. + +When I'm seeing this, the work state in (1) appears to have been either +LOOK_UP_OBJECT or CREATE_OBJECT (object->oob_table is +fscache_osm_lookup_oob). + +The window for (2) is very small: + + (A) object->event_mask is cleared whilst the event dispatch process is + underway - though there's no memory barrier to force this to the top + of the function. + + The window, therefore is from the time the object was selected by the + workqueue processor and made requeueable to the time the mask was + cleared. + + (B) fscache_raise_event() will only queue the object if it manages to set + the event bit and the corresponding event_mask bit was set. + + The enqueuement is then deferred slightly whilst we get a ref on the + object and get the per-CPU variable for workqueue congestion. This + slight deferral slightly increases the probability by allowing extra + time for the workqueue to make the item requeueable. + +Handle this by giving the dead state a processor function and checking the +for the dead state address rather than seeing if the processor function is +address 0x2. The dead state processor function can then set a flag to +indicate that it's occurred and give a warning if it occurs more than once +per object. + +If this race occurs, an oops similar to the following is seen (note the RIP +value): + +BUG: unable to handle kernel NULL pointer dereference at 0000000000000002 +IP: [<0000000000000002>] 0x1 +PGD 0 +Oops: 0010 [#1] SMP +Modules linked in: ... +CPU: 17 PID: 16077 Comm: kworker/u48:9 Not tainted 3.10.0-327.18.2.el7.x86_64 #1 +Hardware name: HP ProLiant DL380 Gen9/ProLiant DL380 Gen9, BIOS P89 12/27/2015 +Workqueue: fscache_object fscache_object_work_func [fscache] +task: ffff880302b63980 ti: ffff880717544000 task.ti: ffff880717544000 +RIP: 0010:[<0000000000000002>] [<0000000000000002>] 0x1 +RSP: 0018:ffff880717547df8 EFLAGS: 00010202 +RAX: ffffffffa0368640 RBX: ffff880edf7a4480 RCX: dead000000200200 +RDX: 0000000000000002 RSI: 00000000ffffffff RDI: ffff880edf7a4480 +RBP: ffff880717547e18 R08: 0000000000000000 R09: dfc40a25cb3a4510 +R10: dfc40a25cb3a4510 R11: 0000000000000400 R12: 0000000000000000 +R13: ffff880edf7a4510 R14: ffff8817f6153400 R15: 0000000000000600 +FS: 0000000000000000(0000) GS:ffff88181f420000(0000) knlGS:0000000000000000 +CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +CR2: 0000000000000002 CR3: 000000000194a000 CR4: 00000000001407e0 +DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 +DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400 +Stack: + ffffffffa0363695 ffff880edf7a4510 ffff88093f16f900 ffff8817faa4ec00 + ffff880717547e60 ffffffff8109d5db 00000000faa4ec18 0000000000000000 + ffff8817faa4ec18 ffff88093f16f930 ffff880302b63980 ffff88093f16f900 +Call Trace: + [] ? fscache_object_work_func+0xa5/0x200 [fscache] + [] process_one_work+0x17b/0x470 + [] worker_thread+0x21c/0x400 + [] ? rescuer_thread+0x400/0x400 + [] kthread+0xcf/0xe0 + [] ? kthread_create_on_node+0x140/0x140 + [] ret_from_fork+0x58/0x90 + [] ? kthread_create_on_node+0x140/0x140 + +Signed-off-by: David Howells +Acked-by: Jeremy McNicoll +Tested-by: Frank Sorenson +Tested-by: Benjamin Coddington +Reviewed-by: Benjamin Coddington +Signed-off-by: Al Viro +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + fs/fscache/object.c | 26 ++++++++++++++++++++++++-- + include/linux/fscache-cache.h | 1 + + 2 files changed, 25 insertions(+), 2 deletions(-) + +--- a/fs/fscache/object.c ++++ b/fs/fscache/object.c +@@ -30,6 +30,7 @@ static const struct fscache_state *fscac + static const struct fscache_state *fscache_object_available(struct fscache_object *, int); + static const struct fscache_state *fscache_parent_ready(struct fscache_object *, int); + static const struct fscache_state *fscache_update_object(struct fscache_object *, int); ++static const struct fscache_state *fscache_object_dead(struct fscache_object *, int); + + #define __STATE_NAME(n) fscache_osm_##n + #define STATE(n) (&__STATE_NAME(n)) +@@ -91,7 +92,7 @@ static WORK_STATE(LOOKUP_FAILURE, "LCFL" + static WORK_STATE(KILL_OBJECT, "KILL", fscache_kill_object); + static WORK_STATE(KILL_DEPENDENTS, "KDEP", fscache_kill_dependents); + static WORK_STATE(DROP_OBJECT, "DROP", fscache_drop_object); +-static WORK_STATE(OBJECT_DEAD, "DEAD", (void*)2UL); ++static WORK_STATE(OBJECT_DEAD, "DEAD", fscache_object_dead); + + static WAIT_STATE(WAIT_FOR_INIT, "?INI", + TRANSIT_TO(INIT_OBJECT, 1 << FSCACHE_OBJECT_EV_NEW_CHILD)); +@@ -229,6 +230,10 @@ execute_work_state: + event = -1; + if (new_state == NO_TRANSIT) { + _debug("{OBJ%x} %s notrans", object->debug_id, state->name); ++ if (unlikely(state == STATE(OBJECT_DEAD))) { ++ _leave(" [dead]"); ++ return; ++ } + fscache_enqueue_object(object); + event_mask = object->oob_event_mask; + goto unmask_events; +@@ -239,7 +244,7 @@ execute_work_state: + object->state = state = new_state; + + if (state->work) { +- if (unlikely(state->work == ((void *)2UL))) { ++ if (unlikely(state == STATE(OBJECT_DEAD))) { + _leave(" [dead]"); + return; + } +@@ -1077,3 +1082,20 @@ void fscache_object_mark_killed(struct f + } + } + EXPORT_SYMBOL(fscache_object_mark_killed); ++ ++/* ++ * The object is dead. We can get here if an object gets queued by an event ++ * that would lead to its death (such as EV_KILL) when the dispatcher is ++ * already running (and so can be requeued) but hasn't yet cleared the event ++ * mask. ++ */ ++static const struct fscache_state *fscache_object_dead(struct fscache_object *object, ++ int event) ++{ ++ if (!test_and_set_bit(FSCACHE_OBJECT_RUN_AFTER_DEAD, ++ &object->flags)) ++ return NO_TRANSIT; ++ ++ WARN(true, "FS-Cache object redispatched after death"); ++ return NO_TRANSIT; ++} +--- a/include/linux/fscache-cache.h ++++ b/include/linux/fscache-cache.h +@@ -360,6 +360,7 @@ struct fscache_object { + #define FSCACHE_OBJECT_IS_AVAILABLE 5 /* T if object has become active */ + #define FSCACHE_OBJECT_RETIRED 6 /* T if object was retired on relinquishment */ + #define FSCACHE_OBJECT_KILLED_BY_CACHE 7 /* T if object was killed by the cache */ ++#define FSCACHE_OBJECT_RUN_AFTER_DEAD 8 /* T if object has been dispatched after death */ + + struct list_head cache_link; /* link in cache->object_list */ + struct hlist_node cookie_link; /* link in cookie->backing_objects */ diff --git a/queue-4.9/ipv6-fix-flow-labels-when-the-traffic-class-is-non-0.patch b/queue-4.9/ipv6-fix-flow-labels-when-the-traffic-class-is-non-0.patch new file mode 100644 index 00000000000..4512e637ee5 --- /dev/null +++ b/queue-4.9/ipv6-fix-flow-labels-when-the-traffic-class-is-non-0.patch @@ -0,0 +1,88 @@ +From foo@baz Thu Jun 15 12:25:36 CEST 2017 +From: Dimitris Michailidis +Date: Tue, 23 May 2017 21:54:07 -0400 +Subject: ipv6: fix flow labels when the traffic class is non-0 + +From: Dimitris Michailidis + + +[ Upstream commit 90427ef5d2a4b9a24079889bf16afdcdaebc4240 ] + +ip6_make_flowlabel() determines the flow label for IPv6 packets. It's +supposed to be passed a flow label, which it returns as is if non-0 and +in some other cases, otherwise it calculates a new value. + +The problem is callers often pass a flowi6.flowlabel, which may also +contain traffic class bits. If the traffic class is non-0 +ip6_make_flowlabel() mistakes the non-0 it gets as a flow label and +returns the whole thing. Thus it can return a 'flow label' longer than +20b and the low 20b of that is typically 0 resulting in packets with 0 +label. Moreover, different packets of a flow may be labeled differently. +For a TCP flow with ECN non-payload and payload packets get different +labels as exemplified by this pair of consecutive packets: + +(pure ACK) +Internet Protocol Version 6, Src: 2002:af5:11a3::, Dst: 2002:af5:11a2:: + 0110 .... = Version: 6 + .... 0000 0000 .... .... .... .... .... = Traffic Class: 0x00 (DSCP: CS0, ECN: Not-ECT) + .... 0000 00.. .... .... .... .... .... = Differentiated Services Codepoint: Default (0) + .... .... ..00 .... .... .... .... .... = Explicit Congestion Notification: Not ECN-Capable Transport (0) + .... .... .... 0001 1100 1110 0100 1001 = Flow Label: 0x1ce49 + Payload Length: 32 + Next Header: TCP (6) + +(payload) +Internet Protocol Version 6, Src: 2002:af5:11a3::, Dst: 2002:af5:11a2:: + 0110 .... = Version: 6 + .... 0000 0010 .... .... .... .... .... = Traffic Class: 0x02 (DSCP: CS0, ECN: ECT(0)) + .... 0000 00.. .... .... .... .... .... = Differentiated Services Codepoint: Default (0) + .... .... ..10 .... .... .... .... .... = Explicit Congestion Notification: ECN-Capable Transport codepoint '10' (2) + .... .... .... 0000 0000 0000 0000 0000 = Flow Label: 0x00000 + Payload Length: 688 + Next Header: TCP (6) + +This patch allows ip6_make_flowlabel() to be passed more than just a +flow label and has it extract the part it really wants. This was simpler +than modifying the callers. With this patch packets like the above become + +Internet Protocol Version 6, Src: 2002:af5:11a3::, Dst: 2002:af5:11a2:: + 0110 .... = Version: 6 + .... 0000 0000 .... .... .... .... .... = Traffic Class: 0x00 (DSCP: CS0, ECN: Not-ECT) + .... 0000 00.. .... .... .... .... .... = Differentiated Services Codepoint: Default (0) + .... .... ..00 .... .... .... .... .... = Explicit Congestion Notification: Not ECN-Capable Transport (0) + .... .... .... 1010 1111 1010 0101 1110 = Flow Label: 0xafa5e + Payload Length: 32 + Next Header: TCP (6) + +Internet Protocol Version 6, Src: 2002:af5:11a3::, Dst: 2002:af5:11a2:: + 0110 .... = Version: 6 + .... 0000 0010 .... .... .... .... .... = Traffic Class: 0x02 (DSCP: CS0, ECN: ECT(0)) + .... 0000 00.. .... .... .... .... .... = Differentiated Services Codepoint: Default (0) + .... .... ..10 .... .... .... .... .... = Explicit Congestion Notification: ECN-Capable Transport codepoint '10' (2) + .... .... .... 1010 1111 1010 0101 1110 = Flow Label: 0xafa5e + Payload Length: 688 + Next Header: TCP (6) + +Signed-off-by: Dimitris Michailidis +Acked-by: Eric Dumazet +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + include/net/ipv6.h | 5 +++++ + 1 file changed, 5 insertions(+) + +--- a/include/net/ipv6.h ++++ b/include/net/ipv6.h +@@ -776,6 +776,11 @@ static inline __be32 ip6_make_flowlabel( + { + u32 hash; + ++ /* @flowlabel may include more than a flow label, eg, the traffic class. ++ * Here we want only the flow label value. ++ */ ++ flowlabel &= IPV6_FLOWLABEL_MASK; ++ + if (flowlabel || + net->ipv6.sysctl.auto_flowlabels == IP6_AUTO_FLOW_LABEL_OFF || + (!autolabel && diff --git a/queue-4.9/net-fix-ndo_features_check-ndo_fix_features-comment-ordering.patch b/queue-4.9/net-fix-ndo_features_check-ndo_fix_features-comment-ordering.patch new file mode 100644 index 00000000000..82eeb95eeb6 --- /dev/null +++ b/queue-4.9/net-fix-ndo_features_check-ndo_fix_features-comment-ordering.patch @@ -0,0 +1,77 @@ +From foo@baz Thu Jun 15 12:25:36 CEST 2017 +From: Dimitris Michailidis +Date: Tue, 23 May 2017 21:54:02 -0400 +Subject: net: fix ndo_features_check/ndo_fix_features comment ordering + +From: Dimitris Michailidis + + +[ Upstream commit 1a2a14444d32b89b28116daea86f63ced1716668 ] + +Commit cdba756f5803a2 ("net: move ndo_features_check() close to +ndo_start_xmit()") inadvertently moved the doc comment for +.ndo_fix_features instead of .ndo_features_check. Fix the comment +ordering. + +Fixes: cdba756f5803a2 ("net: move ndo_features_check() close to ndo_start_xmit()") +Signed-off-by: Dimitris Michailidis +Acked-by: Eric Dumazet +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + include/linux/netdevice.h | 29 +++++++++++++++-------------- + 1 file changed, 15 insertions(+), 14 deletions(-) + +--- a/include/linux/netdevice.h ++++ b/include/linux/netdevice.h +@@ -865,11 +865,15 @@ struct netdev_xdp { + * of useless work if you return NETDEV_TX_BUSY. + * Required; cannot be NULL. + * +- * netdev_features_t (*ndo_fix_features)(struct net_device *dev, +- * netdev_features_t features); +- * Adjusts the requested feature flags according to device-specific +- * constraints, and returns the resulting flags. Must not modify +- * the device state. ++ * netdev_features_t (*ndo_features_check)(struct sk_buff *skb, ++ * struct net_device *dev ++ * netdev_features_t features); ++ * Called by core transmit path to determine if device is capable of ++ * performing offload operations on a given packet. This is to give ++ * the device an opportunity to implement any restrictions that cannot ++ * be otherwise expressed by feature flags. The check is called with ++ * the set of features that the stack has calculated and it returns ++ * those the driver believes to be appropriate. + * + * u16 (*ndo_select_queue)(struct net_device *dev, struct sk_buff *skb, + * void *accel_priv, select_queue_fallback_t fallback); +@@ -1027,6 +1031,12 @@ struct netdev_xdp { + * Called to release previously enslaved netdev. + * + * Feature/offload setting functions. ++ * netdev_features_t (*ndo_fix_features)(struct net_device *dev, ++ * netdev_features_t features); ++ * Adjusts the requested feature flags according to device-specific ++ * constraints, and returns the resulting flags. Must not modify ++ * the device state. ++ * + * int (*ndo_set_features)(struct net_device *dev, netdev_features_t features); + * Called to update device configuration to new features. Passed + * feature set might be less than what was returned by ndo_fix_features()). +@@ -1099,15 +1109,6 @@ struct netdev_xdp { + * Callback to use for xmit over the accelerated station. This + * is used in place of ndo_start_xmit on accelerated net + * devices. +- * netdev_features_t (*ndo_features_check)(struct sk_buff *skb, +- * struct net_device *dev +- * netdev_features_t features); +- * Called by core transmit path to determine if device is capable of +- * performing offload operations on a given packet. This is to give +- * the device an opportunity to implement any restrictions that cannot +- * be otherwise expressed by feature flags. The check is called with +- * the set of features that the stack has calculated and it returns +- * those the driver believes to be appropriate. + * int (*ndo_set_tx_maxrate)(struct net_device *dev, + * int queue_index, u32 maxrate); + * Called when a user wants to set a max-rate limitation of specific diff --git a/queue-4.9/net-phy-fix-lack-of-reference-count-on-phy-driver.patch b/queue-4.9/net-phy-fix-lack-of-reference-count-on-phy-driver.patch new file mode 100644 index 00000000000..5c9aa7d5852 --- /dev/null +++ b/queue-4.9/net-phy-fix-lack-of-reference-count-on-phy-driver.patch @@ -0,0 +1,101 @@ +From foo@baz Thu Jun 15 12:25:36 CEST 2017 +From: Mao Wenan +Date: Tue, 23 May 2017 21:54:00 -0400 +Subject: net: phy: Fix lack of reference count on PHY driver + +From: Mao Wenan + + +[ Upstream commit cafe8df8b9bc9aa3dffa827c1a6757c6cd36f657 ] + +There is currently no reference count being held on the PHY driver, +which makes it possible to remove the PHY driver module while the PHY +state machine is running and polling the PHY. This could cause crashes +similar to this one to show up: + +[ 43.361162] BUG: unable to handle kernel NULL pointer dereference at 0000000000000140 +[ 43.361162] IP: phy_state_machine+0x32/0x490 +[ 43.361162] PGD 59dc067 +[ 43.361162] PUD 0 +[ 43.361162] +[ 43.361162] Oops: 0000 [#1] SMP +[ 43.361162] Modules linked in: dsa_loop [last unloaded: broadcom] +[ 43.361162] CPU: 0 PID: 1299 Comm: kworker/0:3 Not tainted 4.10.0-rc5+ #415 +[ 43.361162] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), +BIOS Ubuntu-1.8.2-1ubuntu2 04/01/2014 +[ 43.361162] Workqueue: events_power_efficient phy_state_machine +[ 43.361162] task: ffff880006782b80 task.stack: ffffc90000184000 +[ 43.361162] RIP: 0010:phy_state_machine+0x32/0x490 +[ 43.361162] RSP: 0018:ffffc90000187e18 EFLAGS: 00000246 +[ 43.361162] RAX: 0000000000000000 RBX: ffff8800059e53c0 RCX: +ffff880006a15c60 +[ 43.361162] RDX: ffff880006782b80 RSI: 0000000000000000 RDI: +ffff8800059e5428 +[ 43.361162] RBP: ffffc90000187e48 R08: ffff880006a15c40 R09: +0000000000000000 +[ 43.361162] R10: 0000000000000000 R11: 0000000000000000 R12: +ffff8800059e5428 +[ 43.361162] R13: ffff8800059e5000 R14: 0000000000000000 R15: +ffff880006a15c40 +[ 43.361162] FS: 0000000000000000(0000) GS:ffff880006a00000(0000) +knlGS:0000000000000000 +[ 43.361162] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +[ 43.361162] CR2: 0000000000000140 CR3: 0000000005979000 CR4: +00000000000006f0 +[ 43.361162] Call Trace: +[ 43.361162] process_one_work+0x1b4/0x3e0 +[ 43.361162] worker_thread+0x43/0x4d0 +[ 43.361162] ? __schedule+0x17f/0x4e0 +[ 43.361162] kthread+0xf7/0x130 +[ 43.361162] ? process_one_work+0x3e0/0x3e0 +[ 43.361162] ? kthread_create_on_node+0x40/0x40 +[ 43.361162] ret_from_fork+0x29/0x40 +[ 43.361162] Code: 56 41 55 41 54 4c 8d 67 68 53 4c 8d af 40 fc ff ff +48 89 fb 4c 89 e7 48 83 ec 08 e8 c9 9d 27 00 48 8b 83 60 ff ff ff 44 8b +73 98 <48> 8b 90 40 01 00 00 44 89 f0 48 85 d2 74 08 4c 89 ef ff d2 8b + +Keep references on the PHY driver module right before we are going to +utilize it in phy_attach_direct(), and conversely when we don't use it +anymore in phy_detach(). + +Signed-off-by: Mao Wenan +[florian: rebase, rework commit message] +Signed-off-by: Florian Fainelli +Signed-off-by: David S. Miller + +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/phy/phy_device.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +--- a/drivers/net/phy/phy_device.c ++++ b/drivers/net/phy/phy_device.c +@@ -872,6 +872,11 @@ int phy_attach_direct(struct net_device + return -EIO; + } + ++ if (!try_module_get(d->driver->owner)) { ++ dev_err(&dev->dev, "failed to get the device driver module\n"); ++ return -EIO; ++ } ++ + get_device(d); + + /* Assume that if there is no driver, that it doesn't +@@ -927,6 +932,7 @@ int phy_attach_direct(struct net_device + + error: + put_device(d); ++ module_put(d->driver->owner); + if (ndev_owner != bus->owner) + module_put(bus->owner); + return err; +@@ -1007,6 +1013,7 @@ void phy_detach(struct phy_device *phyde + bus = phydev->mdio.bus; + + put_device(&phydev->mdio.dev); ++ module_put(phydev->mdio.dev.driver->owner); + if (ndev_owner != bus->owner) + module_put(bus->owner); + } diff --git a/queue-4.9/net-phy-fix-phy-module-checks-and-null-deref-in-phy_attach_direct.patch b/queue-4.9/net-phy-fix-phy-module-checks-and-null-deref-in-phy_attach_direct.patch new file mode 100644 index 00000000000..3aba9450923 --- /dev/null +++ b/queue-4.9/net-phy-fix-phy-module-checks-and-null-deref-in-phy_attach_direct.patch @@ -0,0 +1,117 @@ +From foo@baz Thu Jun 15 12:25:36 CEST 2017 +From: Florian Fainelli +Date: Wed, 8 Feb 2017 19:05:26 -0800 +Subject: net: phy: Fix PHY module checks and NULL deref in phy_attach_direct() + +From: Florian Fainelli + + +[ Upstream commit 6d9f66ac7fec2a6ccd649e5909806dfe36f1fc25 ] + +The Generic PHY drivers gets assigned after we checked that the current +PHY driver is NULL, so we need to check a few things before we can +safely dereference d->driver. This would be causing a NULL deference to +occur when a system binds to the Generic PHY driver. Update +phy_attach_direct() to do the following: + +- grab the driver module reference after we have assigned the Generic + PHY drivers accordingly, and remember we came from the generic PHY + path + +- update the error path to clean up the module reference in case the + Generic PHY probe function fails + +- split the error path involving phy_detacht() to avoid double free/put + since phy_detach() does all the clean up + +- finally, have phy_detach() drop the module reference count before we + call device_release_driver() for the Generic PHY driver case + +Fixes: cafe8df8b9bc ("net: phy: Fix lack of reference count on PHY driver") +Signed-off-by: Florian Fainelli +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/phy/phy_device.c | 29 +++++++++++++++++++++-------- + 1 file changed, 21 insertions(+), 8 deletions(-) + +--- a/drivers/net/phy/phy_device.c ++++ b/drivers/net/phy/phy_device.c +@@ -860,6 +860,7 @@ int phy_attach_direct(struct net_device + struct module *ndev_owner = dev->dev.parent->driver->owner; + struct mii_bus *bus = phydev->mdio.bus; + struct device *d = &phydev->mdio.dev; ++ bool using_genphy = false; + int err; + + /* For Ethernet device drivers that register their own MDIO bus, we +@@ -872,11 +873,6 @@ int phy_attach_direct(struct net_device + return -EIO; + } + +- if (!try_module_get(d->driver->owner)) { +- dev_err(&dev->dev, "failed to get the device driver module\n"); +- return -EIO; +- } +- + get_device(d); + + /* Assume that if there is no driver, that it doesn't +@@ -890,12 +886,22 @@ int phy_attach_direct(struct net_device + d->driver = + &genphy_driver[GENPHY_DRV_1G].mdiodrv.driver; + ++ using_genphy = true; ++ } ++ ++ if (!try_module_get(d->driver->owner)) { ++ dev_err(&dev->dev, "failed to get the device driver module\n"); ++ err = -EIO; ++ goto error_put_device; ++ } ++ ++ if (using_genphy) { + err = d->driver->probe(d); + if (err >= 0) + err = device_bind_driver(d); + + if (err) +- goto error; ++ goto error_module_put; + } + + if (phydev->attached_dev) { +@@ -931,8 +937,14 @@ int phy_attach_direct(struct net_device + return err; + + error: +- put_device(d); ++ /* phy_detach() does all of the cleanup below */ ++ phy_detach(phydev); ++ return err; ++ ++error_module_put: + module_put(d->driver->owner); ++error_put_device: ++ put_device(d); + if (ndev_owner != bus->owner) + module_put(bus->owner); + return err; +@@ -993,6 +1005,8 @@ void phy_detach(struct phy_device *phyde + phydev->attached_dev = NULL; + phy_suspend(phydev); + ++ module_put(phydev->mdio.dev.driver->owner); ++ + /* If the device had no specific driver before (i.e. - it + * was using the generic driver), we unbind the device + * from the generic driver so that there's a chance a +@@ -1013,7 +1027,6 @@ void phy_detach(struct phy_device *phyde + bus = phydev->mdio.bus; + + put_device(&phydev->mdio.dev); +- module_put(phydev->mdio.dev.driver->owner); + if (ndev_owner != bus->owner) + module_put(bus->owner); + } diff --git a/queue-4.9/series b/queue-4.9/series index ba9658cd678..1f389fa0f83 100644 --- a/queue-4.9/series +++ b/queue-4.9/series @@ -32,3 +32,12 @@ jump-label-pass-kbuild_cflags-when-checking-for-asm-goto-support.patch shmem-fix-sleeping-from-atomic-context.patch kasan-respect-proc-sys-kernel-traceoff_on_warning.patch log2-make-order_base_2-behave-correctly-on-const-input-value-zero.patch +ethtool-do-not-vzalloc-0-on-registers-dump.patch +net-phy-fix-lack-of-reference-count-on-phy-driver.patch +net-phy-fix-phy-module-checks-and-null-deref-in-phy_attach_direct.patch +net-fix-ndo_features_check-ndo_fix_features-comment-ordering.patch +fscache-fix-dead-object-requeue.patch +fscache-clear-outstanding-writes-when-disabling-a-cookie.patch +fs-cache-initialise-stores_lock-in-netfs-cookie.patch +ipv6-fix-flow-labels-when-the-traffic-class-is-non-0.patch +drm-nouveau-prevent-userspace-from-deleting-client-object.patch -- 2.47.3