--- /dev/null
+From fa33cdbf3eceb0206a4f844fe91aeebcf6ff2b7a Mon Sep 17 00:00:00 2001
+From: "Steven J. Magnani" <steve.magnani@digidescorp.com>
+Date: Sun, 30 Jun 2019 21:39:35 -0500
+Subject: udf: Fix incorrect final NOT_ALLOCATED (hole) extent length
+
+From: Steven J. Magnani <steve.magnani@digidescorp.com>
+
+commit fa33cdbf3eceb0206a4f844fe91aeebcf6ff2b7a upstream.
+
+In some cases, using the 'truncate' command to extend a UDF file results
+in a mismatch between the length of the file's extents (specifically, due
+to incorrect length of the final NOT_ALLOCATED extent) and the information
+(file) length. The discrepancy can prevent other operating systems
+(i.e., Windows 10) from opening the file.
+
+Two particular errors have been observed when extending a file:
+
+1. The final extent is larger than it should be, having been rounded up
+ to a multiple of the block size.
+
+B. The final extent is not shorter than it should be, due to not having
+ been updated when the file's information length was increased.
+
+[JK: simplified udf_do_extend_final_block(), fixed up some types]
+
+Fixes: 2c948b3f86e5 ("udf: Avoid IO in udf_clear_inode")
+CC: stable@vger.kernel.org
+Signed-off-by: Steven J. Magnani <steve@digidescorp.com>
+Link: https://lore.kernel.org/r/1561948775-5878-1-git-send-email-steve@digidescorp.com
+Signed-off-by: Jan Kara <jack@suse.cz>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/udf/inode.c | 93 ++++++++++++++++++++++++++++++++++++---------------------
+ 1 file changed, 60 insertions(+), 33 deletions(-)
+
+--- a/fs/udf/inode.c
++++ b/fs/udf/inode.c
+@@ -478,13 +478,15 @@ static struct buffer_head *udf_getblk(st
+ return NULL;
+ }
+
+-/* Extend the file by 'blocks' blocks, return the number of extents added */
++/* Extend the file with new blocks totaling 'new_block_bytes',
++ * return the number of extents added
++ */
+ static int udf_do_extend_file(struct inode *inode,
+ struct extent_position *last_pos,
+ struct kernel_long_ad *last_ext,
+- sector_t blocks)
++ loff_t new_block_bytes)
+ {
+- sector_t add;
++ uint32_t add;
+ int count = 0, fake = !(last_ext->extLength & UDF_EXTENT_LENGTH_MASK);
+ struct super_block *sb = inode->i_sb;
+ struct kernel_lb_addr prealloc_loc = {};
+@@ -494,7 +496,7 @@ static int udf_do_extend_file(struct ino
+
+ /* The previous extent is fake and we should not extend by anything
+ * - there's nothing to do... */
+- if (!blocks && fake)
++ if (!new_block_bytes && fake)
+ return 0;
+
+ iinfo = UDF_I(inode);
+@@ -525,13 +527,12 @@ static int udf_do_extend_file(struct ino
+ /* Can we merge with the previous extent? */
+ if ((last_ext->extLength & UDF_EXTENT_FLAG_MASK) ==
+ EXT_NOT_RECORDED_NOT_ALLOCATED) {
+- add = ((1 << 30) - sb->s_blocksize -
+- (last_ext->extLength & UDF_EXTENT_LENGTH_MASK)) >>
+- sb->s_blocksize_bits;
+- if (add > blocks)
+- add = blocks;
+- blocks -= add;
+- last_ext->extLength += add << sb->s_blocksize_bits;
++ add = (1 << 30) - sb->s_blocksize -
++ (last_ext->extLength & UDF_EXTENT_LENGTH_MASK);
++ if (add > new_block_bytes)
++ add = new_block_bytes;
++ new_block_bytes -= add;
++ last_ext->extLength += add;
+ }
+
+ if (fake) {
+@@ -552,28 +553,27 @@ static int udf_do_extend_file(struct ino
+ }
+
+ /* Managed to do everything necessary? */
+- if (!blocks)
++ if (!new_block_bytes)
+ goto out;
+
+ /* All further extents will be NOT_RECORDED_NOT_ALLOCATED */
+ last_ext->extLocation.logicalBlockNum = 0;
+ last_ext->extLocation.partitionReferenceNum = 0;
+- add = (1 << (30-sb->s_blocksize_bits)) - 1;
+- last_ext->extLength = EXT_NOT_RECORDED_NOT_ALLOCATED |
+- (add << sb->s_blocksize_bits);
++ add = (1 << 30) - sb->s_blocksize;
++ last_ext->extLength = EXT_NOT_RECORDED_NOT_ALLOCATED | add;
+
+ /* Create enough extents to cover the whole hole */
+- while (blocks > add) {
+- blocks -= add;
++ while (new_block_bytes > add) {
++ new_block_bytes -= add;
+ err = udf_add_aext(inode, last_pos, &last_ext->extLocation,
+ last_ext->extLength, 1);
+ if (err)
+ return err;
+ count++;
+ }
+- if (blocks) {
++ if (new_block_bytes) {
+ last_ext->extLength = EXT_NOT_RECORDED_NOT_ALLOCATED |
+- (blocks << sb->s_blocksize_bits);
++ new_block_bytes;
+ err = udf_add_aext(inode, last_pos, &last_ext->extLocation,
+ last_ext->extLength, 1);
+ if (err)
+@@ -604,6 +604,24 @@ out:
+ return count;
+ }
+
++/* Extend the final block of the file to final_block_len bytes */
++static void udf_do_extend_final_block(struct inode *inode,
++ struct extent_position *last_pos,
++ struct kernel_long_ad *last_ext,
++ uint32_t final_block_len)
++{
++ struct super_block *sb = inode->i_sb;
++ uint32_t added_bytes;
++
++ added_bytes = final_block_len -
++ (last_ext->extLength & (sb->s_blocksize - 1));
++ last_ext->extLength += added_bytes;
++ UDF_I(inode)->i_lenExtents += added_bytes;
++
++ udf_write_aext(inode, last_pos, &last_ext->extLocation,
++ last_ext->extLength, 1);
++}
++
+ static int udf_extend_file(struct inode *inode, loff_t newsize)
+ {
+
+@@ -613,10 +631,12 @@ static int udf_extend_file(struct inode
+ int8_t etype;
+ struct super_block *sb = inode->i_sb;
+ sector_t first_block = newsize >> sb->s_blocksize_bits, offset;
++ unsigned long partial_final_block;
+ int adsize;
+ struct udf_inode_info *iinfo = UDF_I(inode);
+ struct kernel_long_ad extent;
+- int err;
++ int err = 0;
++ int within_final_block;
+
+ if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT)
+ adsize = sizeof(struct short_ad);
+@@ -626,18 +646,8 @@ static int udf_extend_file(struct inode
+ BUG();
+
+ etype = inode_bmap(inode, first_block, &epos, &eloc, &elen, &offset);
++ within_final_block = (etype != -1);
+
+- /* File has extent covering the new size (could happen when extending
+- * inside a block)? */
+- if (etype != -1)
+- return 0;
+- if (newsize & (sb->s_blocksize - 1))
+- offset++;
+- /* Extended file just to the boundary of the last file block? */
+- if (offset == 0)
+- return 0;
+-
+- /* Truncate is extending the file by 'offset' blocks */
+ if ((!epos.bh && epos.offset == udf_file_entry_alloc_offset(inode)) ||
+ (epos.bh && epos.offset == sizeof(struct allocExtDesc))) {
+ /* File has no extents at all or has empty last
+@@ -651,7 +661,22 @@ static int udf_extend_file(struct inode
+ &extent.extLength, 0);
+ extent.extLength |= etype << 30;
+ }
+- err = udf_do_extend_file(inode, &epos, &extent, offset);
++
++ partial_final_block = newsize & (sb->s_blocksize - 1);
++
++ /* File has extent covering the new size (could happen when extending
++ * inside a block)?
++ */
++ if (within_final_block) {
++ /* Extending file within the last file block */
++ udf_do_extend_final_block(inode, &epos, &extent,
++ partial_final_block);
++ } else {
++ loff_t add = ((loff_t)offset << sb->s_blocksize_bits) |
++ partial_final_block;
++ err = udf_do_extend_file(inode, &epos, &extent, add);
++ }
++
+ if (err < 0)
+ goto out;
+ err = 0;
+@@ -756,6 +781,7 @@ static sector_t inode_getblk(struct inod
+ /* Are we beyond EOF? */
+ if (etype == -1) {
+ int ret;
++ loff_t hole_len;
+ isBeyondEOF = true;
+ if (count) {
+ if (c)
+@@ -771,7 +797,8 @@ static sector_t inode_getblk(struct inod
+ startnum = (offset > 0);
+ }
+ /* Create extents for the hole between EOF and offset */
+- ret = udf_do_extend_file(inode, &prev_epos, laarr, offset);
++ hole_len = (loff_t)offset << inode->i_blkbits;
++ ret = udf_do_extend_file(inode, &prev_epos, laarr, hole_len);
+ if (ret < 0) {
+ brelse(prev_epos.bh);
+ brelse(cur_epos.bh);
--- /dev/null
+From 31a2fbb390fee4231281b939e1979e810f945415 Mon Sep 17 00:00:00 2001
+From: Dianzhang Chen <dianzhangchen0@gmail.com>
+Date: Tue, 25 Jun 2019 23:30:17 +0800
+Subject: x86/ptrace: Fix possible spectre-v1 in ptrace_get_debugreg()
+
+From: Dianzhang Chen <dianzhangchen0@gmail.com>
+
+commit 31a2fbb390fee4231281b939e1979e810f945415 upstream.
+
+The index to access the threads ptrace_bps is controlled by userspace via
+syscall: sys_ptrace(), hence leading to a potential exploitation of the
+Spectre variant 1 vulnerability.
+
+The index can be controlled from:
+ ptrace -> arch_ptrace -> ptrace_get_debugreg.
+
+Fix this by sanitizing the user supplied index before using it access
+thread->ptrace_bps.
+
+Signed-off-by: Dianzhang Chen <dianzhangchen0@gmail.com>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Cc: bp@alien8.de
+Cc: hpa@zytor.com
+Cc: stable@vger.kernel.org
+Link: https://lkml.kernel.org/r/1561476617-3759-1-git-send-email-dianzhangchen0@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/x86/kernel/ptrace.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+--- a/arch/x86/kernel/ptrace.c
++++ b/arch/x86/kernel/ptrace.c
+@@ -23,6 +23,7 @@
+ #include <linux/rcupdate.h>
+ #include <linux/export.h>
+ #include <linux/context_tracking.h>
++#include <linux/nospec.h>
+
+ #include <asm/uaccess.h>
+ #include <asm/pgtable.h>
+@@ -650,9 +651,11 @@ static unsigned long ptrace_get_debugreg
+ {
+ struct thread_struct *thread = &tsk->thread;
+ unsigned long val = 0;
++ int index = n;
+
+ if (n < HBP_NUM) {
+- struct perf_event *bp = thread->ptrace_bps[n];
++ index = array_index_nospec(index, HBP_NUM);
++ struct perf_event *bp = thread->ptrace_bps[index];
+
+ if (bp)
+ val = bp->hw.info.address;
--- /dev/null
+From 993773d11d45c90cb1c6481c2638c3d9f092ea5b Mon Sep 17 00:00:00 2001
+From: Dianzhang Chen <dianzhangchen0@gmail.com>
+Date: Wed, 26 Jun 2019 12:50:30 +0800
+Subject: x86/tls: Fix possible spectre-v1 in do_get_thread_area()
+
+From: Dianzhang Chen <dianzhangchen0@gmail.com>
+
+commit 993773d11d45c90cb1c6481c2638c3d9f092ea5b upstream.
+
+The index to access the threads tls array is controlled by userspace
+via syscall: sys_ptrace(), hence leading to a potential exploitation
+of the Spectre variant 1 vulnerability.
+
+The index can be controlled from:
+ ptrace -> arch_ptrace -> do_get_thread_area.
+
+Fix this by sanitizing the user supplied index before using it to access
+the p->thread.tls_array.
+
+Signed-off-by: Dianzhang Chen <dianzhangchen0@gmail.com>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Cc: bp@alien8.de
+Cc: hpa@zytor.com
+Cc: stable@vger.kernel.org
+Link: https://lkml.kernel.org/r/1561524630-3642-1-git-send-email-dianzhangchen0@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/x86/kernel/tls.c | 9 +++++++--
+ 1 file changed, 7 insertions(+), 2 deletions(-)
+
+--- a/arch/x86/kernel/tls.c
++++ b/arch/x86/kernel/tls.c
+@@ -4,6 +4,7 @@
+ #include <linux/user.h>
+ #include <linux/regset.h>
+ #include <linux/syscalls.h>
++#include <linux/nospec.h>
+
+ #include <asm/uaccess.h>
+ #include <asm/desc.h>
+@@ -219,6 +220,7 @@ int do_get_thread_area(struct task_struc
+ struct user_desc __user *u_info)
+ {
+ struct user_desc info;
++ int index;
+
+ if (idx == -1 && get_user(idx, &u_info->entry_number))
+ return -EFAULT;
+@@ -226,8 +228,11 @@ int do_get_thread_area(struct task_struc
+ if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX)
+ return -EINVAL;
+
+- fill_user_desc(&info, idx,
+- &p->thread.tls_array[idx - GDT_ENTRY_TLS_MIN]);
++ index = idx - GDT_ENTRY_TLS_MIN;
++ index = array_index_nospec(index,
++ GDT_ENTRY_TLS_MAX - GDT_ENTRY_TLS_MIN + 1);
++
++ fill_user_desc(&info, idx, &p->thread.tls_array[index]);
+
+ if (copy_to_user(u_info, &info, sizeof(info)))
+ return -EFAULT;