From: Greg Kroah-Hartman Date: Thu, 21 Jun 2018 21:23:34 +0000 (+0900) Subject: 4.14-stable patches X-Git-Tag: v4.17.3~19 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=e0978e14b53ce45b6bdf40446cdec6eaf53fff77;p=thirdparty%2Fkernel%2Fstable-queue.git 4.14-stable patches added patches: alsa-hda-add-dock-and-led-support-for-hp-elitebook-830-g5.patch alsa-hda-add-dock-and-led-support-for-hp-probook-640-g4.patch alsa-hda-conexant-add-fixup-for-hp-z2-g4-workstation.patch alsa-hda-handle-kzalloc-failure-in-snd_hda_attach_pcm_stream.patch alsa-hda-realtek-enable-mic-mute-hotkey-for-several-lenovo-aios.patch btrfs-fix-clone-vs-chattr-nodatasum-race.patch btrfs-fix-memory-and-mount-leak-in-btrfs_ioctl_rm_dev_v2.patch btrfs-return-error-value-if-create_io_em-failed-in-cow_file_range.patch btrfs-scrub-don-t-use-inode-pages-for-device-replace.patch driver-core-don-t-ignore-class_dir_create_and_add-failure.patch ext4-bubble-errors-from-ext4_find_inline_data_nolock-up-to-ext4_iget.patch ext4-correctly-handle-a-zero-length-xattr-with-a-non-zero-e_value_offs.patch ext4-do-not-allow-external-inodes-for-inline-data.patch ext4-fix-fencepost-error-in-check-for-inode-count-overflow-during-resize.patch ext4-fix-hole-length-detection-in-ext4_ind_map_blocks.patch ext4-update-mtime-in-ext4_punch_hole-even-if-no-blocks-are-released.patch nfsv4.1-fix-up-replays-of-interrupted-requests.patch x86-mce-fix-stack-out-of-bounds-write-in-mce-inject.c-flags_read.patch --- diff --git a/queue-4.14/alsa-hda-add-dock-and-led-support-for-hp-elitebook-830-g5.patch b/queue-4.14/alsa-hda-add-dock-and-led-support-for-hp-elitebook-830-g5.patch new file mode 100644 index 00000000000..e55d60dfcb0 --- /dev/null +++ b/queue-4.14/alsa-hda-add-dock-and-led-support-for-hp-elitebook-830-g5.patch @@ -0,0 +1,32 @@ +From 2861751f67b91e1d24e68010ced96614fb3140f4 Mon Sep 17 00:00:00 2001 +From: Dennis Wassenberg +Date: Tue, 12 Jun 2018 07:10:59 +0200 +Subject: ALSA: hda: add dock and led support for HP EliteBook 830 G5 + +From: Dennis Wassenberg + +commit 2861751f67b91e1d24e68010ced96614fb3140f4 upstream. + +This patch adds missing initialisation for HP 2013 UltraSlim Dock +Line-In/Out PINs and activates keyboard mute/micmute leds +for HP EliteBook 830 G5 + +Signed-off-by: Dennis Wassenberg +Cc: +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman + +--- + sound/pci/hda/patch_conexant.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/sound/pci/hda/patch_conexant.c ++++ b/sound/pci/hda/patch_conexant.c +@@ -959,6 +959,7 @@ static const struct snd_pci_quirk cxt506 + SND_PCI_QUIRK(0x103c, 0x8079, "HP EliteBook 840 G3", CXT_FIXUP_HP_DOCK), + SND_PCI_QUIRK(0x103c, 0x807C, "HP EliteBook 820 G3", CXT_FIXUP_HP_DOCK), + SND_PCI_QUIRK(0x103c, 0x80FD, "HP ProBook 640 G2", CXT_FIXUP_HP_DOCK), ++ SND_PCI_QUIRK(0x103c, 0x83b3, "HP EliteBook 830 G5", CXT_FIXUP_HP_DOCK), + SND_PCI_QUIRK(0x103c, 0x8174, "HP Spectre x360", CXT_FIXUP_HP_SPECTRE), + SND_PCI_QUIRK(0x103c, 0x8115, "HP Z1 Gen3", CXT_FIXUP_HP_GATE_MIC), + SND_PCI_QUIRK(0x103c, 0x814f, "HP ZBook 15u G3", CXT_FIXUP_MUTE_LED_GPIO), diff --git a/queue-4.14/alsa-hda-add-dock-and-led-support-for-hp-probook-640-g4.patch b/queue-4.14/alsa-hda-add-dock-and-led-support-for-hp-probook-640-g4.patch new file mode 100644 index 00000000000..97aa377460d --- /dev/null +++ b/queue-4.14/alsa-hda-add-dock-and-led-support-for-hp-probook-640-g4.patch @@ -0,0 +1,32 @@ +From 7eef32c1ef895a3a96463f9cbd04203007cd5555 Mon Sep 17 00:00:00 2001 +From: Dennis Wassenberg +Date: Tue, 12 Jun 2018 07:11:11 +0200 +Subject: ALSA: hda: add dock and led support for HP ProBook 640 G4 + +From: Dennis Wassenberg + +commit 7eef32c1ef895a3a96463f9cbd04203007cd5555 upstream. + +This patch adds missing initialisation for HP 2013 UltraSlim Dock +Line-In/Out PINs and activates keyboard mute/micmute leds +for HP ProBook 640 G4 + +Signed-off-by: Dennis Wassenberg +Cc: +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman + +--- + sound/pci/hda/patch_conexant.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/sound/pci/hda/patch_conexant.c ++++ b/sound/pci/hda/patch_conexant.c +@@ -960,6 +960,7 @@ static const struct snd_pci_quirk cxt506 + SND_PCI_QUIRK(0x103c, 0x807C, "HP EliteBook 820 G3", CXT_FIXUP_HP_DOCK), + SND_PCI_QUIRK(0x103c, 0x80FD, "HP ProBook 640 G2", CXT_FIXUP_HP_DOCK), + SND_PCI_QUIRK(0x103c, 0x83b3, "HP EliteBook 830 G5", CXT_FIXUP_HP_DOCK), ++ SND_PCI_QUIRK(0x103c, 0x83d3, "HP ProBook 640 G4", CXT_FIXUP_HP_DOCK), + SND_PCI_QUIRK(0x103c, 0x8174, "HP Spectre x360", CXT_FIXUP_HP_SPECTRE), + SND_PCI_QUIRK(0x103c, 0x8115, "HP Z1 Gen3", CXT_FIXUP_HP_GATE_MIC), + SND_PCI_QUIRK(0x103c, 0x814f, "HP ZBook 15u G3", CXT_FIXUP_MUTE_LED_GPIO), diff --git a/queue-4.14/alsa-hda-conexant-add-fixup-for-hp-z2-g4-workstation.patch b/queue-4.14/alsa-hda-conexant-add-fixup-for-hp-z2-g4-workstation.patch new file mode 100644 index 00000000000..64780fba94b --- /dev/null +++ b/queue-4.14/alsa-hda-conexant-add-fixup-for-hp-z2-g4-workstation.patch @@ -0,0 +1,30 @@ +From f16041df4c360eccacfe90f96673b37829e4c959 Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Fri, 18 May 2018 12:14:32 +0200 +Subject: ALSA: hda/conexant - Add fixup for HP Z2 G4 workstation + +From: Takashi Iwai + +commit f16041df4c360eccacfe90f96673b37829e4c959 upstream. + +HP Z2 G4 requires the same workaround as other HP machines that have +no mic-pin detection. + +Cc: +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman + +--- + sound/pci/hda/patch_conexant.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/sound/pci/hda/patch_conexant.c ++++ b/sound/pci/hda/patch_conexant.c +@@ -965,6 +965,7 @@ static const struct snd_pci_quirk cxt506 + SND_PCI_QUIRK(0x103c, 0x822e, "HP ProBook 440 G4", CXT_FIXUP_MUTE_LED_GPIO), + SND_PCI_QUIRK(0x103c, 0x8299, "HP 800 G3 SFF", CXT_FIXUP_HP_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x103c, 0x829a, "HP 800 G3 DM", CXT_FIXUP_HP_MIC_NO_PRESENCE), ++ SND_PCI_QUIRK(0x103c, 0x8455, "HP Z2 G4", CXT_FIXUP_HP_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x1043, 0x138d, "Asus", CXT_FIXUP_HEADPHONE_MIC_PIN), + SND_PCI_QUIRK(0x152d, 0x0833, "OLPC XO-1.5", CXT_FIXUP_OLPC_XO), + SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo T400", CXT_PINCFG_LENOVO_TP410), diff --git a/queue-4.14/alsa-hda-handle-kzalloc-failure-in-snd_hda_attach_pcm_stream.patch b/queue-4.14/alsa-hda-handle-kzalloc-failure-in-snd_hda_attach_pcm_stream.patch new file mode 100644 index 00000000000..98c8552ce58 --- /dev/null +++ b/queue-4.14/alsa-hda-handle-kzalloc-failure-in-snd_hda_attach_pcm_stream.patch @@ -0,0 +1,46 @@ +From a3aa60d511746bd6c0d0366d4eb90a7998bcde8b Mon Sep 17 00:00:00 2001 +From: Bo Chen +Date: Thu, 31 May 2018 15:35:18 -0700 +Subject: ALSA: hda - Handle kzalloc() failure in snd_hda_attach_pcm_stream() + +From: Bo Chen + +commit a3aa60d511746bd6c0d0366d4eb90a7998bcde8b upstream. + +When 'kzalloc()' fails in 'snd_hda_attach_pcm_stream()', a new pcm instance is +created without setting its operators via 'snd_pcm_set_ops()'. Following +operations on the new pcm instance can trigger kernel null pointer dereferences +and cause kernel oops. + +This bug was found with my work on building a gray-box fault-injection tool for +linux-kernel-module binaries. A kernel null pointer dereference was confirmed +from line 'substream->ops->open()' in function 'snd_pcm_open_substream()' in +file 'sound/core/pcm_native.c'. + +This patch fixes the bug by calling 'snd_device_free()' in the error handling +path of 'kzalloc()', which removes the new pcm instance from the snd card before +returns with an error code. + +Signed-off-by: Bo Chen +Cc: +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman + +--- + sound/pci/hda/hda_controller.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/sound/pci/hda/hda_controller.c ++++ b/sound/pci/hda/hda_controller.c +@@ -748,8 +748,10 @@ int snd_hda_attach_pcm_stream(struct hda + return err; + strlcpy(pcm->name, cpcm->name, sizeof(pcm->name)); + apcm = kzalloc(sizeof(*apcm), GFP_KERNEL); +- if (apcm == NULL) ++ if (apcm == NULL) { ++ snd_device_free(chip->card, pcm); + return -ENOMEM; ++ } + apcm->chip = chip; + apcm->pcm = pcm; + apcm->codec = codec; diff --git a/queue-4.14/alsa-hda-realtek-enable-mic-mute-hotkey-for-several-lenovo-aios.patch b/queue-4.14/alsa-hda-realtek-enable-mic-mute-hotkey-for-several-lenovo-aios.patch new file mode 100644 index 00000000000..0ba88434cf4 --- /dev/null +++ b/queue-4.14/alsa-hda-realtek-enable-mic-mute-hotkey-for-several-lenovo-aios.patch @@ -0,0 +1,46 @@ +From 986376b68dcc95bb7df60ad30c2353c1f7578fa5 Mon Sep 17 00:00:00 2001 +From: Hui Wang +Date: Wed, 30 May 2018 12:33:07 +0800 +Subject: ALSA: hda/realtek - Enable mic-mute hotkey for several Lenovo AIOs + +From: Hui Wang + +commit 986376b68dcc95bb7df60ad30c2353c1f7578fa5 upstream. + +We have several Lenovo AIOs like M810z, M820z and M920z, they have +the same design for mic-mute hotkey and led and they use the same +codec with the same pin configuration, so use the pin conf table to +apply fix to all of them. + +Fixes: 29693efcea0f ("ALSA: hda - Fix micmute hotkey problem for a lenovo AIO machine") +Cc: +Signed-off-by: Hui Wang +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman + +--- + sound/pci/hda/patch_realtek.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -6439,7 +6439,6 @@ static const struct snd_pci_quirk alc269 + SND_PCI_QUIRK(0x17aa, 0x312f, "ThinkCentre Station", ALC294_FIXUP_LENOVO_MIC_LOCATION), + SND_PCI_QUIRK(0x17aa, 0x3138, "ThinkCentre Station", ALC294_FIXUP_LENOVO_MIC_LOCATION), + SND_PCI_QUIRK(0x17aa, 0x313c, "ThinkCentre Station", ALC294_FIXUP_LENOVO_MIC_LOCATION), +- SND_PCI_QUIRK(0x17aa, 0x3112, "ThinkCentre AIO", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY), + SND_PCI_QUIRK(0x17aa, 0x3902, "Lenovo E50-80", ALC269_FIXUP_DMIC_THINKPAD_ACPI), + SND_PCI_QUIRK(0x17aa, 0x3977, "IdeaPad S210", ALC283_FIXUP_INT_MIC), + SND_PCI_QUIRK(0x17aa, 0x3978, "IdeaPad Y410P", ALC269_FIXUP_NO_SHUTUP), +@@ -6610,6 +6609,11 @@ static const struct snd_hda_pin_quirk al + {0x12, 0x90a60140}, + {0x14, 0x90170110}, + {0x21, 0x02211020}), ++ SND_HDA_PIN_QUIRK(0x10ec0235, 0x17aa, "Lenovo", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY, ++ {0x12, 0x90a60140}, ++ {0x14, 0x90170110}, ++ {0x19, 0x02a11030}, ++ {0x21, 0x02211020}), + SND_HDA_PIN_QUIRK(0x10ec0236, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE, + {0x12, 0x90a60140}, + {0x14, 0x90170150}, diff --git a/queue-4.14/btrfs-fix-clone-vs-chattr-nodatasum-race.patch b/queue-4.14/btrfs-fix-clone-vs-chattr-nodatasum-race.patch new file mode 100644 index 00000000000..cf0fdfd7436 --- /dev/null +++ b/queue-4.14/btrfs-fix-clone-vs-chattr-nodatasum-race.patch @@ -0,0 +1,67 @@ +From b5c40d598f5408bd0ca22dfffa82f03cd9433f23 Mon Sep 17 00:00:00 2001 +From: Omar Sandoval +Date: Tue, 22 May 2018 15:02:12 -0700 +Subject: Btrfs: fix clone vs chattr NODATASUM race + +From: Omar Sandoval + +commit b5c40d598f5408bd0ca22dfffa82f03cd9433f23 upstream. + +In btrfs_clone_files(), we must check the NODATASUM flag while the +inodes are locked. Otherwise, it's possible that btrfs_ioctl_setflags() +will change the flags after we check and we can end up with a party +checksummed file. + +The race window is only a few instructions in size, between the if and +the locks which is: + +3834 if (S_ISDIR(src->i_mode) || S_ISDIR(inode->i_mode)) +3835 return -EISDIR; + +where the setflags must be run and toggle the NODATASUM flag (provided +the file size is 0). The clone will block on the inode lock, segflags +takes the inode lock, changes flags, releases log and clone continues. + +Not impossible but still needs a lot of bad luck to hit unintentionally. + +Fixes: 0e7b824c4ef9 ("Btrfs: don't make a file partly checksummed through file clone") +CC: stable@vger.kernel.org # 4.4+ +Signed-off-by: Omar Sandoval +Reviewed-by: Nikolay Borisov +Reviewed-by: David Sterba +[ update changelog ] +Signed-off-by: David Sterba +Signed-off-by: Greg Kroah-Hartman + +--- + fs/btrfs/ioctl.c | 12 +++++++----- + 1 file changed, 7 insertions(+), 5 deletions(-) + +--- a/fs/btrfs/ioctl.c ++++ b/fs/btrfs/ioctl.c +@@ -3861,11 +3861,6 @@ static noinline int btrfs_clone_files(st + src->i_sb != inode->i_sb) + return -EXDEV; + +- /* don't make the dst file partly checksummed */ +- if ((BTRFS_I(src)->flags & BTRFS_INODE_NODATASUM) != +- (BTRFS_I(inode)->flags & BTRFS_INODE_NODATASUM)) +- return -EINVAL; +- + if (S_ISDIR(src->i_mode) || S_ISDIR(inode->i_mode)) + return -EISDIR; + +@@ -3875,6 +3870,13 @@ static noinline int btrfs_clone_files(st + inode_lock(src); + } + ++ /* don't make the dst file partly checksummed */ ++ if ((BTRFS_I(src)->flags & BTRFS_INODE_NODATASUM) != ++ (BTRFS_I(inode)->flags & BTRFS_INODE_NODATASUM)) { ++ ret = -EINVAL; ++ goto out_unlock; ++ } ++ + /* determine range to clone */ + ret = -EINVAL; + if (off + len > src->i_size || off + len < off) diff --git a/queue-4.14/btrfs-fix-memory-and-mount-leak-in-btrfs_ioctl_rm_dev_v2.patch b/queue-4.14/btrfs-fix-memory-and-mount-leak-in-btrfs_ioctl_rm_dev_v2.patch new file mode 100644 index 00000000000..93208d24724 --- /dev/null +++ b/queue-4.14/btrfs-fix-memory-and-mount-leak-in-btrfs_ioctl_rm_dev_v2.patch @@ -0,0 +1,83 @@ +From fd4e994bd1f9dc9628e168a7f619bf69f6984635 Mon Sep 17 00:00:00 2001 +From: Omar Sandoval +Date: Tue, 22 May 2018 15:44:01 -0700 +Subject: Btrfs: fix memory and mount leak in btrfs_ioctl_rm_dev_v2() + +From: Omar Sandoval + +commit fd4e994bd1f9dc9628e168a7f619bf69f6984635 upstream. + +If we have invalid flags set, when we error out we must drop our writer +counter and free the buffer we allocated for the arguments. This bug is +trivially reproduced with the following program on 4.7+: + + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + + int main(int argc, char **argv) + { + struct btrfs_ioctl_vol_args_v2 vol_args = { + .flags = UINT64_MAX, + }; + int ret; + int fd; + + if (argc != 2) { + fprintf(stderr, "usage: %s PATH\n", argv[0]); + return EXIT_FAILURE; + } + + fd = open(argv[1], O_WRONLY); + if (fd == -1) { + perror("open"); + return EXIT_FAILURE; + } + + ret = ioctl(fd, BTRFS_IOC_RM_DEV_V2, &vol_args); + if (ret == -1) + perror("ioctl"); + + close(fd); + return EXIT_SUCCESS; + } + +When unmounting the filesystem, we'll hit the +WARN_ON(mnt_get_writers(mnt)) in cleanup_mnt() and also may prevent the +filesystem to be remounted read-only as the writer count will stay +lifted. + +Fixes: 6b526ed70cf1 ("btrfs: introduce device delete by devid") +CC: stable@vger.kernel.org # 4.9+ +Signed-off-by: Omar Sandoval +Reviewed-by: Su Yue +Reviewed-by: David Sterba +Signed-off-by: David Sterba +Signed-off-by: Greg Kroah-Hartman + +--- + fs/btrfs/ioctl.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +--- a/fs/btrfs/ioctl.c ++++ b/fs/btrfs/ioctl.c +@@ -2682,8 +2682,10 @@ static long btrfs_ioctl_rm_dev_v2(struct + } + + /* Check for compatibility reject unknown flags */ +- if (vol_args->flags & ~BTRFS_VOL_ARG_V2_FLAGS_SUPPORTED) +- return -EOPNOTSUPP; ++ if (vol_args->flags & ~BTRFS_VOL_ARG_V2_FLAGS_SUPPORTED) { ++ ret = -EOPNOTSUPP; ++ goto out; ++ } + + if (test_and_set_bit(BTRFS_FS_EXCL_OP, &fs_info->flags)) { + ret = BTRFS_ERROR_DEV_EXCL_RUN_IN_PROGRESS; diff --git a/queue-4.14/btrfs-return-error-value-if-create_io_em-failed-in-cow_file_range.patch b/queue-4.14/btrfs-return-error-value-if-create_io_em-failed-in-cow_file_range.patch new file mode 100644 index 00000000000..c1f3f268447 --- /dev/null +++ b/queue-4.14/btrfs-return-error-value-if-create_io_em-failed-in-cow_file_range.patch @@ -0,0 +1,40 @@ +From 090a127afa8f73e9618d4058d6755f7ec7453dd6 Mon Sep 17 00:00:00 2001 +From: Su Yue +Date: Wed, 30 May 2018 16:48:56 +0800 +Subject: btrfs: return error value if create_io_em failed in cow_file_range + +From: Su Yue + +commit 090a127afa8f73e9618d4058d6755f7ec7453dd6 upstream. + +In cow_file_range(), create_io_em() may fail, but its return value is +not recorded. Then return value may be 0 even it failed which is a +wrong behavior. + +Let cow_file_range() return PTR_ERR(em) if create_io_em() failed. + +Fixes: 6f9994dbabe5 ("Btrfs: create a helper to create em for IO") +CC: stable@vger.kernel.org # 4.11+ +Signed-off-by: Su Yue +Reviewed-by: Nikolay Borisov +Signed-off-by: David Sterba +Signed-off-by: Greg Kroah-Hartman + +--- + fs/btrfs/inode.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/fs/btrfs/inode.c ++++ b/fs/btrfs/inode.c +@@ -1027,8 +1027,10 @@ static noinline int cow_file_range(struc + ram_size, /* ram_bytes */ + BTRFS_COMPRESS_NONE, /* compress_type */ + BTRFS_ORDERED_REGULAR /* type */); +- if (IS_ERR(em)) ++ if (IS_ERR(em)) { ++ ret = PTR_ERR(em); + goto out_reserve; ++ } + free_extent_map(em); + + ret = btrfs_add_ordered_extent(inode, start, ins.objectid, diff --git a/queue-4.14/btrfs-scrub-don-t-use-inode-pages-for-device-replace.patch b/queue-4.14/btrfs-scrub-don-t-use-inode-pages-for-device-replace.patch new file mode 100644 index 00000000000..f404319918b --- /dev/null +++ b/queue-4.14/btrfs-scrub-don-t-use-inode-pages-for-device-replace.patch @@ -0,0 +1,67 @@ +From ac0b4145d662a3b9e34085dea460fb06ede9b69b Mon Sep 17 00:00:00 2001 +From: Qu Wenruo +Date: Tue, 5 Jun 2018 12:36:56 +0800 +Subject: btrfs: scrub: Don't use inode pages for device replace + +From: Qu Wenruo + +commit ac0b4145d662a3b9e34085dea460fb06ede9b69b upstream. + +[BUG] +Btrfs can create compressed extent without checksum (even though it +shouldn't), and if we then try to replace device containing such extent, +the result device will contain all the uncompressed data instead of the +compressed one. + +Test case already submitted to fstests: +https://patchwork.kernel.org/patch/10442353/ + +[CAUSE] +When handling compressed extent without checksum, device replace will +goe into copy_nocow_pages() function. + +In that function, btrfs will get all inodes referring to this data +extents and then use find_or_create_page() to get pages direct from that +inode. + +The problem here is, pages directly from inode are always uncompressed. +And for compressed data extent, they mismatch with on-disk data. +Thus this leads to corrupted compressed data extent written to replace +device. + +[FIX] +In this attempt, we could just remove the "optimization" branch, and let +unified scrub_pages() to handle it. + +Although scrub_pages() won't bother reusing page cache, it will be a +little slower, but it does the correct csum checking and won't cause +such data corruption caused by "optimization". + +Note about the fix: this is the minimal fix that can be backported to +older stable trees without conflicts. The whole callchain from +copy_nocow_pages() can be deleted, and will be in followup patches. + +Fixes: ff023aac3119 ("Btrfs: add code to scrub to copy read data to another disk") +CC: stable@vger.kernel.org # 4.4+ +Reported-by: James Harvey +Reviewed-by: James Harvey +Signed-off-by: Qu Wenruo +[ remove code removal, add note why ] +Signed-off-by: David Sterba +Signed-off-by: Greg Kroah-Hartman + +--- + fs/btrfs/scrub.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/fs/btrfs/scrub.c ++++ b/fs/btrfs/scrub.c +@@ -2775,7 +2775,7 @@ static int scrub_extent(struct scrub_ctx + have_csum = scrub_find_csum(sctx, logical, csum); + if (have_csum == 0) + ++sctx->stat.no_csum; +- if (sctx->is_dev_replace && !have_csum) { ++ if (0 && sctx->is_dev_replace && !have_csum) { + ret = copy_nocow_pages(sctx, logical, l, + mirror_num, + physical_for_dev_replace); diff --git a/queue-4.14/driver-core-don-t-ignore-class_dir_create_and_add-failure.patch b/queue-4.14/driver-core-don-t-ignore-class_dir_create_and_add-failure.patch new file mode 100644 index 00000000000..ab5298b5f92 --- /dev/null +++ b/queue-4.14/driver-core-don-t-ignore-class_dir_create_and_add-failure.patch @@ -0,0 +1,79 @@ +From 84d0c27d6233a9ba0578b20f5a09701eb66cee42 Mon Sep 17 00:00:00 2001 +From: Tetsuo Handa +Date: Mon, 7 May 2018 19:10:31 +0900 +Subject: driver core: Don't ignore class_dir_create_and_add() failure. + +From: Tetsuo Handa + +commit 84d0c27d6233a9ba0578b20f5a09701eb66cee42 upstream. + +syzbot is hitting WARN() at kernfs_add_one() [1]. +This is because kernfs_create_link() is confused by previous device_add() +call which continued without setting dev->kobj.parent field when +get_device_parent() failed by memory allocation fault injection. +Fix this by propagating the error from class_dir_create_and_add() to +the calllers of get_device_parent(). + +[1] https://syzkaller.appspot.com/bug?id=fae0fb607989ea744526d1c082a5b8de6529116f + +Signed-off-by: Tetsuo Handa +Reported-by: syzbot +Cc: Greg Kroah-Hartman +Cc: stable +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/base/core.c | 14 ++++++++++++-- + 1 file changed, 12 insertions(+), 2 deletions(-) + +--- a/drivers/base/core.c ++++ b/drivers/base/core.c +@@ -1461,7 +1461,7 @@ class_dir_create_and_add(struct class *c + + dir = kzalloc(sizeof(*dir), GFP_KERNEL); + if (!dir) +- return NULL; ++ return ERR_PTR(-ENOMEM); + + dir->class = class; + kobject_init(&dir->kobj, &class_dir_ktype); +@@ -1471,7 +1471,7 @@ class_dir_create_and_add(struct class *c + retval = kobject_add(&dir->kobj, parent_kobj, "%s", class->name); + if (retval < 0) { + kobject_put(&dir->kobj); +- return NULL; ++ return ERR_PTR(retval); + } + return &dir->kobj; + } +@@ -1778,6 +1778,10 @@ int device_add(struct device *dev) + + parent = get_device(dev->parent); + kobj = get_device_parent(dev, parent); ++ if (IS_ERR(kobj)) { ++ error = PTR_ERR(kobj); ++ goto parent_error; ++ } + if (kobj) + dev->kobj.parent = kobj; + +@@ -1876,6 +1880,7 @@ done: + kobject_del(&dev->kobj); + Error: + cleanup_glue_dir(dev, glue_dir); ++parent_error: + put_device(parent); + name_error: + kfree(dev->p); +@@ -2695,6 +2700,11 @@ int device_move(struct device *dev, stru + device_pm_lock(); + new_parent = get_device(new_parent); + new_parent_kobj = get_device_parent(dev, new_parent); ++ if (IS_ERR(new_parent_kobj)) { ++ error = PTR_ERR(new_parent_kobj); ++ put_device(new_parent); ++ goto out; ++ } + + pr_debug("device: '%s': %s: moving to '%s'\n", dev_name(dev), + __func__, new_parent ? dev_name(new_parent) : ""); diff --git a/queue-4.14/ext4-bubble-errors-from-ext4_find_inline_data_nolock-up-to-ext4_iget.patch b/queue-4.14/ext4-bubble-errors-from-ext4_find_inline_data_nolock-up-to-ext4_iget.patch new file mode 100644 index 00000000000..8c0f5f58c4b --- /dev/null +++ b/queue-4.14/ext4-bubble-errors-from-ext4_find_inline_data_nolock-up-to-ext4_iget.patch @@ -0,0 +1,65 @@ +From eb9b5f01c33adebc31cbc236c02695f605b0e417 Mon Sep 17 00:00:00 2001 +From: Theodore Ts'o +Date: Tue, 22 May 2018 17:14:07 -0400 +Subject: ext4: bubble errors from ext4_find_inline_data_nolock() up to ext4_iget() + +From: Theodore Ts'o + +commit eb9b5f01c33adebc31cbc236c02695f605b0e417 upstream. + +If ext4_find_inline_data_nolock() returns an error it needs to get +reflected up to ext4_iget(). In order to fix this, +ext4_iget_extra_inode() needs to return an error (and not return +void). + +This is related to "ext4: do not allow external inodes for inline +data" (which fixes CVE-2018-11412) in that in the errors=continue +case, it would be useful to for userspace to receive an error +indicating that file system is corrupted. + +Signed-off-by: Theodore Ts'o +Reviewed-by: Andreas Dilger +Cc: stable@kernel.org +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ext4/inode.c | 10 +++++++--- + 1 file changed, 7 insertions(+), 3 deletions(-) + +--- a/fs/ext4/inode.c ++++ b/fs/ext4/inode.c +@@ -4634,19 +4634,21 @@ static blkcnt_t ext4_inode_blocks(struct + } + } + +-static inline void ext4_iget_extra_inode(struct inode *inode, ++static inline int ext4_iget_extra_inode(struct inode *inode, + struct ext4_inode *raw_inode, + struct ext4_inode_info *ei) + { + __le32 *magic = (void *)raw_inode + + EXT4_GOOD_OLD_INODE_SIZE + ei->i_extra_isize; ++ + if (EXT4_GOOD_OLD_INODE_SIZE + ei->i_extra_isize + sizeof(__le32) <= + EXT4_INODE_SIZE(inode->i_sb) && + *magic == cpu_to_le32(EXT4_XATTR_MAGIC)) { + ext4_set_inode_state(inode, EXT4_STATE_XATTR); +- ext4_find_inline_data_nolock(inode); ++ return ext4_find_inline_data_nolock(inode); + } else + EXT4_I(inode)->i_inline_off = 0; ++ return 0; + } + + int ext4_get_projid(struct inode *inode, kprojid_t *projid) +@@ -4826,7 +4828,9 @@ struct inode *ext4_iget(struct super_blo + ei->i_extra_isize = sizeof(struct ext4_inode) - + EXT4_GOOD_OLD_INODE_SIZE; + } else { +- ext4_iget_extra_inode(inode, raw_inode, ei); ++ ret = ext4_iget_extra_inode(inode, raw_inode, ei); ++ if (ret) ++ goto bad_inode; + } + } + diff --git a/queue-4.14/ext4-correctly-handle-a-zero-length-xattr-with-a-non-zero-e_value_offs.patch b/queue-4.14/ext4-correctly-handle-a-zero-length-xattr-with-a-non-zero-e_value_offs.patch new file mode 100644 index 00000000000..c90a86e8f1d --- /dev/null +++ b/queue-4.14/ext4-correctly-handle-a-zero-length-xattr-with-a-non-zero-e_value_offs.patch @@ -0,0 +1,69 @@ +From 8a2b307c21d4b290e3cbe33f768f194286d07c23 Mon Sep 17 00:00:00 2001 +From: Theodore Ts'o +Date: Wed, 23 May 2018 11:31:03 -0400 +Subject: ext4: correctly handle a zero-length xattr with a non-zero e_value_offs + +From: Theodore Ts'o + +commit 8a2b307c21d4b290e3cbe33f768f194286d07c23 upstream. + +Ext4 will always create ext4 extended attributes which do not have a +value (where e_value_size is zero) with e_value_offs set to zero. In +most places e_value_offs will not be used in a substantive way if +e_value_size is zero. + +There was one exception to this, which is in ext4_xattr_set_entry(), +where if there is a maliciously crafted file system where there is an +extended attribute with e_value_offs is non-zero and e_value_size is +0, the attempt to remove this xattr will result in a negative value +getting passed to memmove, leading to the following sadness: + +[ 41.225365] EXT4-fs (loop0): mounted filesystem with ordered data mode. Opts: (null) +[ 44.538641] BUG: unable to handle kernel paging request at ffff9ec9a3000000 +[ 44.538733] IP: __memmove+0x81/0x1a0 +[ 44.538755] PGD 1249bd067 P4D 1249bd067 PUD 1249c1067 PMD 80000001230000e1 +[ 44.538793] Oops: 0003 [#1] SMP PTI +[ 44.539074] CPU: 0 PID: 1470 Comm: poc Not tainted 4.16.0-rc1+ #1 + ... +[ 44.539475] Call Trace: +[ 44.539832] ext4_xattr_set_entry+0x9e7/0xf80 + ... +[ 44.539972] ext4_xattr_block_set+0x212/0xea0 + ... +[ 44.540041] ext4_xattr_set_handle+0x514/0x610 +[ 44.540065] ext4_xattr_set+0x7f/0x120 +[ 44.540090] __vfs_removexattr+0x4d/0x60 +[ 44.540112] vfs_removexattr+0x75/0xe0 +[ 44.540132] removexattr+0x4d/0x80 + ... +[ 44.540279] path_removexattr+0x91/0xb0 +[ 44.540300] SyS_removexattr+0xf/0x20 +[ 44.540322] do_syscall_64+0x71/0x120 +[ 44.540344] entry_SYSCALL_64_after_hwframe+0x21/0x86 + +https://bugzilla.kernel.org/show_bug.cgi?id=199347 + +This addresses CVE-2018-10840. + +Reported-by: "Xu, Wen" +Signed-off-by: Theodore Ts'o +Reviewed-by: Andreas Dilger +Cc: stable@kernel.org +Fixes: dec214d00e0d7 ("ext4: xattr inode deduplication") +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ext4/xattr.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/fs/ext4/xattr.c ++++ b/fs/ext4/xattr.c +@@ -1687,7 +1687,7 @@ static int ext4_xattr_set_entry(struct e + + /* No failures allowed past this point. */ + +- if (!s->not_found && here->e_value_offs) { ++ if (!s->not_found && here->e_value_size && here->e_value_offs) { + /* Remove the old value. */ + void *first_val = s->base + min_offs; + size_t offs = le16_to_cpu(here->e_value_offs); diff --git a/queue-4.14/ext4-do-not-allow-external-inodes-for-inline-data.patch b/queue-4.14/ext4-do-not-allow-external-inodes-for-inline-data.patch new file mode 100644 index 00000000000..d05b0557e08 --- /dev/null +++ b/queue-4.14/ext4-do-not-allow-external-inodes-for-inline-data.patch @@ -0,0 +1,48 @@ +From 117166efb1ee8f13c38f9e96b258f16d4923f888 Mon Sep 17 00:00:00 2001 +From: Theodore Ts'o +Date: Tue, 22 May 2018 16:15:24 -0400 +Subject: ext4: do not allow external inodes for inline data + +From: Theodore Ts'o + +commit 117166efb1ee8f13c38f9e96b258f16d4923f888 upstream. + +The inline data feature was implemented before we added support for +external inodes for xattrs. It makes no sense to support that +combination, but the problem is that there are a number of extended +attribute checks that are skipped if e_value_inum is non-zero. + +Unfortunately, the inline data code is completely e_value_inum +unaware, and attempts to interpret the xattr fields as if it were an +inline xattr --- at which point, Hilarty Ensues. + +This addresses CVE-2018-11412. + +https://bugzilla.kernel.org/show_bug.cgi?id=199803 + +Reported-by: Jann Horn +Reviewed-by: Andreas Dilger +Signed-off-by: Theodore Ts'o +Fixes: e50e5129f384 ("ext4: xattr-in-inode support") +Cc: stable@kernel.org +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ext4/inline.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +--- a/fs/ext4/inline.c ++++ b/fs/ext4/inline.c +@@ -150,6 +150,12 @@ int ext4_find_inline_data_nolock(struct + goto out; + + if (!is.s.not_found) { ++ if (is.s.here->e_value_inum) { ++ EXT4_ERROR_INODE(inode, "inline data xattr refers " ++ "to an external xattr inode"); ++ error = -EFSCORRUPTED; ++ goto out; ++ } + EXT4_I(inode)->i_inline_off = (u16)((void *)is.s.here - + (void *)ext4_raw_inode(&is.iloc)); + EXT4_I(inode)->i_inline_size = EXT4_MIN_INLINE_DATA_SIZE + diff --git a/queue-4.14/ext4-fix-fencepost-error-in-check-for-inode-count-overflow-during-resize.patch b/queue-4.14/ext4-fix-fencepost-error-in-check-for-inode-count-overflow-during-resize.patch new file mode 100644 index 00000000000..f27aa335981 --- /dev/null +++ b/queue-4.14/ext4-fix-fencepost-error-in-check-for-inode-count-overflow-during-resize.patch @@ -0,0 +1,37 @@ +From 4f2f76f751433908364ccff82f437a57d0e6e9b7 Mon Sep 17 00:00:00 2001 +From: Jan Kara +Date: Fri, 25 May 2018 12:51:25 -0400 +Subject: ext4: fix fencepost error in check for inode count overflow during resize + +From: Jan Kara + +commit 4f2f76f751433908364ccff82f437a57d0e6e9b7 upstream. + +ext4_resize_fs() has an off-by-one bug when checking whether growing of +a filesystem will not overflow inode count. As a result it allows a +filesystem with 8192 inodes per group to grow to 64TB which overflows +inode count to 0 and makes filesystem unusable. Fix it. + +Cc: stable@vger.kernel.org +Fixes: 3f8a6411fbada1fa482276591e037f3b1adcf55b +Reported-by: Jaco Kroon +Signed-off-by: Jan Kara +Signed-off-by: Theodore Ts'o +Reviewed-by: Andreas Dilger +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ext4/resize.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/fs/ext4/resize.c ++++ b/fs/ext4/resize.c +@@ -1905,7 +1905,7 @@ retry: + return 0; + + n_group = ext4_get_group_number(sb, n_blocks_count - 1); +- if (n_group > (0xFFFFFFFFUL / EXT4_INODES_PER_GROUP(sb))) { ++ if (n_group >= (0xFFFFFFFFUL / EXT4_INODES_PER_GROUP(sb))) { + ext4_warning(sb, "resize would cause inodes_count overflow"); + return -EINVAL; + } diff --git a/queue-4.14/ext4-fix-hole-length-detection-in-ext4_ind_map_blocks.patch b/queue-4.14/ext4-fix-hole-length-detection-in-ext4_ind_map_blocks.patch new file mode 100644 index 00000000000..538b640a6d8 --- /dev/null +++ b/queue-4.14/ext4-fix-hole-length-detection-in-ext4_ind_map_blocks.patch @@ -0,0 +1,52 @@ +From 2ee3ee06a8fd792765fa3267ddf928997797eec5 Mon Sep 17 00:00:00 2001 +From: Jan Kara +Date: Sat, 12 May 2018 19:55:00 -0400 +Subject: ext4: fix hole length detection in ext4_ind_map_blocks() + +From: Jan Kara + +commit 2ee3ee06a8fd792765fa3267ddf928997797eec5 upstream. + +When ext4_ind_map_blocks() computes a length of a hole, it doesn't count +with the fact that mapped offset may be somewhere in the middle of the +completely empty subtree. In such case it will return too large length +of the hole which then results in lseek(SEEK_DATA) to end up returning +an incorrect offset beyond the end of the hole. + +Fix the problem by correctly taking offset within a subtree into account +when computing a length of a hole. + +Fixes: facab4d9711e7aa3532cb82643803e8f1b9518e8 +CC: stable@vger.kernel.org +Reported-by: Jeff Mahoney +Signed-off-by: Jan Kara +Signed-off-by: Theodore Ts'o +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ext4/indirect.c | 14 ++++++++++---- + 1 file changed, 10 insertions(+), 4 deletions(-) + +--- a/fs/ext4/indirect.c ++++ b/fs/ext4/indirect.c +@@ -561,10 +561,16 @@ int ext4_ind_map_blocks(handle_t *handle + unsigned epb = inode->i_sb->s_blocksize / sizeof(u32); + int i; + +- /* Count number blocks in a subtree under 'partial' */ +- count = 1; +- for (i = 0; partial + i != chain + depth - 1; i++) +- count *= epb; ++ /* ++ * Count number blocks in a subtree under 'partial'. At each ++ * level we count number of complete empty subtrees beyond ++ * current offset and then descend into the subtree only ++ * partially beyond current offset. ++ */ ++ count = 0; ++ for (i = partial - chain + 1; i < depth; i++) ++ count = count * epb + (epb - offsets[i] - 1); ++ count++; + /* Fill in size of a hole we found */ + map->m_pblk = 0; + map->m_len = min_t(unsigned int, map->m_len, count); diff --git a/queue-4.14/ext4-update-mtime-in-ext4_punch_hole-even-if-no-blocks-are-released.patch b/queue-4.14/ext4-update-mtime-in-ext4_punch_hole-even-if-no-blocks-are-released.patch new file mode 100644 index 00000000000..0b1ef447834 --- /dev/null +++ b/queue-4.14/ext4-update-mtime-in-ext4_punch_hole-even-if-no-blocks-are-released.patch @@ -0,0 +1,77 @@ +From eee597ac931305eff3d3fd1d61d6aae553bc0984 Mon Sep 17 00:00:00 2001 +From: Lukas Czerner +Date: Sun, 13 May 2018 19:28:35 -0400 +Subject: ext4: update mtime in ext4_punch_hole even if no blocks are released + +From: Lukas Czerner + +commit eee597ac931305eff3d3fd1d61d6aae553bc0984 upstream. + +Currently in ext4_punch_hole we're going to skip the mtime update if +there are no actual blocks to release. However we've actually modified +the file by zeroing the partial block so the mtime should be updated. + +Moreover the sync and datasync handling is skipped as well, which is +also wrong. Fix it. + +Signed-off-by: Lukas Czerner +Signed-off-by: Theodore Ts'o +Reported-by: Joe Habermann +Cc: +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ext4/inode.c | 40 ++++++++++++++++++++-------------------- + 1 file changed, 20 insertions(+), 20 deletions(-) + +--- a/fs/ext4/inode.c ++++ b/fs/ext4/inode.c +@@ -4246,28 +4246,28 @@ int ext4_punch_hole(struct inode *inode, + EXT4_BLOCK_SIZE_BITS(sb); + stop_block = (offset + length) >> EXT4_BLOCK_SIZE_BITS(sb); + +- /* If there are no blocks to remove, return now */ +- if (first_block >= stop_block) +- goto out_stop; +- +- down_write(&EXT4_I(inode)->i_data_sem); +- ext4_discard_preallocations(inode); +- +- ret = ext4_es_remove_extent(inode, first_block, +- stop_block - first_block); +- if (ret) { +- up_write(&EXT4_I(inode)->i_data_sem); +- goto out_stop; +- } ++ /* If there are blocks to remove, do it */ ++ if (stop_block > first_block) { ++ ++ down_write(&EXT4_I(inode)->i_data_sem); ++ ext4_discard_preallocations(inode); + +- if (ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)) +- ret = ext4_ext_remove_space(inode, first_block, +- stop_block - 1); +- else +- ret = ext4_ind_remove_space(handle, inode, first_block, +- stop_block); ++ ret = ext4_es_remove_extent(inode, first_block, ++ stop_block - first_block); ++ if (ret) { ++ up_write(&EXT4_I(inode)->i_data_sem); ++ goto out_stop; ++ } ++ ++ if (ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)) ++ ret = ext4_ext_remove_space(inode, first_block, ++ stop_block - 1); ++ else ++ ret = ext4_ind_remove_space(handle, inode, first_block, ++ stop_block); + +- up_write(&EXT4_I(inode)->i_data_sem); ++ up_write(&EXT4_I(inode)->i_data_sem); ++ } + if (IS_SYNC(inode)) + ext4_handle_sync(handle); + diff --git a/queue-4.14/nfsv4.1-fix-up-replays-of-interrupted-requests.patch b/queue-4.14/nfsv4.1-fix-up-replays-of-interrupted-requests.patch new file mode 100644 index 00000000000..05026410063 --- /dev/null +++ b/queue-4.14/nfsv4.1-fix-up-replays-of-interrupted-requests.patch @@ -0,0 +1,328 @@ +From 3be0f80b5fe9c16eca2d538f799b94ca8aa59433 Mon Sep 17 00:00:00 2001 +From: Trond Myklebust +Date: Thu, 19 Oct 2017 15:46:45 -0400 +Subject: NFSv4.1: Fix up replays of interrupted requests + +From: Trond Myklebust + +commit 3be0f80b5fe9c16eca2d538f799b94ca8aa59433 upstream. + +If the previous request on a slot was interrupted before it was +processed by the server, then our slot sequence number may be out of whack, +and so we try the next operation using the old sequence number. + +The problem with this, is that not all servers check to see that the +client is replaying the same operations as previously when they decide +to go to the replay cache, and so instead of the expected error of +NFS4ERR_SEQ_FALSE_RETRY, we get a replay of the old reply, which could +(if the operations match up) be mistaken by the client for a new reply. + +To fix this, we attempt to send a COMPOUND containing only the SEQUENCE op +in order to resync our slot sequence number. + +Cc: Olga Kornievskaia +[olga.kornievskaia@gmail.com: fix an Oops] +Signed-off-by: Trond Myklebust +Signed-off-by: Anna Schumaker +Signed-off-by: Greg Kroah-Hartman + +--- + fs/nfs/nfs4_fs.h | 2 + fs/nfs/nfs4proc.c | 150 +++++++++++++++++++++++++++++++++++++----------------- + 2 files changed, 104 insertions(+), 48 deletions(-) + +--- a/fs/nfs/nfs4_fs.h ++++ b/fs/nfs/nfs4_fs.h +@@ -465,7 +465,7 @@ extern void nfs_increment_open_seqid(int + extern void nfs_increment_lock_seqid(int status, struct nfs_seqid *seqid); + extern void nfs_release_seqid(struct nfs_seqid *seqid); + extern void nfs_free_seqid(struct nfs_seqid *seqid); +-extern int nfs4_setup_sequence(const struct nfs_client *client, ++extern int nfs4_setup_sequence(struct nfs_client *client, + struct nfs4_sequence_args *args, + struct nfs4_sequence_res *res, + struct rpc_task *task); +--- a/fs/nfs/nfs4proc.c ++++ b/fs/nfs/nfs4proc.c +@@ -96,6 +96,10 @@ static int nfs4_do_setattr(struct inode + struct nfs_open_context *ctx, struct nfs4_label *ilabel, + struct nfs4_label *olabel); + #ifdef CONFIG_NFS_V4_1 ++static struct rpc_task *_nfs41_proc_sequence(struct nfs_client *clp, ++ struct rpc_cred *cred, ++ struct nfs4_slot *slot, ++ bool is_privileged); + static int nfs41_test_stateid(struct nfs_server *, nfs4_stateid *, + struct rpc_cred *); + static int nfs41_free_stateid(struct nfs_server *, const nfs4_stateid *, +@@ -641,13 +645,14 @@ static int nfs40_sequence_done(struct rp + + #if defined(CONFIG_NFS_V4_1) + +-static void nfs41_sequence_free_slot(struct nfs4_sequence_res *res) ++static void nfs41_release_slot(struct nfs4_slot *slot) + { + struct nfs4_session *session; + struct nfs4_slot_table *tbl; +- struct nfs4_slot *slot = res->sr_slot; + bool send_new_highest_used_slotid = false; + ++ if (!slot) ++ return; + tbl = slot->table; + session = tbl->session; + +@@ -673,13 +678,18 @@ static void nfs41_sequence_free_slot(str + send_new_highest_used_slotid = false; + out_unlock: + spin_unlock(&tbl->slot_tbl_lock); +- res->sr_slot = NULL; + if (send_new_highest_used_slotid) + nfs41_notify_server(session->clp); + if (waitqueue_active(&tbl->slot_waitq)) + wake_up_all(&tbl->slot_waitq); + } + ++static void nfs41_sequence_free_slot(struct nfs4_sequence_res *res) ++{ ++ nfs41_release_slot(res->sr_slot); ++ res->sr_slot = NULL; ++} ++ + static int nfs41_sequence_process(struct rpc_task *task, + struct nfs4_sequence_res *res) + { +@@ -707,13 +717,6 @@ static int nfs41_sequence_process(struct + /* Check the SEQUENCE operation status */ + switch (res->sr_status) { + case 0: +- /* If previous op on slot was interrupted and we reused +- * the seq# and got a reply from the cache, then retry +- */ +- if (task->tk_status == -EREMOTEIO && interrupted) { +- ++slot->seq_nr; +- goto retry_nowait; +- } + /* Update the slot's sequence and clientid lease timer */ + slot->seq_done = 1; + clp = session->clp; +@@ -747,16 +750,16 @@ static int nfs41_sequence_process(struct + * The slot id we used was probably retired. Try again + * using a different slot id. + */ ++ if (slot->seq_nr < slot->table->target_highest_slotid) ++ goto session_recover; + goto retry_nowait; + case -NFS4ERR_SEQ_MISORDERED: + /* + * Was the last operation on this sequence interrupted? + * If so, retry after bumping the sequence number. + */ +- if (interrupted) { +- ++slot->seq_nr; +- goto retry_nowait; +- } ++ if (interrupted) ++ goto retry_new_seq; + /* + * Could this slot have been previously retired? + * If so, then the server may be expecting seq_nr = 1! +@@ -765,10 +768,11 @@ static int nfs41_sequence_process(struct + slot->seq_nr = 1; + goto retry_nowait; + } +- break; ++ goto session_recover; + case -NFS4ERR_SEQ_FALSE_RETRY: +- ++slot->seq_nr; +- goto retry_nowait; ++ if (interrupted) ++ goto retry_new_seq; ++ goto session_recover; + default: + /* Just update the slot sequence no. */ + slot->seq_done = 1; +@@ -778,6 +782,11 @@ out: + dprintk("%s: Error %d free the slot \n", __func__, res->sr_status); + out_noaction: + return ret; ++session_recover: ++ nfs4_schedule_session_recovery(session, res->sr_status); ++ goto retry_nowait; ++retry_new_seq: ++ ++slot->seq_nr; + retry_nowait: + if (rpc_restart_call_prepare(task)) { + nfs41_sequence_free_slot(res); +@@ -854,6 +863,17 @@ static const struct rpc_call_ops nfs41_c + .rpc_call_done = nfs41_call_sync_done, + }; + ++static void ++nfs4_sequence_process_interrupted(struct nfs_client *client, ++ struct nfs4_slot *slot, struct rpc_cred *cred) ++{ ++ struct rpc_task *task; ++ ++ task = _nfs41_proc_sequence(client, cred, slot, true); ++ if (!IS_ERR(task)) ++ rpc_put_task_async(task); ++} ++ + #else /* !CONFIG_NFS_V4_1 */ + + static int nfs4_sequence_process(struct rpc_task *task, struct nfs4_sequence_res *res) +@@ -874,9 +894,34 @@ int nfs4_sequence_done(struct rpc_task * + } + EXPORT_SYMBOL_GPL(nfs4_sequence_done); + ++static void ++nfs4_sequence_process_interrupted(struct nfs_client *client, ++ struct nfs4_slot *slot, struct rpc_cred *cred) ++{ ++ WARN_ON_ONCE(1); ++ slot->interrupted = 0; ++} ++ + #endif /* !CONFIG_NFS_V4_1 */ + +-int nfs4_setup_sequence(const struct nfs_client *client, ++static ++void nfs4_sequence_attach_slot(struct nfs4_sequence_args *args, ++ struct nfs4_sequence_res *res, ++ struct nfs4_slot *slot) ++{ ++ if (!slot) ++ return; ++ slot->privileged = args->sa_privileged ? 1 : 0; ++ args->sa_slot = slot; ++ ++ res->sr_slot = slot; ++ res->sr_timestamp = jiffies; ++ res->sr_status_flags = 0; ++ res->sr_status = 1; ++ ++} ++ ++int nfs4_setup_sequence(struct nfs_client *client, + struct nfs4_sequence_args *args, + struct nfs4_sequence_res *res, + struct rpc_task *task) +@@ -894,30 +939,29 @@ int nfs4_setup_sequence(const struct nfs + task->tk_timeout = 0; + } + +- spin_lock(&tbl->slot_tbl_lock); +- /* The state manager will wait until the slot table is empty */ +- if (nfs4_slot_tbl_draining(tbl) && !args->sa_privileged) +- goto out_sleep; +- +- slot = nfs4_alloc_slot(tbl); +- if (IS_ERR(slot)) { +- /* Try again in 1/4 second */ +- if (slot == ERR_PTR(-ENOMEM)) +- task->tk_timeout = HZ >> 2; +- goto out_sleep; +- } +- spin_unlock(&tbl->slot_tbl_lock); +- +- slot->privileged = args->sa_privileged ? 1 : 0; +- args->sa_slot = slot; ++ for (;;) { ++ spin_lock(&tbl->slot_tbl_lock); ++ /* The state manager will wait until the slot table is empty */ ++ if (nfs4_slot_tbl_draining(tbl) && !args->sa_privileged) ++ goto out_sleep; ++ ++ slot = nfs4_alloc_slot(tbl); ++ if (IS_ERR(slot)) { ++ /* Try again in 1/4 second */ ++ if (slot == ERR_PTR(-ENOMEM)) ++ task->tk_timeout = HZ >> 2; ++ goto out_sleep; ++ } ++ spin_unlock(&tbl->slot_tbl_lock); + +- res->sr_slot = slot; +- if (session) { +- res->sr_timestamp = jiffies; +- res->sr_status_flags = 0; +- res->sr_status = 1; ++ if (likely(!slot->interrupted)) ++ break; ++ nfs4_sequence_process_interrupted(client, ++ slot, task->tk_msg.rpc_cred); + } + ++ nfs4_sequence_attach_slot(args, res, slot); ++ + trace_nfs4_setup_sequence(session, args); + out_start: + rpc_call_start(task); +@@ -8151,6 +8195,7 @@ static const struct rpc_call_ops nfs41_s + + static struct rpc_task *_nfs41_proc_sequence(struct nfs_client *clp, + struct rpc_cred *cred, ++ struct nfs4_slot *slot, + bool is_privileged) + { + struct nfs4_sequence_data *calldata; +@@ -8164,15 +8209,18 @@ static struct rpc_task *_nfs41_proc_sequ + .callback_ops = &nfs41_sequence_ops, + .flags = RPC_TASK_ASYNC | RPC_TASK_TIMEOUT, + }; ++ struct rpc_task *ret; + ++ ret = ERR_PTR(-EIO); + if (!atomic_inc_not_zero(&clp->cl_count)) +- return ERR_PTR(-EIO); ++ goto out_err; ++ ++ ret = ERR_PTR(-ENOMEM); + calldata = kzalloc(sizeof(*calldata), GFP_NOFS); +- if (calldata == NULL) { +- nfs_put_client(clp); +- return ERR_PTR(-ENOMEM); +- } ++ if (calldata == NULL) ++ goto out_put_clp; + nfs4_init_sequence(&calldata->args, &calldata->res, 0); ++ nfs4_sequence_attach_slot(&calldata->args, &calldata->res, slot); + if (is_privileged) + nfs4_set_sequence_privileged(&calldata->args); + msg.rpc_argp = &calldata->args; +@@ -8180,7 +8228,15 @@ static struct rpc_task *_nfs41_proc_sequ + calldata->clp = clp; + task_setup_data.callback_data = calldata; + +- return rpc_run_task(&task_setup_data); ++ ret = rpc_run_task(&task_setup_data); ++ if (IS_ERR(ret)) ++ goto out_err; ++ return ret; ++out_put_clp: ++ nfs_put_client(clp); ++out_err: ++ nfs41_release_slot(slot); ++ return ret; + } + + static int nfs41_proc_async_sequence(struct nfs_client *clp, struct rpc_cred *cred, unsigned renew_flags) +@@ -8190,7 +8246,7 @@ static int nfs41_proc_async_sequence(str + + if ((renew_flags & NFS4_RENEW_TIMEOUT) == 0) + return -EAGAIN; +- task = _nfs41_proc_sequence(clp, cred, false); ++ task = _nfs41_proc_sequence(clp, cred, NULL, false); + if (IS_ERR(task)) + ret = PTR_ERR(task); + else +@@ -8204,7 +8260,7 @@ static int nfs4_proc_sequence(struct nfs + struct rpc_task *task; + int ret; + +- task = _nfs41_proc_sequence(clp, cred, true); ++ task = _nfs41_proc_sequence(clp, cred, NULL, true); + if (IS_ERR(task)) { + ret = PTR_ERR(task); + goto out; diff --git a/queue-4.14/series b/queue-4.14/series index 87be79a6910..e008b89bf5b 100644 --- a/queue-4.14/series +++ b/queue-4.14/series @@ -9,3 +9,21 @@ udp-fix-rx-queue-len-reported-by-diag-and-proc-interface.patch net-in-virtio_net_hdr-only-add-vlan_hlen-to-csum_start-if-payload-holds-vlan.patch hv_netvsc-fix-a-network-regression-after-ifdown-ifup.patch tls-fix-use-after-free-in-tls_push_record.patch +nfsv4.1-fix-up-replays-of-interrupted-requests.patch +ext4-fix-hole-length-detection-in-ext4_ind_map_blocks.patch +ext4-update-mtime-in-ext4_punch_hole-even-if-no-blocks-are-released.patch +ext4-do-not-allow-external-inodes-for-inline-data.patch +ext4-bubble-errors-from-ext4_find_inline_data_nolock-up-to-ext4_iget.patch +ext4-correctly-handle-a-zero-length-xattr-with-a-non-zero-e_value_offs.patch +ext4-fix-fencepost-error-in-check-for-inode-count-overflow-during-resize.patch +driver-core-don-t-ignore-class_dir_create_and_add-failure.patch +btrfs-fix-clone-vs-chattr-nodatasum-race.patch +btrfs-fix-memory-and-mount-leak-in-btrfs_ioctl_rm_dev_v2.patch +btrfs-return-error-value-if-create_io_em-failed-in-cow_file_range.patch +btrfs-scrub-don-t-use-inode-pages-for-device-replace.patch +alsa-hda-realtek-enable-mic-mute-hotkey-for-several-lenovo-aios.patch +alsa-hda-conexant-add-fixup-for-hp-z2-g4-workstation.patch +alsa-hda-handle-kzalloc-failure-in-snd_hda_attach_pcm_stream.patch +alsa-hda-add-dock-and-led-support-for-hp-elitebook-830-g5.patch +alsa-hda-add-dock-and-led-support-for-hp-probook-640-g4.patch +x86-mce-fix-stack-out-of-bounds-write-in-mce-inject.c-flags_read.patch diff --git a/queue-4.14/x86-mce-fix-stack-out-of-bounds-write-in-mce-inject.c-flags_read.patch b/queue-4.14/x86-mce-fix-stack-out-of-bounds-write-in-mce-inject.c-flags_read.patch new file mode 100644 index 00000000000..83ba9f7c12c --- /dev/null +++ b/queue-4.14/x86-mce-fix-stack-out-of-bounds-write-in-mce-inject.c-flags_read.patch @@ -0,0 +1,46 @@ +From 985c78d3ff8e9c74450fa2bb08eb55e680d999ca Mon Sep 17 00:00:00 2001 +From: "Luck, Tony" +Date: Fri, 27 Apr 2018 09:37:08 -0700 +Subject: x86/MCE: Fix stack out-of-bounds write in mce-inject.c: Flags_read() + +From: Tony Luck + +commit 985c78d3ff8e9c74450fa2bb08eb55e680d999ca upstream. + +Each of the strings that we want to put into the buf[MAX_FLAG_OPT_SIZE] +in flags_read() is two characters long. But the sprintf() adds +a trailing newline and will add a terminating NUL byte. So +MAX_FLAG_OPT_SIZE needs to be 4. + +sprintf() calls vsnprintf() and *that* does return: + +" * The return value is the number of characters which would + * be generated for the given input, excluding the trailing + * '\0', as per ISO C99." + +Note the "excluding". + +Reported-by: Dmitry Vyukov +Signed-off-by: Tony Luck +Signed-off-by: Borislav Petkov +Signed-off-by: Thomas Gleixner +Cc: stable@vger.kernel.org +Cc: linux-edac +Link: http://lkml.kernel.org/r/20180427163707.ktaiysvbk3yhk4wm@agluck-desk +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/kernel/cpu/mcheck/mce-inject.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/x86/kernel/cpu/mcheck/mce-inject.c ++++ b/arch/x86/kernel/cpu/mcheck/mce-inject.c +@@ -48,7 +48,7 @@ static struct dentry *dfs_inj; + + static u8 n_banks; + +-#define MAX_FLAG_OPT_SIZE 3 ++#define MAX_FLAG_OPT_SIZE 4 + #define NBCFG 0x44 + + enum injection_type {