From: Greg Kroah-Hartman Date: Sat, 26 Sep 2015 17:52:53 +0000 (-0700) Subject: 3.10-stable patches X-Git-Tag: v4.1.9~16 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=491b57996da9c45c2908d5c0f0e2d455b9fbb71e;p=thirdparty%2Fkernel%2Fstable-queue.git 3.10-stable patches added patches: hfs-fix-b-tree-corruption-after-insertion-at-position-0.patch hfs-hfsplus-cache-pages-correctly-between-bnode_create-and-bnode_free.patch ib-mlx4-forbid-using-sysfs-to-change-roce-pkeys.patch ib-mlx4-use-correct-sl-on-ah-query-under-roce.patch ib-uverbs-fix-race-between-ib_uverbs_open-and-remove_one.patch ib-uverbs-reject-invalid-or-unknown-opcodes.patch stmmac-fix-check-for-phydev-being-open.patch --- diff --git a/queue-3.10/hfs-fix-b-tree-corruption-after-insertion-at-position-0.patch b/queue-3.10/hfs-fix-b-tree-corruption-after-insertion-at-position-0.patch new file mode 100644 index 00000000000..5ced0ddd2c7 --- /dev/null +++ b/queue-3.10/hfs-fix-b-tree-corruption-after-insertion-at-position-0.patch @@ -0,0 +1,77 @@ +From b4cc0efea4f0bfa2477c56af406cfcf3d3e58680 Mon Sep 17 00:00:00 2001 +From: Hin-Tak Leung +Date: Wed, 9 Sep 2015 15:38:07 -0700 +Subject: hfs: fix B-tree corruption after insertion at position 0 + +From: Hin-Tak Leung + +commit b4cc0efea4f0bfa2477c56af406cfcf3d3e58680 upstream. + +Fix B-tree corruption when a new record is inserted at position 0 in the +node in hfs_brec_insert(). + +This is an identical change to the corresponding hfs b-tree code to Sergei +Antonov's "hfsplus: fix B-tree corruption after insertion at position 0", +to keep similar code paths in the hfs and hfsplus drivers in sync, where +appropriate. + +Signed-off-by: Hin-Tak Leung +Cc: Sergei Antonov +Cc: Joe Perches +Reviewed-by: Vyacheslav Dubeyko +Cc: Anton Altaparmakov +Cc: Al Viro +Cc: Christoph Hellwig +Cc: +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + fs/hfs/brec.c | 20 +++++++++++--------- + 1 file changed, 11 insertions(+), 9 deletions(-) + +--- a/fs/hfs/brec.c ++++ b/fs/hfs/brec.c +@@ -131,13 +131,16 @@ skip: + hfs_bnode_write(node, entry, data_off + key_len, entry_len); + hfs_bnode_dump(node); + +- if (new_node) { +- /* update parent key if we inserted a key +- * at the start of the first node +- */ +- if (!rec && new_node != node) +- hfs_brec_update_parent(fd); ++ /* ++ * update parent key if we inserted a key ++ * at the start of the node and it is not the new node ++ */ ++ if (!rec && new_node != node) { ++ hfs_bnode_read_key(node, fd->search_key, data_off + size); ++ hfs_brec_update_parent(fd); ++ } + ++ if (new_node) { + hfs_bnode_put(fd->bnode); + if (!new_node->parent) { + hfs_btree_inc_height(tree); +@@ -166,9 +169,6 @@ skip: + goto again; + } + +- if (!rec) +- hfs_brec_update_parent(fd); +- + return 0; + } + +@@ -366,6 +366,8 @@ again: + if (IS_ERR(parent)) + return PTR_ERR(parent); + __hfs_brec_find(parent, fd); ++ if (fd->record < 0) ++ return -ENOENT; + hfs_bnode_dump(parent); + rec = fd->record; + diff --git a/queue-3.10/hfs-hfsplus-cache-pages-correctly-between-bnode_create-and-bnode_free.patch b/queue-3.10/hfs-hfsplus-cache-pages-correctly-between-bnode_create-and-bnode_free.patch new file mode 100644 index 00000000000..36d8bccb484 --- /dev/null +++ b/queue-3.10/hfs-hfsplus-cache-pages-correctly-between-bnode_create-and-bnode_free.patch @@ -0,0 +1,180 @@ +From 7cb74be6fd827e314f81df3c5889b87e4c87c569 Mon Sep 17 00:00:00 2001 +From: Hin-Tak Leung +Date: Wed, 9 Sep 2015 15:38:04 -0700 +Subject: hfs,hfsplus: cache pages correctly between bnode_create and bnode_free + +From: Hin-Tak Leung + +commit 7cb74be6fd827e314f81df3c5889b87e4c87c569 upstream. + +Pages looked up by __hfs_bnode_create() (called by hfs_bnode_create() and +hfs_bnode_find() for finding or creating pages corresponding to an inode) +are immediately kmap()'ed and used (both read and write) and kunmap()'ed, +and should not be page_cache_release()'ed until hfs_bnode_free(). + +This patch fixes a problem I first saw in July 2012: merely running "du" +on a large hfsplus-mounted directory a few times on a reasonably loaded +system would get the hfsplus driver all confused and complaining about +B-tree inconsistencies, and generates a "BUG: Bad page state". Most +recently, I can generate this problem on up-to-date Fedora 22 with shipped +kernel 4.0.5, by running "du /" (="/" + "/home" + "/mnt" + other smaller +mounts) and "du /mnt" simultaneously on two windows, where /mnt is a +lightly-used QEMU VM image of the full Mac OS X 10.9: + +$ df -i / /home /mnt +Filesystem Inodes IUsed IFree IUse% Mounted on +/dev/mapper/fedora-root 3276800 551665 2725135 17% / +/dev/mapper/fedora-home 52879360 716221 52163139 2% /home +/dev/nbd0p2 4294967295 1387818 4293579477 1% /mnt + +After applying the patch, I was able to run "du /" (60+ times) and "du +/mnt" (150+ times) continuously and simultaneously for 6+ hours. + +There are many reports of the hfsplus driver getting confused under load +and generating "BUG: Bad page state" or other similar issues over the +years. [1] + +The unpatched code [2] has always been wrong since it entered the kernel +tree. The only reason why it gets away with it is that the +kmap/memcpy/kunmap follow very quickly after the page_cache_release() so +the kernel has not had a chance to reuse the memory for something else, +most of the time. + +The current RW driver appears to have followed the design and development +of the earlier read-only hfsplus driver [3], where-by version 0.1 (Dec +2001) had a B-tree node-centric approach to +read_cache_page()/page_cache_release() per bnode_get()/bnode_put(), +migrating towards version 0.2 (June 2002) of caching and releasing pages +per inode extents. When the current RW code first entered the kernel [2] +in 2005, there was an REF_PAGES conditional (and "//" commented out code) +to switch between B-node centric paging to inode-centric paging. There +was a mistake with the direction of one of the REF_PAGES conditionals in +__hfs_bnode_create(). In a subsequent "remove debug code" commit [4], the +read_cache_page()/page_cache_release() per bnode_get()/bnode_put() were +removed, but a page_cache_release() was mistakenly left in (propagating +the "REF_PAGES <-> !REF_PAGE" mistake), and the commented-out +page_cache_release() in bnode_release() (which should be spanned by +!REF_PAGES) was never enabled. + +References: +[1]: +Michael Fox, Apr 2013 +http://www.spinics.net/lists/linux-fsdevel/msg63807.html +("hfsplus volume suddenly inaccessable after 'hfs: recoff %d too large'") + +Sasha Levin, Feb 2015 +http://lkml.org/lkml/2015/2/20/85 ("use after free") + +https://bugs.launchpad.net/ubuntu/+source/linux/+bug/740814 +https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1027887 +https://bugzilla.kernel.org/show_bug.cgi?id=42342 +https://bugzilla.kernel.org/show_bug.cgi?id=63841 +https://bugzilla.kernel.org/show_bug.cgi?id=78761 + +[2]: +http://git.kernel.org/cgit/linux/kernel/git/tglx/history.git/commit/\ +fs/hfs/bnode.c?id=d1081202f1d0ee35ab0beb490da4b65d4bc763db +commit d1081202f1d0ee35ab0beb490da4b65d4bc763db +Author: Andrew Morton +Date: Wed Feb 25 16:17:36 2004 -0800 + + [PATCH] HFS rewrite + +http://git.kernel.org/cgit/linux/kernel/git/tglx/history.git/commit/\ +fs/hfsplus/bnode.c?id=91556682e0bf004d98a529bf829d339abb98bbbd + +commit 91556682e0bf004d98a529bf829d339abb98bbbd +Author: Andrew Morton +Date: Wed Feb 25 16:17:48 2004 -0800 + + [PATCH] HFS+ support + +[3]: +http://sourceforge.net/projects/linux-hfsplus/ + +http://sourceforge.net/projects/linux-hfsplus/files/Linux%202.4.x%20patch/hfsplus%200.1/ +http://sourceforge.net/projects/linux-hfsplus/files/Linux%202.4.x%20patch/hfsplus%200.2/ + +http://linux-hfsplus.cvs.sourceforge.net/viewvc/linux-hfsplus/linux/\ +fs/hfsplus/bnode.c?r1=1.4&r2=1.5 + +Date: Thu Jun 6 09:45:14 2002 +0000 +Use buffer cache instead of page cache in bnode.c. Cache inode extents. + +[4]: +http://git.kernel.org/cgit/linux/kernel/git/\ +stable/linux-stable.git/commit/?id=a5e3985fa014029eb6795664c704953720cc7f7d + +commit a5e3985fa014029eb6795664c704953720cc7f7d +Author: Roman Zippel +Date: Tue Sep 6 15:18:47 2005 -0700 + +[PATCH] hfs: remove debug code + +Signed-off-by: Hin-Tak Leung +Signed-off-by: Sergei Antonov +Reviewed-by: Anton Altaparmakov +Reported-by: Sasha Levin +Cc: Al Viro +Cc: Christoph Hellwig +Cc: Vyacheslav Dubeyko +Cc: Sougata Santra +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + fs/hfs/bnode.c | 9 ++++----- + fs/hfsplus/bnode.c | 3 --- + 2 files changed, 4 insertions(+), 8 deletions(-) + +--- a/fs/hfs/bnode.c ++++ b/fs/hfs/bnode.c +@@ -288,7 +288,6 @@ static struct hfs_bnode *__hfs_bnode_cre + page_cache_release(page); + goto fail; + } +- page_cache_release(page); + node->page[i] = page; + } + +@@ -398,11 +397,11 @@ node_error: + + void hfs_bnode_free(struct hfs_bnode *node) + { +- //int i; ++ int i; + +- //for (i = 0; i < node->tree->pages_per_bnode; i++) +- // if (node->page[i]) +- // page_cache_release(node->page[i]); ++ for (i = 0; i < node->tree->pages_per_bnode; i++) ++ if (node->page[i]) ++ page_cache_release(node->page[i]); + kfree(node); + } + +--- a/fs/hfsplus/bnode.c ++++ b/fs/hfsplus/bnode.c +@@ -456,7 +456,6 @@ static struct hfs_bnode *__hfs_bnode_cre + page_cache_release(page); + goto fail; + } +- page_cache_release(page); + node->page[i] = page; + } + +@@ -568,13 +567,11 @@ node_error: + + void hfs_bnode_free(struct hfs_bnode *node) + { +-#if 0 + int i; + + for (i = 0; i < node->tree->pages_per_bnode; i++) + if (node->page[i]) + page_cache_release(node->page[i]); +-#endif + kfree(node); + } + diff --git a/queue-3.10/ib-mlx4-forbid-using-sysfs-to-change-roce-pkeys.patch b/queue-3.10/ib-mlx4-forbid-using-sysfs-to-change-roce-pkeys.patch new file mode 100644 index 00000000000..01dd89a63ac --- /dev/null +++ b/queue-3.10/ib-mlx4-forbid-using-sysfs-to-change-roce-pkeys.patch @@ -0,0 +1,51 @@ +From 2b135db3e81301d0452e6aa107349abe67b097d6 Mon Sep 17 00:00:00 2001 +From: Jack Morgenstein +Date: Thu, 30 Jul 2015 17:34:23 +0300 +Subject: IB/mlx4: Forbid using sysfs to change RoCE pkeys + +From: Jack Morgenstein + +commit 2b135db3e81301d0452e6aa107349abe67b097d6 upstream. + +The pkey mapping for RoCE must remain the default mapping: +VFs: + virtual index 0 = mapped to real index 0 (0xFFFF) + All others indices: mapped to a real pkey index containing an + invalid pkey. +PF: + virtual index i = real index i. + +Don't allow users to change these mappings using files found in +sysfs. + +Fixes: c1e7e466120b ('IB/mlx4: Add iov directory in sysfs under the ib device') +Signed-off-by: Jack Morgenstein +Signed-off-by: Or Gerlitz +Signed-off-by: Doug Ledford +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/infiniband/hw/mlx4/sysfs.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +--- a/drivers/infiniband/hw/mlx4/sysfs.c ++++ b/drivers/infiniband/hw/mlx4/sysfs.c +@@ -563,6 +563,8 @@ static int add_port(struct mlx4_ib_dev * + struct mlx4_port *p; + int i; + int ret; ++ int is_eth = rdma_port_get_link_layer(&dev->ib_dev, port_num) == ++ IB_LINK_LAYER_ETHERNET; + + p = kzalloc(sizeof *p, GFP_KERNEL); + if (!p) +@@ -580,7 +582,8 @@ static int add_port(struct mlx4_ib_dev * + + p->pkey_group.name = "pkey_idx"; + p->pkey_group.attrs = +- alloc_group_attrs(show_port_pkey, store_port_pkey, ++ alloc_group_attrs(show_port_pkey, ++ is_eth ? NULL : store_port_pkey, + dev->dev->caps.pkey_table_len[port_num]); + if (!p->pkey_group.attrs) + goto err_alloc; diff --git a/queue-3.10/ib-mlx4-use-correct-sl-on-ah-query-under-roce.patch b/queue-3.10/ib-mlx4-use-correct-sl-on-ah-query-under-roce.patch new file mode 100644 index 00000000000..e49dc40f33e --- /dev/null +++ b/queue-3.10/ib-mlx4-use-correct-sl-on-ah-query-under-roce.patch @@ -0,0 +1,40 @@ +From 5e99b139f1b68acd65e36515ca347b03856dfb5a Mon Sep 17 00:00:00 2001 +From: Noa Osherovich +Date: Thu, 30 Jul 2015 17:34:24 +0300 +Subject: IB/mlx4: Use correct SL on AH query under RoCE + +From: Noa Osherovich + +commit 5e99b139f1b68acd65e36515ca347b03856dfb5a upstream. + +The mlx4 IB driver implementation for ib_query_ah used a wrong offset +(28 instead of 29) when link type is Ethernet. Fixed to use the correct one. + +Fixes: fa417f7b520e ('IB/mlx4: Add support for IBoE') +Signed-off-by: Shani Michaeli +Signed-off-by: Noa Osherovich +Signed-off-by: Or Gerlitz +Signed-off-by: Doug Ledford +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/infiniband/hw/mlx4/ah.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +--- a/drivers/infiniband/hw/mlx4/ah.c ++++ b/drivers/infiniband/hw/mlx4/ah.c +@@ -169,9 +169,13 @@ int mlx4_ib_query_ah(struct ib_ah *ibah, + enum rdma_link_layer ll; + + memset(ah_attr, 0, sizeof *ah_attr); +- ah_attr->sl = be32_to_cpu(ah->av.ib.sl_tclass_flowlabel) >> 28; + ah_attr->port_num = be32_to_cpu(ah->av.ib.port_pd) >> 24; + ll = rdma_port_get_link_layer(ibah->device, ah_attr->port_num); ++ if (ll == IB_LINK_LAYER_ETHERNET) ++ ah_attr->sl = be32_to_cpu(ah->av.eth.sl_tclass_flowlabel) >> 29; ++ else ++ ah_attr->sl = be32_to_cpu(ah->av.ib.sl_tclass_flowlabel) >> 28; ++ + ah_attr->dlid = ll == IB_LINK_LAYER_INFINIBAND ? be16_to_cpu(ah->av.ib.dlid) : 0; + if (ah->av.ib.stat_rate) + ah_attr->static_rate = ah->av.ib.stat_rate - MLX4_STAT_RATE_OFFSET; diff --git a/queue-3.10/ib-uverbs-fix-race-between-ib_uverbs_open-and-remove_one.patch b/queue-3.10/ib-uverbs-fix-race-between-ib_uverbs_open-and-remove_one.patch new file mode 100644 index 00000000000..2195da63f6f --- /dev/null +++ b/queue-3.10/ib-uverbs-fix-race-between-ib_uverbs_open-and-remove_one.patch @@ -0,0 +1,201 @@ +From 35d4a0b63dc0c6d1177d4f532a9deae958f0662c Mon Sep 17 00:00:00 2001 +From: Yishai Hadas +Date: Thu, 13 Aug 2015 18:32:03 +0300 +Subject: IB/uverbs: Fix race between ib_uverbs_open and remove_one + +From: Yishai Hadas + +commit 35d4a0b63dc0c6d1177d4f532a9deae958f0662c upstream. + +Fixes: 2a72f212263701b927559f6850446421d5906c41 ("IB/uverbs: Remove dev_table") + +Before this commit there was a device look-up table that was protected +by a spin_lock used by ib_uverbs_open and by ib_uverbs_remove_one. When +it was dropped and container_of was used instead, it enabled the race +with remove_one as dev might be freed just after: +dev = container_of(inode->i_cdev, struct ib_uverbs_device, cdev) but +before the kref_get. + +In addition, this buggy patch added some dead code as +container_of(x,y,z) can never be NULL and so dev can never be NULL. +As a result the comment above ib_uverbs_open saying "the open method +will either immediately run -ENXIO" is wrong as it can never happen. + +The solution follows Jason Gunthorpe suggestion from below URL: +https://www.mail-archive.com/linux-rdma@vger.kernel.org/msg25692.html + +cdev will hold a kref on the parent (the containing structure, +ib_uverbs_device) and only when that kref is released it is +guaranteed that open will never be called again. + +In addition, fixes the active count scheme to use an atomic +not a kref to prevent WARN_ON as pointed by above comment +from Jason. + +Signed-off-by: Yishai Hadas +Signed-off-by: Shachar Raindel +Reviewed-by: Jason Gunthorpe +Signed-off-by: Doug Ledford +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/infiniband/core/uverbs.h | 3 +- + drivers/infiniband/core/uverbs_main.c | 43 +++++++++++++++++++++++----------- + 2 files changed, 32 insertions(+), 14 deletions(-) + +--- a/drivers/infiniband/core/uverbs.h ++++ b/drivers/infiniband/core/uverbs.h +@@ -69,7 +69,7 @@ + */ + + struct ib_uverbs_device { +- struct kref ref; ++ atomic_t refcount; + int num_comp_vectors; + struct completion comp; + struct device *dev; +@@ -78,6 +78,7 @@ struct ib_uverbs_device { + struct cdev cdev; + struct rb_root xrcd_tree; + struct mutex xrcd_tree_mutex; ++ struct kobject kobj; + }; + + struct ib_uverbs_event_file { +--- a/drivers/infiniband/core/uverbs_main.c ++++ b/drivers/infiniband/core/uverbs_main.c +@@ -119,14 +119,18 @@ static ssize_t (*uverbs_cmd_table[])(str + static void ib_uverbs_add_one(struct ib_device *device); + static void ib_uverbs_remove_one(struct ib_device *device); + +-static void ib_uverbs_release_dev(struct kref *ref) ++static void ib_uverbs_release_dev(struct kobject *kobj) + { + struct ib_uverbs_device *dev = +- container_of(ref, struct ib_uverbs_device, ref); ++ container_of(kobj, struct ib_uverbs_device, kobj); + +- complete(&dev->comp); ++ kfree(dev); + } + ++static struct kobj_type ib_uverbs_dev_ktype = { ++ .release = ib_uverbs_release_dev, ++}; ++ + static void ib_uverbs_release_event_file(struct kref *ref) + { + struct ib_uverbs_event_file *file = +@@ -282,13 +286,19 @@ static int ib_uverbs_cleanup_ucontext(st + return context->device->dealloc_ucontext(context); + } + ++static void ib_uverbs_comp_dev(struct ib_uverbs_device *dev) ++{ ++ complete(&dev->comp); ++} ++ + static void ib_uverbs_release_file(struct kref *ref) + { + struct ib_uverbs_file *file = + container_of(ref, struct ib_uverbs_file, ref); + + module_put(file->device->ib_dev->owner); +- kref_put(&file->device->ref, ib_uverbs_release_dev); ++ if (atomic_dec_and_test(&file->device->refcount)) ++ ib_uverbs_comp_dev(file->device); + + kfree(file); + } +@@ -629,9 +639,7 @@ static int ib_uverbs_open(struct inode * + int ret; + + dev = container_of(inode->i_cdev, struct ib_uverbs_device, cdev); +- if (dev) +- kref_get(&dev->ref); +- else ++ if (!atomic_inc_not_zero(&dev->refcount)) + return -ENXIO; + + if (!try_module_get(dev->ib_dev->owner)) { +@@ -652,6 +660,7 @@ static int ib_uverbs_open(struct inode * + mutex_init(&file->mutex); + + filp->private_data = file; ++ kobject_get(&dev->kobj); + + return nonseekable_open(inode, filp); + +@@ -659,13 +668,16 @@ err_module: + module_put(dev->ib_dev->owner); + + err: +- kref_put(&dev->ref, ib_uverbs_release_dev); ++ if (atomic_dec_and_test(&dev->refcount)) ++ ib_uverbs_comp_dev(dev); ++ + return ret; + } + + static int ib_uverbs_close(struct inode *inode, struct file *filp) + { + struct ib_uverbs_file *file = filp->private_data; ++ struct ib_uverbs_device *dev = file->device; + + ib_uverbs_cleanup_ucontext(file, file->ucontext); + +@@ -673,6 +685,7 @@ static int ib_uverbs_close(struct inode + kref_put(&file->async_file->ref, ib_uverbs_release_event_file); + + kref_put(&file->ref, ib_uverbs_release_file); ++ kobject_put(&dev->kobj); + + return 0; + } +@@ -768,10 +781,11 @@ static void ib_uverbs_add_one(struct ib_ + if (!uverbs_dev) + return; + +- kref_init(&uverbs_dev->ref); ++ atomic_set(&uverbs_dev->refcount, 1); + init_completion(&uverbs_dev->comp); + uverbs_dev->xrcd_tree = RB_ROOT; + mutex_init(&uverbs_dev->xrcd_tree_mutex); ++ kobject_init(&uverbs_dev->kobj, &ib_uverbs_dev_ktype); + + spin_lock(&map_lock); + devnum = find_first_zero_bit(dev_map, IB_UVERBS_MAX_DEVICES); +@@ -798,6 +812,7 @@ static void ib_uverbs_add_one(struct ib_ + cdev_init(&uverbs_dev->cdev, NULL); + uverbs_dev->cdev.owner = THIS_MODULE; + uverbs_dev->cdev.ops = device->mmap ? &uverbs_mmap_fops : &uverbs_fops; ++ uverbs_dev->cdev.kobj.parent = &uverbs_dev->kobj; + kobject_set_name(&uverbs_dev->cdev.kobj, "uverbs%d", uverbs_dev->devnum); + if (cdev_add(&uverbs_dev->cdev, base, 1)) + goto err_cdev; +@@ -828,9 +843,10 @@ err_cdev: + clear_bit(devnum, overflow_map); + + err: +- kref_put(&uverbs_dev->ref, ib_uverbs_release_dev); ++ if (atomic_dec_and_test(&uverbs_dev->refcount)) ++ ib_uverbs_comp_dev(uverbs_dev); + wait_for_completion(&uverbs_dev->comp); +- kfree(uverbs_dev); ++ kobject_put(&uverbs_dev->kobj); + return; + } + +@@ -850,9 +866,10 @@ static void ib_uverbs_remove_one(struct + else + clear_bit(uverbs_dev->devnum - IB_UVERBS_MAX_DEVICES, overflow_map); + +- kref_put(&uverbs_dev->ref, ib_uverbs_release_dev); ++ if (atomic_dec_and_test(&uverbs_dev->refcount)) ++ ib_uverbs_comp_dev(uverbs_dev); + wait_for_completion(&uverbs_dev->comp); +- kfree(uverbs_dev); ++ kobject_put(&uverbs_dev->kobj); + } + + static char *uverbs_devnode(struct device *dev, umode_t *mode) diff --git a/queue-3.10/ib-uverbs-reject-invalid-or-unknown-opcodes.patch b/queue-3.10/ib-uverbs-reject-invalid-or-unknown-opcodes.patch new file mode 100644 index 00000000000..21f5b9c6b3a --- /dev/null +++ b/queue-3.10/ib-uverbs-reject-invalid-or-unknown-opcodes.patch @@ -0,0 +1,52 @@ +From b632ffa7cee439ba5dce3b3bc4a5cbe2b3e20133 Mon Sep 17 00:00:00 2001 +From: Christoph Hellwig +Date: Wed, 26 Aug 2015 11:00:37 +0200 +Subject: IB/uverbs: reject invalid or unknown opcodes + +From: Christoph Hellwig + +commit b632ffa7cee439ba5dce3b3bc4a5cbe2b3e20133 upstream. + +We have many WR opcodes that are only supported in kernel space +and/or require optional information to be copied into the WR +structure. Reject all those not explicitly handled so that we +can't pass invalid information to drivers. + +Signed-off-by: Christoph Hellwig +Reviewed-by: Jason Gunthorpe +Reviewed-by: Sagi Grimberg +Signed-off-by: Doug Ledford +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/infiniband/core/uverbs_cmd.c | 10 +++++++++- + 1 file changed, 9 insertions(+), 1 deletion(-) + +--- a/drivers/infiniband/core/uverbs_cmd.c ++++ b/drivers/infiniband/core/uverbs_cmd.c +@@ -2106,6 +2106,12 @@ ssize_t ib_uverbs_post_send(struct ib_uv + next->send_flags = user_wr->send_flags; + + if (is_ud) { ++ if (next->opcode != IB_WR_SEND && ++ next->opcode != IB_WR_SEND_WITH_IMM) { ++ ret = -EINVAL; ++ goto out_put; ++ } ++ + next->wr.ud.ah = idr_read_ah(user_wr->wr.ud.ah, + file->ucontext); + if (!next->wr.ud.ah) { +@@ -2142,9 +2148,11 @@ ssize_t ib_uverbs_post_send(struct ib_uv + user_wr->wr.atomic.compare_add; + next->wr.atomic.swap = user_wr->wr.atomic.swap; + next->wr.atomic.rkey = user_wr->wr.atomic.rkey; ++ case IB_WR_SEND: + break; + default: +- break; ++ ret = -EINVAL; ++ goto out_put; + } + } + diff --git a/queue-3.10/series b/queue-3.10/series index e2f12d5f334..2f7c426f79d 100644 --- a/queue-3.10/series +++ b/queue-3.10/series @@ -21,3 +21,10 @@ fs-if-a-coredump-already-exists-unlink-and-recreate-with-o_excl.patch mmc-core-fix-race-condition-in-mmc_wait_data_done.patch md-raid10-always-set-reshape_safe-when-initializing-reshape_position.patch xen-gntdev-convert-priv-lock-to-a-mutex.patch +hfs-fix-b-tree-corruption-after-insertion-at-position-0.patch +ib-uverbs-reject-invalid-or-unknown-opcodes.patch +ib-uverbs-fix-race-between-ib_uverbs_open-and-remove_one.patch +ib-mlx4-forbid-using-sysfs-to-change-roce-pkeys.patch +ib-mlx4-use-correct-sl-on-ah-query-under-roce.patch +stmmac-fix-check-for-phydev-being-open.patch +hfs-hfsplus-cache-pages-correctly-between-bnode_create-and-bnode_free.patch diff --git a/queue-3.10/stmmac-fix-check-for-phydev-being-open.patch b/queue-3.10/stmmac-fix-check-for-phydev-being-open.patch new file mode 100644 index 00000000000..3bb50f6145f --- /dev/null +++ b/queue-3.10/stmmac-fix-check-for-phydev-being-open.patch @@ -0,0 +1,43 @@ +From dfc50fcaad574e5c8c85cbc83eca1426b2413fa4 Mon Sep 17 00:00:00 2001 +From: Alexey Brodkin +Date: Wed, 9 Sep 2015 18:01:08 +0300 +Subject: stmmac: fix check for phydev being open + +From: Alexey Brodkin + +commit dfc50fcaad574e5c8c85cbc83eca1426b2413fa4 upstream. + +Current check of phydev with IS_ERR(phydev) may make not much sense +because of_phy_connect() returns NULL on failure instead of error value. + +Still for checking result of phy_connect() IS_ERR() makes perfect sense. + +So let's use combined check IS_ERR_OR_NULL() that covers both cases. + +Cc: Sergei Shtylyov +Cc: Giuseppe Cavallaro +Cc: linux-kernel@vger.kernel.org +Cc: David Miller +Signed-off-by: Alexey Brodkin +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c ++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +@@ -834,8 +834,11 @@ static int stmmac_init_phy(struct net_de + + phydev = phy_connect(dev, phy_id_fmt, &stmmac_adjust_link, interface); + +- if (IS_ERR(phydev)) { ++ if (IS_ERR_OR_NULL(phydev)) { + pr_err("%s: Could not attach to PHY\n", dev->name); ++ if (!phydev) ++ return -ENODEV; ++ + return PTR_ERR(phydev); + } +