From bfdc6cd9565086cdfd349e22a029f383dfa21834 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Sun, 15 Jul 2018 13:41:31 +0200 Subject: [PATCH] 3.18-stable patches added patches: loop-add-recursion-validation-to-loop_change_fd.patch loop-remember-whether-sysfs_create_group-was-done.patch netfilter-x_tables-initialise-match-target-check-parameter-struct.patch pm-hibernate-fix-oops-at-snapshot_write.patch rdma-ucm-mark-ucm-interface-as-broken.patch --- ...cursion-validation-to-loop_change_fd.patch | 143 ++++++++++++++++++ ...-whether-sysfs_create_group-was-done.patch | 65 ++++++++ ...-match-target-check-parameter-struct.patch | 70 +++++++++ ...hibernate-fix-oops-at-snapshot_write.patch | 38 +++++ ...dma-ucm-mark-ucm-interface-as-broken.patch | 66 ++++++++ queue-3.18/series | 5 + 6 files changed, 387 insertions(+) create mode 100644 queue-3.18/loop-add-recursion-validation-to-loop_change_fd.patch create mode 100644 queue-3.18/loop-remember-whether-sysfs_create_group-was-done.patch create mode 100644 queue-3.18/netfilter-x_tables-initialise-match-target-check-parameter-struct.patch create mode 100644 queue-3.18/pm-hibernate-fix-oops-at-snapshot_write.patch create mode 100644 queue-3.18/rdma-ucm-mark-ucm-interface-as-broken.patch diff --git a/queue-3.18/loop-add-recursion-validation-to-loop_change_fd.patch b/queue-3.18/loop-add-recursion-validation-to-loop_change_fd.patch new file mode 100644 index 00000000000..2c31aa1455b --- /dev/null +++ b/queue-3.18/loop-add-recursion-validation-to-loop_change_fd.patch @@ -0,0 +1,143 @@ +From d2ac838e4cd7e5e9891ecc094d626734b0245c99 Mon Sep 17 00:00:00 2001 +From: Theodore Ts'o +Date: Mon, 7 May 2018 11:37:58 -0400 +Subject: loop: add recursion validation to LOOP_CHANGE_FD + +From: Theodore Ts'o + +commit d2ac838e4cd7e5e9891ecc094d626734b0245c99 upstream. + +Refactor the validation code used in LOOP_SET_FD so it is also used in +LOOP_CHANGE_FD. Otherwise it is possible to construct a set of loop +devices that all refer to each other. This can lead to a infinite +loop in starting with "while (is_loop_device(f)) .." in loop_set_fd(). + +Fix this by refactoring out the validation code and using it for +LOOP_CHANGE_FD as well as LOOP_SET_FD. + +Reported-by: syzbot+4349872271ece473a7c91190b68b4bac7c5dbc87@syzkaller.appspotmail.com +Reported-by: syzbot+40bd32c4d9a3cc12a339@syzkaller.appspotmail.com +Reported-by: syzbot+769c54e66f994b041be7@syzkaller.appspotmail.com +Reported-by: syzbot+0a89a9ce473936c57065@syzkaller.appspotmail.com +Signed-off-by: Theodore Ts'o +Signed-off-by: Jens Axboe +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/block/loop.c | 68 ++++++++++++++++++++++++++++----------------------- + 1 file changed, 38 insertions(+), 30 deletions(-) + +--- a/drivers/block/loop.c ++++ b/drivers/block/loop.c +@@ -628,6 +628,36 @@ out: + } + + ++static inline int is_loop_device(struct file *file) ++{ ++ struct inode *i = file->f_mapping->host; ++ ++ return i && S_ISBLK(i->i_mode) && MAJOR(i->i_rdev) == LOOP_MAJOR; ++} ++ ++static int loop_validate_file(struct file *file, struct block_device *bdev) ++{ ++ struct inode *inode = file->f_mapping->host; ++ struct file *f = file; ++ ++ /* Avoid recursion */ ++ while (is_loop_device(f)) { ++ struct loop_device *l; ++ ++ if (f->f_mapping->host->i_bdev == bdev) ++ return -EBADF; ++ ++ l = f->f_mapping->host->i_bdev->bd_disk->private_data; ++ if (l->lo_state == Lo_unbound) { ++ return -EINVAL; ++ } ++ f = l->lo_backing_file; ++ } ++ if (!S_ISREG(inode->i_mode) && !S_ISBLK(inode->i_mode)) ++ return -EINVAL; ++ return 0; ++} ++ + /* + * loop_change_fd switched the backing store of a loopback device to + * a new file. This is useful for operating system installers to free up +@@ -657,14 +687,15 @@ static int loop_change_fd(struct loop_de + if (!file) + goto out; + ++ error = loop_validate_file(file, bdev); ++ if (error) ++ goto out_putf; ++ + inode = file->f_mapping->host; + old_file = lo->lo_backing_file; + + error = -EINVAL; + +- if (!S_ISREG(inode->i_mode) && !S_ISBLK(inode->i_mode)) +- goto out_putf; +- + /* size of the new backing store needs to be the same */ + if (get_loop_size(lo, file) != get_loop_size(lo, old_file)) + goto out_putf; +@@ -685,13 +716,6 @@ static int loop_change_fd(struct loop_de + return error; + } + +-static inline int is_loop_device(struct file *file) +-{ +- struct inode *i = file->f_mapping->host; +- +- return i && S_ISBLK(i->i_mode) && MAJOR(i->i_rdev) == LOOP_MAJOR; +-} +- + /* loop sysfs attributes */ + + static ssize_t loop_attr_show(struct device *dev, char *page, +@@ -823,7 +847,7 @@ static void loop_config_discard(struct l + static int loop_set_fd(struct loop_device *lo, fmode_t mode, + struct block_device *bdev, unsigned int arg) + { +- struct file *file, *f; ++ struct file *file; + struct inode *inode; + struct address_space *mapping; + unsigned lo_blocksize; +@@ -843,29 +867,13 @@ static int loop_set_fd(struct loop_devic + if (lo->lo_state != Lo_unbound) + goto out_putf; + +- /* Avoid recursion */ +- f = file; +- while (is_loop_device(f)) { +- struct loop_device *l; +- +- if (f->f_mapping->host->i_bdev == bdev) +- goto out_putf; +- +- l = f->f_mapping->host->i_bdev->bd_disk->private_data; +- if (l->lo_state == Lo_unbound) { +- error = -EINVAL; +- goto out_putf; +- } +- f = l->lo_backing_file; +- } ++ error = loop_validate_file(file, bdev); ++ if (error) ++ goto out_putf; + + mapping = file->f_mapping; + inode = mapping->host; + +- error = -EINVAL; +- if (!S_ISREG(inode->i_mode) && !S_ISBLK(inode->i_mode)) +- goto out_putf; +- + if (!(file->f_mode & FMODE_WRITE) || !(mode & FMODE_WRITE) || + !file->f_op->write) + lo_flags |= LO_FLAGS_READ_ONLY; diff --git a/queue-3.18/loop-remember-whether-sysfs_create_group-was-done.patch b/queue-3.18/loop-remember-whether-sysfs_create_group-was-done.patch new file mode 100644 index 00000000000..45a200fc036 --- /dev/null +++ b/queue-3.18/loop-remember-whether-sysfs_create_group-was-done.patch @@ -0,0 +1,65 @@ +From d3349b6b3c373ac1fbfb040b810fcee5e2adc7e0 Mon Sep 17 00:00:00 2001 +From: Tetsuo Handa +Date: Fri, 4 May 2018 10:58:09 -0600 +Subject: loop: remember whether sysfs_create_group() was done + +From: Tetsuo Handa + +commit d3349b6b3c373ac1fbfb040b810fcee5e2adc7e0 upstream. + +syzbot is hitting WARN() triggered by memory allocation fault +injection [1] because loop module is calling sysfs_remove_group() +when sysfs_create_group() failed. +Fix this by remembering whether sysfs_create_group() succeeded. + +[1] https://syzkaller.appspot.com/bug?id=3f86c0edf75c86d2633aeb9dd69eccc70bc7e90b + +Signed-off-by: Tetsuo Handa +Reported-by: syzbot +Reviewed-by: Greg Kroah-Hartman + +Renamed sysfs_ready -> sysfs_inited. + +Signed-off-by: Jens Axboe +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/block/loop.c | 11 ++++++----- + drivers/block/loop.h | 1 + + 2 files changed, 7 insertions(+), 5 deletions(-) + +--- a/drivers/block/loop.c ++++ b/drivers/block/loop.c +@@ -803,16 +803,17 @@ static struct attribute_group loop_attri + .attrs= loop_attrs, + }; + +-static int loop_sysfs_init(struct loop_device *lo) ++static void loop_sysfs_init(struct loop_device *lo) + { +- return sysfs_create_group(&disk_to_dev(lo->lo_disk)->kobj, +- &loop_attribute_group); ++ lo->sysfs_inited = !sysfs_create_group(&disk_to_dev(lo->lo_disk)->kobj, ++ &loop_attribute_group); + } + + static void loop_sysfs_exit(struct loop_device *lo) + { +- sysfs_remove_group(&disk_to_dev(lo->lo_disk)->kobj, +- &loop_attribute_group); ++ if (lo->sysfs_inited) ++ sysfs_remove_group(&disk_to_dev(lo->lo_disk)->kobj, ++ &loop_attribute_group); + } + + static void loop_config_discard(struct loop_device *lo) +--- a/drivers/block/loop.h ++++ b/drivers/block/loop.h +@@ -60,6 +60,7 @@ struct loop_device { + wait_queue_head_t lo_event; + /* wait queue for incoming requests */ + wait_queue_head_t lo_req_wait; ++ bool sysfs_inited; + + struct request_queue *lo_queue; + struct gendisk *lo_disk; diff --git a/queue-3.18/netfilter-x_tables-initialise-match-target-check-parameter-struct.patch b/queue-3.18/netfilter-x_tables-initialise-match-target-check-parameter-struct.patch new file mode 100644 index 00000000000..4dc9636cb02 --- /dev/null +++ b/queue-3.18/netfilter-x_tables-initialise-match-target-check-parameter-struct.patch @@ -0,0 +1,70 @@ +From c568503ef02030f169c9e19204def610a3510918 Mon Sep 17 00:00:00 2001 +From: Florian Westphal +Date: Thu, 7 Jun 2018 21:34:43 +0200 +Subject: netfilter: x_tables: initialise match/target check parameter struct + +From: Florian Westphal + +commit c568503ef02030f169c9e19204def610a3510918 upstream. + +syzbot reports following splat: + +BUG: KMSAN: uninit-value in ebt_stp_mt_check+0x24b/0x450 + net/bridge/netfilter/ebt_stp.c:162 + ebt_stp_mt_check+0x24b/0x450 net/bridge/netfilter/ebt_stp.c:162 + xt_check_match+0x1438/0x1650 net/netfilter/x_tables.c:506 + ebt_check_match net/bridge/netfilter/ebtables.c:372 [inline] + ebt_check_entry net/bridge/netfilter/ebtables.c:702 [inline] + +The uninitialised access is + xt_mtchk_param->nft_compat + +... which should be set to 0. +Fix it by zeroing the struct beforehand, same for tgchk. + +ip(6)tables targetinfo uses c99-style initialiser, so no change +needed there. + +Reported-by: syzbot+da4494182233c23a5fcf@syzkaller.appspotmail.com +Fixes: 55917a21d0cc0 ("netfilter: x_tables: add context to know if extension runs from nft_compat") +Signed-off-by: Florian Westphal +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Greg Kroah-Hartman + +--- + net/bridge/netfilter/ebtables.c | 2 ++ + net/ipv4/netfilter/ip_tables.c | 1 + + net/ipv6/netfilter/ip6_tables.c | 1 + + 3 files changed, 4 insertions(+) + +--- a/net/bridge/netfilter/ebtables.c ++++ b/net/bridge/netfilter/ebtables.c +@@ -699,6 +699,8 @@ ebt_check_entry(struct ebt_entry *e, str + } + i = 0; + ++ memset(&mtpar, 0, sizeof(mtpar)); ++ memset(&tgpar, 0, sizeof(tgpar)); + mtpar.net = tgpar.net = net; + mtpar.table = tgpar.table = name; + mtpar.entryinfo = tgpar.entryinfo = e; +--- a/net/ipv4/netfilter/ip_tables.c ++++ b/net/ipv4/netfilter/ip_tables.c +@@ -651,6 +651,7 @@ find_check_entry(struct ipt_entry *e, st + struct xt_entry_match *ematch; + + j = 0; ++ memset(&mtpar, 0, sizeof(mtpar)); + mtpar.net = net; + mtpar.table = name; + mtpar.entryinfo = &e->ip; +--- a/net/ipv6/netfilter/ip6_tables.c ++++ b/net/ipv6/netfilter/ip6_tables.c +@@ -662,6 +662,7 @@ find_check_entry(struct ip6t_entry *e, s + struct xt_entry_match *ematch; + + j = 0; ++ memset(&mtpar, 0, sizeof(mtpar)); + mtpar.net = net; + mtpar.table = name; + mtpar.entryinfo = &e->ipv6; diff --git a/queue-3.18/pm-hibernate-fix-oops-at-snapshot_write.patch b/queue-3.18/pm-hibernate-fix-oops-at-snapshot_write.patch new file mode 100644 index 00000000000..24c9c60c93d --- /dev/null +++ b/queue-3.18/pm-hibernate-fix-oops-at-snapshot_write.patch @@ -0,0 +1,38 @@ +From fc14eebfc20854a38fd9f1d93a42b1783dad4d17 Mon Sep 17 00:00:00 2001 +From: Tetsuo Handa +Date: Sat, 26 May 2018 09:59:36 +0900 +Subject: PM / hibernate: Fix oops at snapshot_write() + +From: Tetsuo Handa + +commit fc14eebfc20854a38fd9f1d93a42b1783dad4d17 upstream. + +syzbot is reporting NULL pointer dereference at snapshot_write() [1]. +This is because data->handle is zero-cleared by ioctl(SNAPSHOT_FREE). +Fix this by checking data_of(data->handle) != NULL before using it. + +[1] https://syzkaller.appspot.com/bug?id=828a3c71bd344a6de8b6a31233d51a72099f27fd + +Signed-off-by: Tetsuo Handa +Reported-by: syzbot +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/power/user.c | 5 +++++ + 1 file changed, 5 insertions(+) + +--- a/kernel/power/user.c ++++ b/kernel/power/user.c +@@ -184,6 +184,11 @@ static ssize_t snapshot_write(struct fil + res = PAGE_SIZE - pg_offp; + } + ++ if (!data_of(data->handle)) { ++ res = -EINVAL; ++ goto unlock; ++ } ++ + res = simple_write_to_buffer(data_of(data->handle), res, &pg_offp, + buf, count); + if (res > 0) diff --git a/queue-3.18/rdma-ucm-mark-ucm-interface-as-broken.patch b/queue-3.18/rdma-ucm-mark-ucm-interface-as-broken.patch new file mode 100644 index 00000000000..4ce1a30dd97 --- /dev/null +++ b/queue-3.18/rdma-ucm-mark-ucm-interface-as-broken.patch @@ -0,0 +1,66 @@ +From 7a8690ed6f5346f6738971892205e91d39b6b901 Mon Sep 17 00:00:00 2001 +From: Leon Romanovsky +Date: Wed, 23 May 2018 08:22:11 +0300 +Subject: RDMA/ucm: Mark UCM interface as BROKEN + +From: Leon Romanovsky + +commit 7a8690ed6f5346f6738971892205e91d39b6b901 upstream. + +In commit 357d23c811a7 ("Remove the obsolete libibcm library") +in rdma-core [1], we removed obsolete library which used the +/dev/infiniband/ucmX interface. + +Following multiple syzkaller reports about non-sanitized +user input in the UCMA module, the short audit reveals the same +issues in UCM module too. + +It is better to disable this interface in the kernel, +before syzkaller team invests time and energy to harden +this unused interface. + +[1] https://github.com/linux-rdma/rdma-core/pull/279 + +Signed-off-by: Leon Romanovsky +Signed-off-by: Jason Gunthorpe +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/infiniband/Kconfig | 12 ++++++++++++ + drivers/infiniband/core/Makefile | 4 ++-- + 2 files changed, 14 insertions(+), 2 deletions(-) + +--- a/drivers/infiniband/Kconfig ++++ b/drivers/infiniband/Kconfig +@@ -33,6 +33,18 @@ config INFINIBAND_USER_ACCESS + libibverbs, libibcm and a hardware driver library from + . + ++config INFINIBAND_USER_ACCESS_UCM ++ bool "Userspace CM (UCM, DEPRECATED)" ++ depends on BROKEN ++ depends on INFINIBAND_USER_ACCESS ++ help ++ The UCM module has known security flaws, which no one is ++ interested to fix. The user-space part of this code was ++ dropped from the upstream a long time ago. ++ ++ This option is DEPRECATED and planned to be removed. ++ ++ + config INFINIBAND_USER_MEM + bool + depends on INFINIBAND_USER_ACCESS != n +--- a/drivers/infiniband/core/Makefile ++++ b/drivers/infiniband/core/Makefile +@@ -5,8 +5,8 @@ obj-$(CONFIG_INFINIBAND) += ib_core.o i + ib_cm.o iw_cm.o ib_addr.o \ + $(infiniband-y) + obj-$(CONFIG_INFINIBAND_USER_MAD) += ib_umad.o +-obj-$(CONFIG_INFINIBAND_USER_ACCESS) += ib_uverbs.o ib_ucm.o \ +- $(user_access-y) ++obj-$(CONFIG_INFINIBAND_USER_ACCESS) += ib_uverbs.o $(user_access-y) ++obj-$(CONFIG_INFINIBAND_USER_ACCESS_UCM) += ib_ucm.o $(user_access-y) + + ib_core-y := packer.o ud_header.o verbs.o sysfs.o \ + device.o fmr_pool.o cache.o netlink.o diff --git a/queue-3.18/series b/queue-3.18/series index a354e93887d..7e7d92cb4f7 100644 --- a/queue-3.18/series +++ b/queue-3.18/series @@ -5,3 +5,8 @@ usb-serial-mos7840-fix-status-register-error-handling.patch usb-quirks-add-delay-quirks-for-corsair-strafe.patch xhci-xhci-mem-off-by-one-in-xhci_stream_id_to_ring.patch fix-up-non-directory-creation-in-sgid-directories.patch +netfilter-x_tables-initialise-match-target-check-parameter-struct.patch +loop-add-recursion-validation-to-loop_change_fd.patch +pm-hibernate-fix-oops-at-snapshot_write.patch +rdma-ucm-mark-ucm-interface-as-broken.patch +loop-remember-whether-sysfs_create_group-was-done.patch -- 2.47.3