--- /dev/null
+From 9cb2feb4d21d97386eb25c7b67e2793efcc1e70a Mon Sep 17 00:00:00 2001
+From: Stafford Horne <shorne@gmail.com>
+Date: Tue, 8 Jan 2019 22:15:15 +0900
+Subject: arch/openrisc: Fix issues with access_ok()
+
+From: Stafford Horne <shorne@gmail.com>
+
+commit 9cb2feb4d21d97386eb25c7b67e2793efcc1e70a upstream.
+
+The commit 594cc251fdd0 ("make 'user_access_begin()' do 'access_ok()'")
+exposed incorrect implementations of access_ok() macro in several
+architectures. This change fixes 2 issues found in OpenRISC.
+
+OpenRISC was not properly using parenthesis for arguments and also using
+arguments twice. This patch fixes those 2 issues.
+
+I test booted this patch with v5.0-rc1 on qemu and it's working fine.
+
+Cc: Guenter Roeck <linux@roeck-us.net>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Reported-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Stafford Horne <shorne@gmail.com>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Miles Chen <miles.chen@mediatek.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/openrisc/include/asm/uaccess.h | 8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+--- a/arch/openrisc/include/asm/uaccess.h
++++ b/arch/openrisc/include/asm/uaccess.h
+@@ -58,8 +58,12 @@
+ /* Ensure that addr is below task's addr_limit */
+ #define __addr_ok(addr) ((unsigned long) addr < get_fs())
+
+-#define access_ok(type, addr, size) \
+- __range_ok((unsigned long)addr, (unsigned long)size)
++#define access_ok(type, addr, size) \
++({ \
++ unsigned long __ao_addr = (unsigned long)(addr); \
++ unsigned long __ao_size = (unsigned long)(size); \
++ __range_ok(__ao_addr, __ao_size); \
++})
+
+ /*
+ * These are the main single-value transfer routines. They automatically
--- /dev/null
+From 62fdaa52a3d00a875da771719b6dc537ca79fce1 Mon Sep 17 00:00:00 2001
+From: Qu Wenruo <wqu@suse.com>
+Date: Thu, 22 Aug 2019 10:14:15 +0800
+Subject: btrfs: Detect unbalanced tree with empty leaf before crashing btree operations
+
+From: Qu Wenruo <wqu@suse.com>
+
+commit 62fdaa52a3d00a875da771719b6dc537ca79fce1 upstream.
+
+[BUG]
+With crafted image, btrfs will panic at btree operations:
+
+ kernel BUG at fs/btrfs/ctree.c:3894!
+ invalid opcode: 0000 [#1] SMP PTI
+ CPU: 0 PID: 1138 Comm: btrfs-transacti Not tainted 5.0.0-rc8+ #9
+ RIP: 0010:__push_leaf_left+0x6b6/0x6e0
+ RSP: 0018:ffffc0bd4128b990 EFLAGS: 00010246
+ RAX: 0000000000000000 RBX: ffffa0a4ab8f0e38 RCX: 0000000000000000
+ RDX: ffffa0a280000000 RSI: 0000000000000000 RDI: ffffa0a4b3814000
+ RBP: ffffc0bd4128ba38 R08: 0000000000001000 R09: ffffc0bd4128b948
+ R10: 0000000000000000 R11: 0000000000000000 R12: 0000000000000240
+ R13: ffffa0a4b556fb60 R14: ffffa0a4ab8f0af0 R15: ffffa0a4ab8f0af0
+ FS: 0000000000000000(0000) GS:ffffa0a4b7a00000(0000) knlGS:0000000000000000
+ CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+ CR2: 00007f2461c80020 CR3: 000000022b32a006 CR4: 00000000000206f0
+ Call Trace:
+ ? _cond_resched+0x1a/0x50
+ push_leaf_left+0x179/0x190
+ btrfs_del_items+0x316/0x470
+ btrfs_del_csums+0x215/0x3a0
+ __btrfs_free_extent.isra.72+0x5a7/0xbe0
+ __btrfs_run_delayed_refs+0x539/0x1120
+ btrfs_run_delayed_refs+0xdb/0x1b0
+ btrfs_commit_transaction+0x52/0x950
+ ? start_transaction+0x94/0x450
+ transaction_kthread+0x163/0x190
+ kthread+0x105/0x140
+ ? btrfs_cleanup_transaction+0x560/0x560
+ ? kthread_destroy_worker+0x50/0x50
+ ret_from_fork+0x35/0x40
+ Modules linked in:
+ ---[ end trace c2425e6e89b5558f ]---
+
+[CAUSE]
+The offending csum tree looks like this:
+
+ checksum tree key (CSUM_TREE ROOT_ITEM 0)
+ node 29741056 level 1 items 14 free 107 generation 19 owner CSUM_TREE
+ ...
+ key (EXTENT_CSUM EXTENT_CSUM 85975040) block 29630464 gen 17
+ key (EXTENT_CSUM EXTENT_CSUM 89911296) block 29642752 gen 17 <<<
+ key (EXTENT_CSUM EXTENT_CSUM 92274688) block 29646848 gen 17
+ ...
+
+ leaf 29630464 items 6 free space 1 generation 17 owner CSUM_TREE
+ item 0 key (EXTENT_CSUM EXTENT_CSUM 85975040) itemoff 3987 itemsize 8
+ range start 85975040 end 85983232 length 8192
+ ...
+ leaf 29642752 items 0 free space 3995 generation 17 owner 0
+ ^ empty leaf invalid owner ^
+
+ leaf 29646848 items 1 free space 602 generation 17 owner CSUM_TREE
+ item 0 key (EXTENT_CSUM EXTENT_CSUM 92274688) itemoff 627 itemsize 3368
+ range start 92274688 end 95723520 length 3448832
+
+So we have a corrupted csum tree where one tree leaf is completely
+empty, causing unbalanced btree, thus leading to unexpected btree
+balance error.
+
+[FIX]
+For this particular case, we handle it in two directions to catch it:
+- Check if the tree block is empty through btrfs_verify_level_key()
+ So that invalid tree blocks won't be read out through
+ btrfs_search_slot() and its variants.
+
+- Check 0 tree owner in tree checker
+ NO tree is using 0 as its tree owner, detect it and reject at tree
+ block read time.
+
+Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=202821
+Reviewed-by: Nikolay Borisov <nborisov@suse.com>
+Signed-off-by: Qu Wenruo <wqu@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Vikash Bansal <bvikas@vmware.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/btrfs/disk-io.c | 10 ++++++++++
+ fs/btrfs/tree-checker.c | 6 ++++++
+ 2 files changed, 16 insertions(+)
+
+--- a/fs/btrfs/disk-io.c
++++ b/fs/btrfs/disk-io.c
+@@ -438,6 +438,16 @@ int btrfs_verify_level_key(struct btrfs_
+ */
+ if (btrfs_header_generation(eb) > fs_info->last_trans_committed)
+ return 0;
++
++ /* We have @first_key, so this @eb must have at least one item */
++ if (btrfs_header_nritems(eb) == 0) {
++ btrfs_err(fs_info,
++ "invalid tree nritems, bytenr=%llu nritems=0 expect >0",
++ eb->start);
++ WARN_ON(IS_ENABLED(CONFIG_BTRFS_DEBUG));
++ return -EUCLEAN;
++ }
++
+ if (found_level)
+ btrfs_node_key_to_cpu(eb, &found_key, 0);
+ else
+--- a/fs/btrfs/tree-checker.c
++++ b/fs/btrfs/tree-checker.c
+@@ -169,6 +169,12 @@ static int check_extent_data_item(struct
+ btrfs_file_extent_ram_bytes(leaf, fi));
+ return -EUCLEAN;
+ }
++ /* Unknown tree */
++ if (owner == 0) {
++ generic_err(leaf, 0,
++ "invalid owner, root 0 is not defined");
++ return -EUCLEAN;
++ }
+ return 0;
+ }
+
--- /dev/null
+From 09ba3bc9dd150457c506e4661380a6183af651c1 Mon Sep 17 00:00:00 2001
+From: Anand Jain <anand.jain@oracle.com>
+Date: Sat, 19 Jan 2019 14:48:55 +0800
+Subject: btrfs: merge btrfs_find_device and find_device
+
+From: Anand Jain <anand.jain@oracle.com>
+
+commit 09ba3bc9dd150457c506e4661380a6183af651c1 upstream.
+
+Both btrfs_find_device() and find_device() does the same thing except
+that the latter does not take the seed device onto account in the device
+scanning context. We can merge them.
+
+Signed-off-by: Anand Jain <anand.jain@oracle.com>
+Reviewed-by: David Sterba <dsterba@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+[4.19.y backport notes:
+Vikash : - To apply this patch, a portion of commit e4319cd9cace
+ was used to change the first argument of function
+ "btrfs_find_device" from "struct btrfs_fs_info" to
+ "struct btrfs_fs_devices".
+Signed-off-by: Vikash Bansal <bvikas@vmware.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/btrfs/dev-replace.c | 8 ++--
+ fs/btrfs/ioctl.c | 5 +-
+ fs/btrfs/scrub.c | 4 +-
+ fs/btrfs/volumes.c | 84 ++++++++++++++++++++++++-------------------------
+ fs/btrfs/volumes.h | 4 +-
+ 5 files changed, 53 insertions(+), 52 deletions(-)
+
+--- a/fs/btrfs/dev-replace.c
++++ b/fs/btrfs/dev-replace.c
+@@ -112,11 +112,11 @@ no_valid_dev_replace_entry_found:
+ break;
+ case BTRFS_IOCTL_DEV_REPLACE_STATE_STARTED:
+ case BTRFS_IOCTL_DEV_REPLACE_STATE_SUSPENDED:
+- dev_replace->srcdev = btrfs_find_device(fs_info, src_devid,
+- NULL, NULL);
+- dev_replace->tgtdev = btrfs_find_device(fs_info,
++ dev_replace->srcdev = btrfs_find_device(fs_info->fs_devices,
++ src_devid, NULL, NULL, true);
++ dev_replace->tgtdev = btrfs_find_device(fs_info->fs_devices,
+ BTRFS_DEV_REPLACE_DEVID,
+- NULL, NULL);
++ NULL, NULL, true);
+ /*
+ * allow 'btrfs dev replace_cancel' if src/tgt device is
+ * missing
+--- a/fs/btrfs/ioctl.c
++++ b/fs/btrfs/ioctl.c
+@@ -1642,7 +1642,7 @@ static noinline int btrfs_ioctl_resize(s
+ btrfs_info(fs_info, "resizing devid %llu", devid);
+ }
+
+- device = btrfs_find_device(fs_info, devid, NULL, NULL);
++ device = btrfs_find_device(fs_info->fs_devices, devid, NULL, NULL, true);
+ if (!device) {
+ btrfs_info(fs_info, "resizer unable to find device %llu",
+ devid);
+@@ -3178,7 +3178,8 @@ static long btrfs_ioctl_dev_info(struct
+ s_uuid = di_args->uuid;
+
+ rcu_read_lock();
+- dev = btrfs_find_device(fs_info, di_args->devid, s_uuid, NULL);
++ dev = btrfs_find_device(fs_info->fs_devices, di_args->devid, s_uuid,
++ NULL, true);
+
+ if (!dev) {
+ ret = -ENODEV;
+--- a/fs/btrfs/scrub.c
++++ b/fs/btrfs/scrub.c
+@@ -3835,7 +3835,7 @@ int btrfs_scrub_dev(struct btrfs_fs_info
+ return PTR_ERR(sctx);
+
+ mutex_lock(&fs_info->fs_devices->device_list_mutex);
+- dev = btrfs_find_device(fs_info, devid, NULL, NULL);
++ dev = btrfs_find_device(fs_info->fs_devices, devid, NULL, NULL, true);
+ if (!dev || (test_bit(BTRFS_DEV_STATE_MISSING, &dev->dev_state) &&
+ !is_dev_replace)) {
+ mutex_unlock(&fs_info->fs_devices->device_list_mutex);
+@@ -4019,7 +4019,7 @@ int btrfs_scrub_progress(struct btrfs_fs
+ struct scrub_ctx *sctx = NULL;
+
+ mutex_lock(&fs_info->fs_devices->device_list_mutex);
+- dev = btrfs_find_device(fs_info, devid, NULL, NULL);
++ dev = btrfs_find_device(fs_info->fs_devices, devid, NULL, NULL, true);
+ if (dev)
+ sctx = dev->scrub_ctx;
+ if (sctx)
+--- a/fs/btrfs/volumes.c
++++ b/fs/btrfs/volumes.c
+@@ -347,27 +347,6 @@ static struct btrfs_device *__alloc_devi
+ return dev;
+ }
+
+-/*
+- * Find a device specified by @devid or @uuid in the list of @fs_devices, or
+- * return NULL.
+- *
+- * If devid and uuid are both specified, the match must be exact, otherwise
+- * only devid is used.
+- */
+-static struct btrfs_device *find_device(struct btrfs_fs_devices *fs_devices,
+- u64 devid, const u8 *uuid)
+-{
+- struct btrfs_device *dev;
+-
+- list_for_each_entry(dev, &fs_devices->devices, dev_list) {
+- if (dev->devid == devid &&
+- (!uuid || !memcmp(dev->uuid, uuid, BTRFS_UUID_SIZE))) {
+- return dev;
+- }
+- }
+- return NULL;
+-}
+-
+ static noinline struct btrfs_fs_devices *find_fsid(u8 *fsid)
+ {
+ struct btrfs_fs_devices *fs_devices;
+@@ -772,8 +751,8 @@ static noinline struct btrfs_device *dev
+ device = NULL;
+ } else {
+ mutex_lock(&fs_devices->device_list_mutex);
+- device = find_device(fs_devices, devid,
+- disk_super->dev_item.uuid);
++ device = btrfs_find_device(fs_devices, devid,
++ disk_super->dev_item.uuid, NULL, false);
+ }
+
+ if (!device) {
+@@ -2144,7 +2123,8 @@ static int btrfs_find_device_by_path(str
+ disk_super = (struct btrfs_super_block *)bh->b_data;
+ devid = btrfs_stack_device_id(&disk_super->dev_item);
+ dev_uuid = disk_super->dev_item.uuid;
+- *device = btrfs_find_device(fs_info, devid, dev_uuid, disk_super->fsid);
++ *device = btrfs_find_device(fs_info->fs_devices, devid, dev_uuid,
++ disk_super->fsid, true);
+ brelse(bh);
+ if (!*device)
+ ret = -ENOENT;
+@@ -2190,7 +2170,8 @@ int btrfs_find_device_by_devspec(struct
+
+ if (devid) {
+ ret = 0;
+- *device = btrfs_find_device(fs_info, devid, NULL, NULL);
++ *device = btrfs_find_device(fs_info->fs_devices, devid,
++ NULL, NULL, true);
+ if (!*device)
+ ret = -ENOENT;
+ } else {
+@@ -2322,7 +2303,8 @@ next_slot:
+ BTRFS_UUID_SIZE);
+ read_extent_buffer(leaf, fs_uuid, btrfs_device_fsid(dev_item),
+ BTRFS_FSID_SIZE);
+- device = btrfs_find_device(fs_info, devid, dev_uuid, fs_uuid);
++ device = btrfs_find_device(fs_info->fs_devices, devid, dev_uuid,
++ fs_uuid, true);
+ BUG_ON(!device); /* Logic error */
+
+ if (device->fs_devices->seeding) {
+@@ -6254,21 +6236,36 @@ blk_status_t btrfs_map_bio(struct btrfs_
+ return BLK_STS_OK;
+ }
+
+-struct btrfs_device *btrfs_find_device(struct btrfs_fs_info *fs_info, u64 devid,
+- u8 *uuid, u8 *fsid)
++/*
++ * Find a device specified by @devid or @uuid in the list of @fs_devices, or
++ * return NULL.
++ *
++ * If devid and uuid are both specified, the match must be exact, otherwise
++ * only devid is used.
++ *
++ * If @seed is true, traverse through the seed devices.
++ */
++struct btrfs_device *btrfs_find_device(struct btrfs_fs_devices *fs_devices,
++ u64 devid, u8 *uuid, u8 *fsid,
++ bool seed)
+ {
+ struct btrfs_device *device;
+- struct btrfs_fs_devices *cur_devices;
+
+- cur_devices = fs_info->fs_devices;
+- while (cur_devices) {
++ while (fs_devices) {
+ if (!fsid ||
+- !memcmp(cur_devices->fsid, fsid, BTRFS_FSID_SIZE)) {
+- device = find_device(cur_devices, devid, uuid);
+- if (device)
+- return device;
++ !memcmp(fs_devices->fsid, fsid, BTRFS_FSID_SIZE)) {
++ list_for_each_entry(device, &fs_devices->devices,
++ dev_list) {
++ if (device->devid == devid &&
++ (!uuid || memcmp(device->uuid, uuid,
++ BTRFS_UUID_SIZE) == 0))
++ return device;
++ }
+ }
+- cur_devices = cur_devices->seed;
++ if (seed)
++ fs_devices = fs_devices->seed;
++ else
++ return NULL;
+ }
+ return NULL;
+ }
+@@ -6513,8 +6510,8 @@ static int read_one_chunk(struct btrfs_f
+ read_extent_buffer(leaf, uuid, (unsigned long)
+ btrfs_stripe_dev_uuid_nr(chunk, i),
+ BTRFS_UUID_SIZE);
+- map->stripes[i].dev = btrfs_find_device(fs_info, devid,
+- uuid, NULL);
++ map->stripes[i].dev = btrfs_find_device(fs_info->fs_devices,
++ devid, uuid, NULL, true);
+ if (!map->stripes[i].dev &&
+ !btrfs_test_opt(fs_info, DEGRADED)) {
+ free_extent_map(em);
+@@ -6653,7 +6650,8 @@ static int read_one_dev(struct btrfs_fs_
+ return PTR_ERR(fs_devices);
+ }
+
+- device = btrfs_find_device(fs_info, devid, dev_uuid, fs_uuid);
++ device = btrfs_find_device(fs_info->fs_devices, devid, dev_uuid,
++ fs_uuid, true);
+ if (!device) {
+ if (!btrfs_test_opt(fs_info, DEGRADED)) {
+ btrfs_report_missing_device(fs_info, devid,
+@@ -7243,7 +7241,8 @@ int btrfs_get_dev_stats(struct btrfs_fs_
+ int i;
+
+ mutex_lock(&fs_devices->device_list_mutex);
+- dev = btrfs_find_device(fs_info, stats->devid, NULL, NULL);
++ dev = btrfs_find_device(fs_info->fs_devices, stats->devid,
++ NULL, NULL, true);
+ mutex_unlock(&fs_devices->device_list_mutex);
+
+ if (!dev) {
+@@ -7460,7 +7459,7 @@ static int verify_one_dev_extent(struct
+ }
+
+ /* Make sure no dev extent is beyond device bondary */
+- dev = btrfs_find_device(fs_info, devid, NULL, NULL);
++ dev = btrfs_find_device(fs_info->fs_devices, devid, NULL, NULL, true);
+ if (!dev) {
+ btrfs_err(fs_info, "failed to find devid %llu", devid);
+ ret = -EUCLEAN;
+@@ -7469,7 +7468,8 @@ static int verify_one_dev_extent(struct
+
+ /* It's possible this device is a dummy for seed device */
+ if (dev->disk_total_bytes == 0) {
+- dev = find_device(fs_info->fs_devices->seed, devid, NULL);
++ dev = btrfs_find_device(fs_info->fs_devices->seed, devid,
++ NULL, NULL, false);
+ if (!dev) {
+ btrfs_err(fs_info, "failed to find seed devid %llu",
+ devid);
+--- a/fs/btrfs/volumes.h
++++ b/fs/btrfs/volumes.h
+@@ -430,8 +430,8 @@ void __exit btrfs_cleanup_fs_uuids(void)
+ int btrfs_num_copies(struct btrfs_fs_info *fs_info, u64 logical, u64 len);
+ int btrfs_grow_device(struct btrfs_trans_handle *trans,
+ struct btrfs_device *device, u64 new_size);
+-struct btrfs_device *btrfs_find_device(struct btrfs_fs_info *fs_info, u64 devid,
+- u8 *uuid, u8 *fsid);
++struct btrfs_device *btrfs_find_device(struct btrfs_fs_devices *fs_devices,
++ u64 devid, u8 *uuid, u8 *fsid, bool seed);
+ int btrfs_shrink_device(struct btrfs_device *device, u64 new_size);
+ int btrfs_init_new_device(struct btrfs_fs_info *fs_info, const char *path);
+ int btrfs_balance(struct btrfs_fs_info *fs_info,
--- /dev/null
+From 94bd8a05cd4de344a9a57e52ef7d99550251984f Mon Sep 17 00:00:00 2001
+From: Linus Torvalds <torvalds@linux-foundation.org>
+Date: Sun, 6 Jan 2019 11:15:04 -0800
+Subject: Fix 'acccess_ok()' on alpha and SH
+
+From: Linus Torvalds <torvalds@linux-foundation.org>
+
+commit 94bd8a05cd4de344a9a57e52ef7d99550251984f upstream.
+
+Commit 594cc251fdd0 ("make 'user_access_begin()' do 'access_ok()'")
+broke both alpha and SH booting in qemu, as noticed by Guenter Roeck.
+
+It turns out that the bug wasn't actually in that commit itself (which
+would have been surprising: it was mostly a no-op), but in how the
+addition of access_ok() to the strncpy_from_user() and strnlen_user()
+functions now triggered the case where those functions would test the
+access of the very last byte of the user address space.
+
+The string functions actually did that user range test before too, but
+they did it manually by just comparing against user_addr_max(). But
+with user_access_begin() doing the check (using "access_ok()"), it now
+exposed problems in the architecture implementations of that function.
+
+For example, on alpha, the access_ok() helper macro looked like this:
+
+ #define __access_ok(addr, size) \
+ ((get_fs().seg & (addr | size | (addr+size))) == 0)
+
+and what it basically tests is of any of the high bits get set (the
+USER_DS masking value is 0xfffffc0000000000).
+
+And that's completely wrong for the "addr+size" check. Because it's
+off-by-one for the case where we check to the very end of the user
+address space, which is exactly what the strn*_user() functions do.
+
+Why? Because "addr+size" will be exactly the size of the address space,
+so trying to access the last byte of the user address space will fail
+the __access_ok() check, even though it shouldn't. As a result, the
+user string accessor functions failed consistently - because they
+literally don't know how long the string is going to be, and the max
+access is going to be that last byte of the user address space.
+
+Side note: that alpha macro is buggy for another reason too - it re-uses
+the arguments twice.
+
+And SH has another version of almost the exact same bug:
+
+ #define __addr_ok(addr) \
+ ((unsigned long __force)(addr) < current_thread_info()->addr_limit.seg)
+
+so far so good: yes, a user address must be below the limit. But then:
+
+ #define __access_ok(addr, size) \
+ (__addr_ok((addr) + (size)))
+
+is wrong with the exact same off-by-one case: the case when "addr+size"
+is exactly _equal_ to the limit is actually perfectly fine (think "one
+byte access at the last address of the user address space")
+
+The SH version is actually seriously buggy in another way: it doesn't
+actually check for overflow, even though it did copy the _comment_ that
+talks about overflow.
+
+So it turns out that both SH and alpha actually have completely buggy
+implementations of access_ok(), but they happened to work in practice
+(although the SH overflow one is a serious serious security bug, not
+that anybody likely cares about SH security).
+
+This fixes the problems by using a similar macro on both alpha and SH.
+It isn't trying to be clever, the end address is based on this logic:
+
+ unsigned long __ao_end = __ao_a + __ao_b - !!__ao_b;
+
+which basically says "add start and length, and then subtract one unless
+the length was zero". We can't subtract one for a zero length, or we'd
+just hit an underflow instead.
+
+For a lot of access_ok() users the length is a constant, so this isn't
+actually as expensive as it initially looks.
+
+Reported-and-tested-by: Guenter Roeck <linux@roeck-us.net>
+Cc: Matt Turner <mattst88@gmail.com>
+Cc: Yoshinori Sato <ysato@users.sourceforge.jp>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Miles Chen <miles.chen@mediatek.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/alpha/include/asm/uaccess.h | 8 +++++---
+ arch/sh/include/asm/uaccess.h | 7 +++++--
+ 2 files changed, 10 insertions(+), 5 deletions(-)
+
+--- a/arch/alpha/include/asm/uaccess.h
++++ b/arch/alpha/include/asm/uaccess.h
+@@ -30,11 +30,13 @@
+ * Address valid if:
+ * - "addr" doesn't have any high-bits set
+ * - AND "size" doesn't have any high-bits set
+- * - AND "addr+size" doesn't have any high-bits set
++ * - AND "addr+size-(size != 0)" doesn't have any high-bits set
+ * - OR we are in kernel mode.
+ */
+-#define __access_ok(addr, size) \
+- ((get_fs().seg & (addr | size | (addr+size))) == 0)
++#define __access_ok(addr, size) ({ \
++ unsigned long __ao_a = (addr), __ao_b = (size); \
++ unsigned long __ao_end = __ao_a + __ao_b - !!__ao_b; \
++ (get_fs().seg & (__ao_a | __ao_b | __ao_end)) == 0; })
+
+ #define access_ok(type, addr, size) \
+ ({ \
+--- a/arch/sh/include/asm/uaccess.h
++++ b/arch/sh/include/asm/uaccess.h
+@@ -16,8 +16,11 @@
+ * sum := addr + size; carry? --> flag = true;
+ * if (sum >= addr_limit) flag = true;
+ */
+-#define __access_ok(addr, size) \
+- (__addr_ok((addr) + (size)))
++#define __access_ok(addr, size) ({ \
++ unsigned long __ao_a = (addr), __ao_b = (size); \
++ unsigned long __ao_end = __ao_a + __ao_b - !!__ao_b; \
++ __ao_end >= __ao_a && __addr_ok(__ao_end); })
++
+ #define access_ok(type, addr, size) \
+ (__chk_user_ptr(addr), \
+ __access_ok((unsigned long __force)(addr), (size)))
--- /dev/null
+From ab10ae1c3bef56c29bac61e1201c752221b87b41 Mon Sep 17 00:00:00 2001
+From: Christophe Leroy <christophe.leroy@c-s.fr>
+Date: Thu, 23 Jan 2020 08:34:18 +0000
+Subject: lib: Reduce user_access_begin() boundaries in strncpy_from_user() and strnlen_user()
+
+From: Christophe Leroy <christophe.leroy@c-s.fr>
+
+commit ab10ae1c3bef56c29bac61e1201c752221b87b41 upstream.
+
+The range passed to user_access_begin() by strncpy_from_user() and
+strnlen_user() starts at 'src' and goes up to the limit of userspace
+although reads will be limited by the 'count' param.
+
+On 32 bits powerpc (book3s/32) access has to be granted for each
+256Mbytes segment and the cost increases with the number of segments to
+unlock.
+
+Limit the range with 'count' param.
+
+Fixes: 594cc251fdd0 ("make 'user_access_begin()' do 'access_ok()'")
+Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Miles Chen <miles.chen@mediatek.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ lib/strncpy_from_user.c | 14 +++++++-------
+ lib/strnlen_user.c | 14 +++++++-------
+ 2 files changed, 14 insertions(+), 14 deletions(-)
+
+--- a/lib/strncpy_from_user.c
++++ b/lib/strncpy_from_user.c
+@@ -29,13 +29,6 @@ static inline long do_strncpy_from_user(
+ const struct word_at_a_time constants = WORD_AT_A_TIME_CONSTANTS;
+ unsigned long res = 0;
+
+- /*
+- * Truncate 'max' to the user-specified limit, so that
+- * we only have one limit we need to check in the loop
+- */
+- if (max > count)
+- max = count;
+-
+ if (IS_UNALIGNED(src, dst))
+ goto byte_at_a_time;
+
+@@ -113,6 +106,13 @@ long strncpy_from_user(char *dst, const
+ unsigned long max = max_addr - src_addr;
+ long retval;
+
++ /*
++ * Truncate 'max' to the user-specified limit, so that
++ * we only have one limit we need to check in the loop
++ */
++ if (max > count)
++ max = count;
++
+ kasan_check_write(dst, count);
+ check_object_size(dst, count, false);
+ if (user_access_begin(VERIFY_READ, src, max)) {
+--- a/lib/strnlen_user.c
++++ b/lib/strnlen_user.c
+@@ -32,13 +32,6 @@ static inline long do_strnlen_user(const
+ unsigned long c;
+
+ /*
+- * Truncate 'max' to the user-specified limit, so that
+- * we only have one limit we need to check in the loop
+- */
+- if (max > count)
+- max = count;
+-
+- /*
+ * Do everything aligned. But that means that we
+ * need to also expand the maximum..
+ */
+@@ -114,6 +107,13 @@ long strnlen_user(const char __user *str
+ unsigned long max = max_addr - src_addr;
+ long retval;
+
++ /*
++ * Truncate 'max' to the user-specified limit, so that
++ * we only have one limit we need to check in the loop
++ */
++ if (max > count)
++ max = count;
++
+ if (user_access_begin(VERIFY_READ, str, max)) {
+ retval = do_strnlen_user(str, count, max);
+ user_access_end();
--- /dev/null
+From 594cc251fdd0d231d342d88b2fdff4bc42fb0690 Mon Sep 17 00:00:00 2001
+From: Linus Torvalds <torvalds@linux-foundation.org>
+Date: Fri, 4 Jan 2019 12:56:09 -0800
+Subject: make 'user_access_begin()' do 'access_ok()'
+
+From: Linus Torvalds <torvalds@linux-foundation.org>
+
+commit 594cc251fdd0d231d342d88b2fdff4bc42fb0690 upstream.
+
+Originally, the rule used to be that you'd have to do access_ok()
+separately, and then user_access_begin() before actually doing the
+direct (optimized) user access.
+
+But experience has shown that people then decide not to do access_ok()
+at all, and instead rely on it being implied by other operations or
+similar. Which makes it very hard to verify that the access has
+actually been range-checked.
+
+If you use the unsafe direct user accesses, hardware features (either
+SMAP - Supervisor Mode Access Protection - on x86, or PAN - Privileged
+Access Never - on ARM) do force you to use user_access_begin(). But
+nothing really forces the range check.
+
+By putting the range check into user_access_begin(), we actually force
+people to do the right thing (tm), and the range check vill be visible
+near the actual accesses. We have way too long a history of people
+trying to avoid them.
+
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Miles Chen <miles.chen@mediatek.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/x86/include/asm/uaccess.h | 12 +++++++++++-
+ drivers/gpu/drm/i915/i915_gem_execbuffer.c | 16 ++++++++++++++--
+ include/linux/uaccess.h | 2 +-
+ kernel/compat.c | 6 ++----
+ kernel/exit.c | 6 ++----
+ lib/strncpy_from_user.c | 9 +++++----
+ lib/strnlen_user.c | 9 +++++----
+ 7 files changed, 40 insertions(+), 20 deletions(-)
+
+--- a/arch/x86/include/asm/uaccess.h
++++ b/arch/x86/include/asm/uaccess.h
+@@ -711,7 +711,17 @@ extern struct movsl_mask {
+ * checking before using them, but you have to surround them with the
+ * user_access_begin/end() pair.
+ */
+-#define user_access_begin() __uaccess_begin()
++static __must_check inline bool user_access_begin(int type,
++ const void __user *ptr,
++ size_t len)
++{
++ if (unlikely(!access_ok(type, ptr, len)))
++ return 0;
++ __uaccess_begin();
++ return 1;
++}
++
++#define user_access_begin(a, b, c) user_access_begin(a, b, c)
+ #define user_access_end() __uaccess_end()
+
+ #define unsafe_put_user(x, ptr, err_label) \
+--- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c
++++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
+@@ -1604,7 +1604,9 @@ static int eb_copy_relocations(const str
+ * happened we would make the mistake of assuming that the
+ * relocations were valid.
+ */
+- user_access_begin();
++ if (!user_access_begin(VERIFY_WRITE, urelocs, size))
++ goto end_user;
++
+ for (copied = 0; copied < nreloc; copied++)
+ unsafe_put_user(-1,
+ &urelocs[copied].presumed_offset,
+@@ -2649,7 +2651,17 @@ i915_gem_execbuffer2_ioctl(struct drm_de
+ unsigned int i;
+
+ /* Copy the new buffer offsets back to the user's exec list. */
+- user_access_begin();
++ /*
++ * Note: count * sizeof(*user_exec_list) does not overflow,
++ * because we checked 'count' in check_buffer_count().
++ *
++ * And this range already got effectively checked earlier
++ * when we did the "copy_from_user()" above.
++ */
++ if (!user_access_begin(VERIFY_WRITE, user_exec_list,
++ count * sizeof(*user_exec_list)))
++ goto end_user;
++
+ for (i = 0; i < args->buffer_count; i++) {
+ if (!(exec2_list[i].offset & UPDATE))
+ continue;
+--- a/include/linux/uaccess.h
++++ b/include/linux/uaccess.h
+@@ -267,7 +267,7 @@ extern long strncpy_from_unsafe(char *ds
+ probe_kernel_read(&retval, addr, sizeof(retval))
+
+ #ifndef user_access_begin
+-#define user_access_begin() do { } while (0)
++#define user_access_begin(type, ptr, len) access_ok(type, ptr, len)
+ #define user_access_end() do { } while (0)
+ #define unsafe_get_user(x, ptr, err) do { if (unlikely(__get_user(x, ptr))) goto err; } while (0)
+ #define unsafe_put_user(x, ptr, err) do { if (unlikely(__put_user(x, ptr))) goto err; } while (0)
+--- a/kernel/compat.c
++++ b/kernel/compat.c
+@@ -354,10 +354,9 @@ long compat_get_bitmap(unsigned long *ma
+ bitmap_size = ALIGN(bitmap_size, BITS_PER_COMPAT_LONG);
+ nr_compat_longs = BITS_TO_COMPAT_LONGS(bitmap_size);
+
+- if (!access_ok(VERIFY_READ, umask, bitmap_size / 8))
++ if (!user_access_begin(VERIFY_READ, umask, bitmap_size / 8))
+ return -EFAULT;
+
+- user_access_begin();
+ while (nr_compat_longs > 1) {
+ compat_ulong_t l1, l2;
+ unsafe_get_user(l1, umask++, Efault);
+@@ -384,10 +383,9 @@ long compat_put_bitmap(compat_ulong_t __
+ bitmap_size = ALIGN(bitmap_size, BITS_PER_COMPAT_LONG);
+ nr_compat_longs = BITS_TO_COMPAT_LONGS(bitmap_size);
+
+- if (!access_ok(VERIFY_WRITE, umask, bitmap_size / 8))
++ if (!user_access_begin(VERIFY_WRITE, umask, bitmap_size / 8))
+ return -EFAULT;
+
+- user_access_begin();
+ while (nr_compat_longs > 1) {
+ unsigned long m = *mask++;
+ unsafe_put_user((compat_ulong_t)m, umask++, Efault);
+--- a/kernel/exit.c
++++ b/kernel/exit.c
+@@ -1617,10 +1617,9 @@ SYSCALL_DEFINE5(waitid, int, which, pid_
+ if (!infop)
+ return err;
+
+- if (!access_ok(VERIFY_WRITE, infop, sizeof(*infop)))
++ if (!user_access_begin(VERIFY_WRITE, infop, sizeof(*infop)))
+ return -EFAULT;
+
+- user_access_begin();
+ unsafe_put_user(signo, &infop->si_signo, Efault);
+ unsafe_put_user(0, &infop->si_errno, Efault);
+ unsafe_put_user(info.cause, &infop->si_code, Efault);
+@@ -1745,10 +1744,9 @@ COMPAT_SYSCALL_DEFINE5(waitid,
+ if (!infop)
+ return err;
+
+- if (!access_ok(VERIFY_WRITE, infop, sizeof(*infop)))
++ if (!user_access_begin(VERIFY_WRITE, infop, sizeof(*infop)))
+ return -EFAULT;
+
+- user_access_begin();
+ unsafe_put_user(signo, &infop->si_signo, Efault);
+ unsafe_put_user(0, &infop->si_errno, Efault);
+ unsafe_put_user(info.cause, &infop->si_code, Efault);
+--- a/lib/strncpy_from_user.c
++++ b/lib/strncpy_from_user.c
+@@ -115,10 +115,11 @@ long strncpy_from_user(char *dst, const
+
+ kasan_check_write(dst, count);
+ check_object_size(dst, count, false);
+- user_access_begin();
+- retval = do_strncpy_from_user(dst, src, count, max);
+- user_access_end();
+- return retval;
++ if (user_access_begin(VERIFY_READ, src, max)) {
++ retval = do_strncpy_from_user(dst, src, count, max);
++ user_access_end();
++ return retval;
++ }
+ }
+ return -EFAULT;
+ }
+--- a/lib/strnlen_user.c
++++ b/lib/strnlen_user.c
+@@ -114,10 +114,11 @@ long strnlen_user(const char __user *str
+ unsigned long max = max_addr - src_addr;
+ long retval;
+
+- user_access_begin();
+- retval = do_strnlen_user(str, count, max);
+- user_access_end();
+- return retval;
++ if (user_access_begin(VERIFY_READ, str, max)) {
++ retval = do_strnlen_user(str, count, max);
++ user_access_end();
++ return retval;
++ }
+ }
+ return 0;
+ }
vxlan-avoid-infinite-loop-when-suppressing-ns-messages-with-invalid-options.patch
tun-correct-header-offsets-in-napi-frags-mode.patch
selftests-bpf-fix-use-of-undeclared-ret_if-macro.patch
+make-user_access_begin-do-access_ok.patch
+fix-acccess_ok-on-alpha-and-sh.patch
+arch-openrisc-fix-issues-with-access_ok.patch
+x86-uaccess-inhibit-speculation-past-access_ok-in-user_access_begin.patch
+lib-reduce-user_access_begin-boundaries-in-strncpy_from_user-and-strnlen_user.patch
+btrfs-merge-btrfs_find_device-and-find_device.patch
+btrfs-detect-unbalanced-tree-with-empty-leaf-before-crashing-btree-operations.patch
--- /dev/null
+From 6e693b3ffecb0b478c7050b44a4842854154f715 Mon Sep 17 00:00:00 2001
+From: Will Deacon <will@kernel.org>
+Date: Sat, 19 Jan 2019 21:56:05 +0000
+Subject: x86: uaccess: Inhibit speculation past access_ok() in user_access_begin()
+
+From: Will Deacon <will.deacon@arm.com>
+
+commit 6e693b3ffecb0b478c7050b44a4842854154f715 upstream.
+
+Commit 594cc251fdd0 ("make 'user_access_begin()' do 'access_ok()'")
+makes the access_ok() check part of the user_access_begin() preceding a
+series of 'unsafe' accesses. This has the desirable effect of ensuring
+that all 'unsafe' accesses have been range-checked, without having to
+pick through all of the callsites to verify whether the appropriate
+checking has been made.
+
+However, the consolidated range check does not inhibit speculation, so
+it is still up to the caller to ensure that they are not susceptible to
+any speculative side-channel attacks for user addresses that ultimately
+fail the access_ok() check.
+
+This is an oversight, so use __uaccess_begin_nospec() to ensure that
+speculation is inhibited until the access_ok() check has passed.
+
+Reported-by: Julien Thierry <julien.thierry@arm.com>
+Signed-off-by: Will Deacon <will.deacon@arm.com>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Miles Chen <miles.chen@mediatek.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/x86/include/asm/uaccess.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/arch/x86/include/asm/uaccess.h
++++ b/arch/x86/include/asm/uaccess.h
+@@ -717,7 +717,7 @@ static __must_check inline bool user_acc
+ {
+ if (unlikely(!access_ok(type, ptr, len)))
+ return 0;
+- __uaccess_begin();
++ __uaccess_begin_nospec();
+ return 1;
+ }
+