summaryrefslogtreecommitdiff
path: root/fs/btrfs/ioctl.c
diff options
context:
space:
mode:
authorMichael Bestas <mkbestas@lineageos.org>2020-09-19 12:58:54 +0300
committerMichael Bestas <mkbestas@lineageos.org>2020-09-19 12:58:54 +0300
commit3b601dd398b0f8a66744c0ecf384a6cbe65e36e7 (patch)
tree570d5895dfced5d2e443a7f9b8f6fa5f9a7560f3 /fs/btrfs/ioctl.c
parenta638073161e90ac6dc0ffc2e27cbc4bcd3ff88c3 (diff)
parent5fd2d19eeb9767339e1338eb6789495d1812065b (diff)
Merge branch 'android-4.4-p' of https://android.googlesource.com/kernel/common into lineage-17.1-caf-msm8998
This brings LA.UM.8.4.r1-05900-8x98.0 up to date with https://android.googlesource.com/kernel/common/ android-4.4-p at commit: 5fd2d19eeb976 Merge 4.4.236 into android-4.4-p Conflicts: drivers/scsi/ufs/ufshcd.c Change-Id: I22282a0d571bdb72f50d3fc1e2cee4443de1f7f4
Diffstat (limited to 'fs/btrfs/ioctl.c')
-rw-r--r--fs/btrfs/ioctl.c27
1 files changed, 20 insertions, 7 deletions
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index 245a50f490f6..91a45ef69152 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -2017,9 +2017,14 @@ static noinline int copy_to_sk(struct btrfs_root *root,
sh.len = item_len;
sh.transid = found_transid;
- /* copy search result header */
- if (copy_to_user(ubuf + *sk_offset, &sh, sizeof(sh))) {
- ret = -EFAULT;
+ /*
+ * Copy search result header. If we fault then loop again so we
+ * can fault in the pages and -EFAULT there if there's a
+ * problem. Otherwise we'll fault and then copy the buffer in
+ * properly this next time through
+ */
+ if (probe_user_write(ubuf + *sk_offset, &sh, sizeof(sh))) {
+ ret = 0;
goto out;
}
@@ -2027,10 +2032,14 @@ static noinline int copy_to_sk(struct btrfs_root *root,
if (item_len) {
char __user *up = ubuf + *sk_offset;
- /* copy the item */
- if (read_extent_buffer_to_user(leaf, up,
- item_off, item_len)) {
- ret = -EFAULT;
+ /*
+ * Copy the item, same behavior as above, but reset the
+ * * sk_offset so we copy the full thing again.
+ */
+ if (read_extent_buffer_to_user_nofault(leaf, up,
+ item_off, item_len)) {
+ ret = 0;
+ *sk_offset -= sizeof(sh);
goto out;
}
@@ -2120,6 +2129,10 @@ static noinline int search_ioctl(struct inode *inode,
key.offset = sk->min_offset;
while (1) {
+ ret = fault_in_pages_writeable(ubuf, *buf_size - sk_offset);
+ if (ret)
+ break;
+
ret = btrfs_search_forward(root, &key, path, sk->min_transid);
if (ret != 0) {
if (ret > 0)