From: Greg Kroah-Hartman Date: Fri, 15 May 2015 01:57:30 +0000 (-0700) Subject: 3.14-stable patches X-Git-Tag: v3.10.79~26 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=925329c2ae9edcea2eb7f8f8e43c0712edace4eb;p=thirdparty%2Fkernel%2Fstable-queue.git 3.14-stable patches added patches: gpio-sysfs-fix-memory-leaks-and-device-hotplug.patch mnt-fix-fs_fully_visible-to-verify-the-root-directory-is-visible.patch nilfs2-fix-sanity-check-of-btree-level-in-nilfs_btree_root_broken.patch rdma-cma-canonize-ipv4-on-ipv6-sockets-properly.patch --- diff --git a/queue-3.14/gpio-sysfs-fix-memory-leaks-and-device-hotplug.patch b/queue-3.14/gpio-sysfs-fix-memory-leaks-and-device-hotplug.patch new file mode 100644 index 00000000000..e778151b4cf --- /dev/null +++ b/queue-3.14/gpio-sysfs-fix-memory-leaks-and-device-hotplug.patch @@ -0,0 +1,97 @@ +From 483d821108791092798f5d230686868112927044 Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Tue, 21 Apr 2015 17:42:09 +0200 +Subject: gpio: sysfs: fix memory leaks and device hotplug + +From: Johan Hovold + +commit 483d821108791092798f5d230686868112927044 upstream. + +Unregister GPIOs requested through sysfs at chip remove to avoid leaking +the associated memory and sysfs entries. + +The stale sysfs entries prevented the gpio numbers from being exported +when the gpio range was later reused (e.g. at device reconnect). + +This also fixes the related module-reference leak. + +Note that kernfs makes sure that any on-going sysfs operations finish +before the class devices are unregistered and that further accesses +fail. + +The chip exported flag is used to prevent gpiod exports during removal. +This also makes it harder to trigger, but does not fix, the related race +between gpiochip_remove and export_store, which is really a race with +gpiod_request that needs to be addressed separately. + +Also note that this would prevent the crashes (e.g. NULL-dereferences) +at reconnect that affects pre-3.18 kernels, as well as use-after-free on +operations on open attribute files on pre-3.14 kernels (prior to +kernfs). + +Fixes: d8f388d8dc8d ("gpio: sysfs interface") +Signed-off-by: Johan Hovold +Signed-off-by: Linus Walleij +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpio/gpiolib.c | 19 +++++++++++++++++++ + 1 file changed, 19 insertions(+) + +--- a/drivers/gpio/gpiolib.c ++++ b/drivers/gpio/gpiolib.c +@@ -800,6 +800,7 @@ static struct class gpio_class = { + */ + int gpiod_export(struct gpio_desc *desc, bool direction_may_change) + { ++ struct gpio_chip *chip; + unsigned long flags; + int status; + const char *ioname = NULL; +@@ -817,8 +818,16 @@ int gpiod_export(struct gpio_desc *desc, + return -EINVAL; + } + ++ chip = desc->chip; ++ + mutex_lock(&sysfs_lock); + ++ /* check if chip is being removed */ ++ if (!chip || !chip->exported) { ++ status = -ENODEV; ++ goto fail_unlock; ++ } ++ + spin_lock_irqsave(&gpio_lock, flags); + if (!test_bit(FLAG_REQUESTED, &desc->flags) || + test_bit(FLAG_EXPORT, &desc->flags)) { +@@ -1057,12 +1066,15 @@ static void gpiochip_unexport(struct gpi + { + int status; + struct device *dev; ++ struct gpio_desc *desc; ++ unsigned int i; + + mutex_lock(&sysfs_lock); + dev = class_find_device(&gpio_class, NULL, chip, match_export); + if (dev) { + put_device(dev); + device_unregister(dev); ++ /* prevent further gpiod exports */ + chip->exported = false; + status = 0; + } else +@@ -1071,6 +1083,13 @@ static void gpiochip_unexport(struct gpi + + if (status) + chip_dbg(chip, "%s: status %d\n", __func__, status); ++ ++ /* unregister gpiod class devices owned by sysfs */ ++ for (i = 0; i < chip->ngpio; i++) { ++ desc = &chip->desc[i]; ++ if (test_and_clear_bit(FLAG_SYSFS, &desc->flags)) ++ gpiod_free(desc); ++ } + } + + static int __init gpiolib_sysfs_init(void) diff --git a/queue-3.14/mnt-fix-fs_fully_visible-to-verify-the-root-directory-is-visible.patch b/queue-3.14/mnt-fix-fs_fully_visible-to-verify-the-root-directory-is-visible.patch new file mode 100644 index 00000000000..7abb85f06fd --- /dev/null +++ b/queue-3.14/mnt-fix-fs_fully_visible-to-verify-the-root-directory-is-visible.patch @@ -0,0 +1,35 @@ +From 7e96c1b0e0f495c5a7450dc4aa7c9a24ba4305bd Mon Sep 17 00:00:00 2001 +From: "Eric W. Biederman" +Date: Fri, 8 May 2015 16:36:50 -0500 +Subject: mnt: Fix fs_fully_visible to verify the root directory is visible + +From: "Eric W. Biederman" + +commit 7e96c1b0e0f495c5a7450dc4aa7c9a24ba4305bd upstream. + +This fixes a dumb bug in fs_fully_visible that allows proc or sys to +be mounted if there is a bind mount of part of /proc/ or /sys/ visible. + +Reported-by: Eric Windisch +Signed-off-by: "Eric W. Biederman" +Signed-off-by: Greg Kroah-Hartman + +--- + fs/namespace.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +--- a/fs/namespace.c ++++ b/fs/namespace.c +@@ -3025,6 +3025,12 @@ bool fs_fully_visible(struct file_system + if (mnt->mnt.mnt_sb->s_type != type) + continue; + ++ /* This mount is not fully visible if it's root directory ++ * is not the root directory of the filesystem. ++ */ ++ if (mnt->mnt.mnt_root != mnt->mnt.mnt_sb->s_root) ++ continue; ++ + /* This mount is not fully visible if there are any child mounts + * that cover anything except for empty directories. + */ diff --git a/queue-3.14/nilfs2-fix-sanity-check-of-btree-level-in-nilfs_btree_root_broken.patch b/queue-3.14/nilfs2-fix-sanity-check-of-btree-level-in-nilfs_btree_root_broken.patch new file mode 100644 index 00000000000..e99d3f10266 --- /dev/null +++ b/queue-3.14/nilfs2-fix-sanity-check-of-btree-level-in-nilfs_btree_root_broken.patch @@ -0,0 +1,54 @@ +From d8fd150fe3935e1692bf57c66691e17409ebb9c1 Mon Sep 17 00:00:00 2001 +From: Ryusuke Konishi +Date: Tue, 5 May 2015 16:24:00 -0700 +Subject: nilfs2: fix sanity check of btree level in nilfs_btree_root_broken() + +From: Ryusuke Konishi + +commit d8fd150fe3935e1692bf57c66691e17409ebb9c1 upstream. + +The range check for b-tree level parameter in nilfs_btree_root_broken() +is wrong; it accepts the case of "level == NILFS_BTREE_LEVEL_MAX" even +though the level is limited to values in the range of 0 to +(NILFS_BTREE_LEVEL_MAX - 1). + +Since the level parameter is read from storage device and used to index +nilfs_btree_path array whose element count is NILFS_BTREE_LEVEL_MAX, it +can cause memory overrun during btree operations if the boundary value +is set to the level parameter on device. + +This fixes the broken sanity check and adds a comment to clarify that +the upper bound NILFS_BTREE_LEVEL_MAX is exclusive. + +Signed-off-by: Ryusuke Konishi +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + fs/nilfs2/btree.c | 2 +- + include/linux/nilfs2_fs.h | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +--- a/fs/nilfs2/btree.c ++++ b/fs/nilfs2/btree.c +@@ -388,7 +388,7 @@ static int nilfs_btree_root_broken(const + nchildren = nilfs_btree_node_get_nchildren(node); + + if (unlikely(level < NILFS_BTREE_LEVEL_NODE_MIN || +- level > NILFS_BTREE_LEVEL_MAX || ++ level >= NILFS_BTREE_LEVEL_MAX || + nchildren < 0 || + nchildren > NILFS_BTREE_ROOT_NCHILDREN_MAX)) { + pr_crit("NILFS: bad btree root (inode number=%lu): level = %d, flags = 0x%x, nchildren = %d\n", +--- a/include/linux/nilfs2_fs.h ++++ b/include/linux/nilfs2_fs.h +@@ -458,7 +458,7 @@ struct nilfs_btree_node { + /* level */ + #define NILFS_BTREE_LEVEL_DATA 0 + #define NILFS_BTREE_LEVEL_NODE_MIN (NILFS_BTREE_LEVEL_DATA + 1) +-#define NILFS_BTREE_LEVEL_MAX 14 ++#define NILFS_BTREE_LEVEL_MAX 14 /* Max level (exclusive) */ + + /** + * struct nilfs_palloc_group_desc - block group descriptor diff --git a/queue-3.14/rdma-cma-canonize-ipv4-on-ipv6-sockets-properly.patch b/queue-3.14/rdma-cma-canonize-ipv4-on-ipv6-sockets-properly.patch new file mode 100644 index 00000000000..cd8d37f78bf --- /dev/null +++ b/queue-3.14/rdma-cma-canonize-ipv4-on-ipv6-sockets-properly.patch @@ -0,0 +1,82 @@ +From 285214409a9e5fceba2215461b4682b6069d8e77 Mon Sep 17 00:00:00 2001 +From: Jason Gunthorpe +Date: Mon, 20 Apr 2015 14:01:11 -0600 +Subject: RDMA/CMA: Canonize IPv4 on IPV6 sockets properly + +From: Jason Gunthorpe + +commit 285214409a9e5fceba2215461b4682b6069d8e77 upstream. + +When accepting a new IPv4 connect to an IPv6 socket, the CMA tries to +canonize the address family to IPv4, but does not properly process +the listening sockaddr to get the listening port, and does not properly +set the address family of the canonized sockaddr. + +Fixes: e51060f08a61 ("IB: IP address based RDMA connection manager") + +Reported-By: Yotam Kenneth +Signed-off-by: Jason Gunthorpe +Tested-by: Haggai Eran +Signed-off-by: Doug Ledford +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/infiniband/core/cma.c | 27 +++++++++++++++++---------- + 1 file changed, 17 insertions(+), 10 deletions(-) + +--- a/drivers/infiniband/core/cma.c ++++ b/drivers/infiniband/core/cma.c +@@ -859,19 +859,27 @@ static void cma_save_ib_info(struct rdma + memcpy(&ib->sib_addr, &path->dgid, 16); + } + ++static __be16 ss_get_port(const struct sockaddr_storage *ss) ++{ ++ if (ss->ss_family == AF_INET) ++ return ((struct sockaddr_in *)ss)->sin_port; ++ else if (ss->ss_family == AF_INET6) ++ return ((struct sockaddr_in6 *)ss)->sin6_port; ++ BUG(); ++} ++ + static void cma_save_ip4_info(struct rdma_cm_id *id, struct rdma_cm_id *listen_id, + struct cma_hdr *hdr) + { +- struct sockaddr_in *listen4, *ip4; ++ struct sockaddr_in *ip4; + +- listen4 = (struct sockaddr_in *) &listen_id->route.addr.src_addr; + ip4 = (struct sockaddr_in *) &id->route.addr.src_addr; +- ip4->sin_family = listen4->sin_family; ++ ip4->sin_family = AF_INET; + ip4->sin_addr.s_addr = hdr->dst_addr.ip4.addr; +- ip4->sin_port = listen4->sin_port; ++ ip4->sin_port = ss_get_port(&listen_id->route.addr.src_addr); + + ip4 = (struct sockaddr_in *) &id->route.addr.dst_addr; +- ip4->sin_family = listen4->sin_family; ++ ip4->sin_family = AF_INET; + ip4->sin_addr.s_addr = hdr->src_addr.ip4.addr; + ip4->sin_port = hdr->port; + } +@@ -879,16 +887,15 @@ static void cma_save_ip4_info(struct rdm + static void cma_save_ip6_info(struct rdma_cm_id *id, struct rdma_cm_id *listen_id, + struct cma_hdr *hdr) + { +- struct sockaddr_in6 *listen6, *ip6; ++ struct sockaddr_in6 *ip6; + +- listen6 = (struct sockaddr_in6 *) &listen_id->route.addr.src_addr; + ip6 = (struct sockaddr_in6 *) &id->route.addr.src_addr; +- ip6->sin6_family = listen6->sin6_family; ++ ip6->sin6_family = AF_INET6; + ip6->sin6_addr = hdr->dst_addr.ip6; +- ip6->sin6_port = listen6->sin6_port; ++ ip6->sin6_port = ss_get_port(&listen_id->route.addr.src_addr); + + ip6 = (struct sockaddr_in6 *) &id->route.addr.dst_addr; +- ip6->sin6_family = listen6->sin6_family; ++ ip6->sin6_family = AF_INET6; + ip6->sin6_addr = hdr->src_addr.ip6; + ip6->sin6_port = hdr->port; + } diff --git a/queue-3.14/series b/queue-3.14/series index 30531c6f700..f87cabadca4 100644 --- a/queue-3.14/series +++ b/queue-3.14/series @@ -1 +1,5 @@ ocfs2-dlm-fix-race-between-purge-and-get-lock-resource.patch +nilfs2-fix-sanity-check-of-btree-level-in-nilfs_btree_root_broken.patch +rdma-cma-canonize-ipv4-on-ipv6-sockets-properly.patch +gpio-sysfs-fix-memory-leaks-and-device-hotplug.patch +mnt-fix-fs_fully_visible-to-verify-the-root-directory-is-visible.patch