diff options
author | Laura Abbott <labbott@fedoraproject.org> | 2016-05-04 16:34:07 -0700 |
---|---|---|
committer | Laura Abbott <labbott@fedoraproject.org> | 2016-05-04 16:34:07 -0700 |
commit | 3067805602fe55acc47e28708ede310e3a283a04 (patch) | |
tree | aed3f1613ed74a89d428706cd7e9a7c750f9d4c7 | |
parent | f5752fc447d01fc8e9266a5ed9b0b5965be7eae7 (diff) | |
download | kernel-3067805602fe55acc47e28708ede310e3a283a04.tar.gz kernel-3067805602fe55acc47e28708ede310e3a283a04.tar.xz kernel-3067805602fe55acc47e28708ede310e3a283a04.zip |
Linux v4.4.9
-rw-r--r-- | USB-usbip-fix-potential-out-of-bounds-write.patch | 45 | ||||
-rw-r--r-- | ext4-fix-races-between-buffered-IO-and-collapse-inse.patch | 119 | ||||
-rw-r--r-- | ext4-fix-races-between-page-faults-and-hole-punching.patch | 442 | ||||
-rw-r--r-- | ext4-fix-races-of-writeback-with-punch-hole-and-zero.patch | 110 | ||||
-rw-r--r-- | ext4-move-unlocked-dio-protection-from-ext4_alloc_fi.patch | 93 | ||||
-rw-r--r-- | input-gtco-fix-crash-on-detecting-device-without-end.patch | 49 | ||||
-rw-r--r-- | kernel.spec | 20 | ||||
-rw-r--r-- | sources | 2 | ||||
-rw-r--r-- | x86-xen-suppress-hugetlbfs-in-PV-guests.patch | 70 |
9 files changed, 5 insertions, 945 deletions
diff --git a/USB-usbip-fix-potential-out-of-bounds-write.patch b/USB-usbip-fix-potential-out-of-bounds-write.patch deleted file mode 100644 index 3d9f7c294..000000000 --- a/USB-usbip-fix-potential-out-of-bounds-write.patch +++ /dev/null @@ -1,45 +0,0 @@ -From b348d7dddb6c4fbfc810b7a0626e8ec9e29f7cbb Mon Sep 17 00:00:00 2001 -From: Ignat Korchagin <ignat.korchagin@gmail.com> -Date: Thu, 17 Mar 2016 18:00:29 +0000 -Subject: [PATCH] USB: usbip: fix potential out-of-bounds write - -Fix potential out-of-bounds write to urb->transfer_buffer -usbip handles network communication directly in the kernel. When receiving a -packet from its peer, usbip code parses headers according to protocol. As -part of this parsing urb->actual_length is filled. Since the input for -urb->actual_length comes from the network, it should be treated as untrusted. -Any entity controlling the network may put any value in the input and the -preallocated urb->transfer_buffer may not be large enough to hold the data. -Thus, the malicious entity is able to write arbitrary data to kernel memory. - -Signed-off-by: Ignat Korchagin <ignat.korchagin@gmail.com> -Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> ---- - drivers/usb/usbip/usbip_common.c | 11 +++++++++++ - 1 file changed, 11 insertions(+) - -diff --git a/drivers/usb/usbip/usbip_common.c b/drivers/usb/usbip/usbip_common.c -index facaaf003f19..e40da7759a0e 100644 ---- a/drivers/usb/usbip/usbip_common.c -+++ b/drivers/usb/usbip/usbip_common.c -@@ -741,6 +741,17 @@ int usbip_recv_xbuff(struct usbip_device *ud, struct urb *urb) - if (!(size > 0)) - return 0; - -+ if (size > urb->transfer_buffer_length) { -+ /* should not happen, probably malicious packet */ -+ if (ud->side == USBIP_STUB) { -+ usbip_event_add(ud, SDEV_EVENT_ERROR_TCP); -+ return 0; -+ } else { -+ usbip_event_add(ud, VDEV_EVENT_ERROR_TCP); -+ return -EPIPE; -+ } -+ } -+ - ret = usbip_recv(ud->tcp_socket, urb->transfer_buffer, size); - if (ret != size) { - dev_err(&urb->dev->dev, "recv xbuf, %d\n", ret); --- -2.5.5 - diff --git a/ext4-fix-races-between-buffered-IO-and-collapse-inse.patch b/ext4-fix-races-between-buffered-IO-and-collapse-inse.patch deleted file mode 100644 index 0c89ea77a..000000000 --- a/ext4-fix-races-between-buffered-IO-and-collapse-inse.patch +++ /dev/null @@ -1,119 +0,0 @@ -From 32ebffd3bbb4162da5ff88f9a35dd32d0a28ea70 Mon Sep 17 00:00:00 2001 -From: Jan Kara <jack@suse.com> -Date: Mon, 7 Dec 2015 14:31:11 -0500 -Subject: [PATCH 3/4] ext4: fix races between buffered IO and collapse / insert - range - -Current code implementing FALLOC_FL_COLLAPSE_RANGE and -FALLOC_FL_INSERT_RANGE is prone to races with buffered writes and page -faults. If buffered write or write via mmap manages to squeeze between -filemap_write_and_wait_range() and truncate_pagecache() in the fallocate -implementations, the written data is simply discarded by -truncate_pagecache() although it should have been shifted. - -Fix the problem by moving filemap_write_and_wait_range() call inside -i_mutex and i_mmap_sem. That way we are protected against races with -both buffered writes and page faults. - -Signed-off-by: Jan Kara <jack@suse.com> -Signed-off-by: Theodore Ts'o <tytso@mit.edu> ---- - fs/ext4/extents.c | 59 +++++++++++++++++++++++++++++-------------------------- - 1 file changed, 31 insertions(+), 28 deletions(-) - -diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c -index 65b5ada2833f..4b105c96df08 100644 ---- a/fs/ext4/extents.c -+++ b/fs/ext4/extents.c -@@ -5487,21 +5487,7 @@ int ext4_collapse_range(struct inode *inode, loff_t offset, loff_t len) - return ret; - } - -- /* -- * Need to round down offset to be aligned with page size boundary -- * for page size > block size. -- */ -- ioffset = round_down(offset, PAGE_SIZE); -- -- /* Write out all dirty pages */ -- ret = filemap_write_and_wait_range(inode->i_mapping, ioffset, -- LLONG_MAX); -- if (ret) -- return ret; -- -- /* Take mutex lock */ - mutex_lock(&inode->i_mutex); -- - /* - * There is no need to overlap collapse range with EOF, in which case - * it is effectively a truncate operation -@@ -5526,6 +5512,27 @@ int ext4_collapse_range(struct inode *inode, loff_t offset, loff_t len) - * page cache. - */ - down_write(&EXT4_I(inode)->i_mmap_sem); -+ /* -+ * Need to round down offset to be aligned with page size boundary -+ * for page size > block size. -+ */ -+ ioffset = round_down(offset, PAGE_SIZE); -+ /* -+ * Write tail of the last page before removed range since it will get -+ * removed from the page cache below. -+ */ -+ ret = filemap_write_and_wait_range(inode->i_mapping, ioffset, offset); -+ if (ret) -+ goto out_mmap; -+ /* -+ * Write data that will be shifted to preserve them when discarding -+ * page cache below. We are also protected from pages becoming dirty -+ * by i_mmap_sem. -+ */ -+ ret = filemap_write_and_wait_range(inode->i_mapping, offset + len, -+ LLONG_MAX); -+ if (ret) -+ goto out_mmap; - truncate_pagecache(inode, ioffset); - - credits = ext4_writepage_trans_blocks(inode); -@@ -5626,21 +5633,7 @@ int ext4_insert_range(struct inode *inode, loff_t offset, loff_t len) - return ret; - } - -- /* -- * Need to round down to align start offset to page size boundary -- * for page size > block size. -- */ -- ioffset = round_down(offset, PAGE_SIZE); -- -- /* Write out all dirty pages */ -- ret = filemap_write_and_wait_range(inode->i_mapping, ioffset, -- LLONG_MAX); -- if (ret) -- return ret; -- -- /* Take mutex lock */ - mutex_lock(&inode->i_mutex); -- - /* Currently just for extent based files */ - if (!ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)) { - ret = -EOPNOTSUPP; -@@ -5668,6 +5661,16 @@ int ext4_insert_range(struct inode *inode, loff_t offset, loff_t len) - * page cache. - */ - down_write(&EXT4_I(inode)->i_mmap_sem); -+ /* -+ * Need to round down to align start offset to page size boundary -+ * for page size > block size. -+ */ -+ ioffset = round_down(offset, PAGE_SIZE); -+ /* Write out all dirty pages */ -+ ret = filemap_write_and_wait_range(inode->i_mapping, ioffset, -+ LLONG_MAX); -+ if (ret) -+ goto out_mmap; - truncate_pagecache(inode, ioffset); - - credits = ext4_writepage_trans_blocks(inode); --- -2.5.5 - diff --git a/ext4-fix-races-between-page-faults-and-hole-punching.patch b/ext4-fix-races-between-page-faults-and-hole-punching.patch deleted file mode 100644 index 9034b958c..000000000 --- a/ext4-fix-races-between-page-faults-and-hole-punching.patch +++ /dev/null @@ -1,442 +0,0 @@ -From ea3d7209ca01da209cda6f0dea8be9cc4b7a933b Mon Sep 17 00:00:00 2001 -From: Jan Kara <jack@suse.com> -Date: Mon, 7 Dec 2015 14:28:03 -0500 -Subject: [PATCH 1/4] ext4: fix races between page faults and hole punching - -Currently, page faults and hole punching are completely unsynchronized. -This can result in page fault faulting in a page into a range that we -are punching after truncate_pagecache_range() has been called and thus -we can end up with a page mapped to disk blocks that will be shortly -freed. Filesystem corruption will shortly follow. Note that the same -race is avoided for truncate by checking page fault offset against -i_size but there isn't similar mechanism available for punching holes. - -Fix the problem by creating new rw semaphore i_mmap_sem in inode and -grab it for writing over truncate, hole punching, and other functions -removing blocks from extent tree and for read over page faults. We -cannot easily use i_data_sem for this since that ranks below transaction -start and we need something ranking above it so that it can be held over -the whole truncate / hole punching operation. Also remove various -workarounds we had in the code to reduce race window when page fault -could have created pages with stale mapping information. - -Signed-off-by: Jan Kara <jack@suse.com> -Signed-off-by: Theodore Ts'o <tytso@mit.edu> ---- - fs/ext4/ext4.h | 10 +++++++++ - fs/ext4/extents.c | 54 ++++++++++++++++++++++++-------------------- - fs/ext4/file.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++-------- - fs/ext4/inode.c | 36 +++++++++++++++++++++-------- - fs/ext4/super.c | 1 + - fs/ext4/truncate.h | 2 ++ - 6 files changed, 127 insertions(+), 42 deletions(-) - -diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h -index cc7ca4e87144..348a5ff4a0e2 100644 ---- a/fs/ext4/ext4.h -+++ b/fs/ext4/ext4.h -@@ -910,6 +910,15 @@ struct ext4_inode_info { - * by other means, so we have i_data_sem. - */ - struct rw_semaphore i_data_sem; -+ /* -+ * i_mmap_sem is for serializing page faults with truncate / punch hole -+ * operations. We have to make sure that new page cannot be faulted in -+ * a section of the inode that is being punched. We cannot easily use -+ * i_data_sem for this since we need protection for the whole punch -+ * operation and i_data_sem ranks below transaction start so we have -+ * to occasionally drop it. -+ */ -+ struct rw_semaphore i_mmap_sem; - struct inode vfs_inode; - struct jbd2_inode *jinode; - -@@ -2484,6 +2493,7 @@ extern int ext4_chunk_trans_blocks(struct inode *, int nrblocks); - extern int ext4_zero_partial_blocks(handle_t *handle, struct inode *inode, - loff_t lstart, loff_t lend); - extern int ext4_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf); -+extern int ext4_filemap_fault(struct vm_area_struct *vma, struct vm_fault *vmf); - extern qsize_t *ext4_get_reserved_space(struct inode *inode); - extern void ext4_da_update_reserve_space(struct inode *inode, - int used, int quota_claim); -diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c -index 551353b1b17a..5be9ca5a8a7a 100644 ---- a/fs/ext4/extents.c -+++ b/fs/ext4/extents.c -@@ -4770,7 +4770,6 @@ static long ext4_zero_range(struct file *file, loff_t offset, - int partial_begin, partial_end; - loff_t start, end; - ext4_lblk_t lblk; -- struct address_space *mapping = inode->i_mapping; - unsigned int blkbits = inode->i_blkbits; - - trace_ext4_zero_range(inode, offset, len, mode); -@@ -4786,17 +4785,6 @@ static long ext4_zero_range(struct file *file, loff_t offset, - } - - /* -- * Write out all dirty pages to avoid race conditions -- * Then release them. -- */ -- if (mapping->nrpages && mapping_tagged(mapping, PAGECACHE_TAG_DIRTY)) { -- ret = filemap_write_and_wait_range(mapping, offset, -- offset + len - 1); -- if (ret) -- return ret; -- } -- -- /* - * Round up offset. This is not fallocate, we neet to zero out - * blocks, so convert interior block aligned part of the range to - * unwritten and possibly manually zero out unaligned parts of the -@@ -4856,16 +4844,22 @@ static long ext4_zero_range(struct file *file, loff_t offset, - flags |= (EXT4_GET_BLOCKS_CONVERT_UNWRITTEN | - EXT4_EX_NOCACHE); - -- /* Now release the pages and zero block aligned part of pages*/ -- truncate_pagecache_range(inode, start, end - 1); -- inode->i_mtime = inode->i_ctime = ext4_current_time(inode); -- - /* Wait all existing dio workers, newcomers will block on i_mutex */ - ext4_inode_block_unlocked_dio(inode); - inode_dio_wait(inode); - -+ /* -+ * Prevent page faults from reinstantiating pages we have -+ * released from page cache. -+ */ -+ down_write(&EXT4_I(inode)->i_mmap_sem); -+ /* Now release the pages and zero block aligned part of pages */ -+ truncate_pagecache_range(inode, start, end - 1); -+ inode->i_mtime = inode->i_ctime = ext4_current_time(inode); -+ - ret = ext4_alloc_file_blocks(file, lblk, max_blocks, new_size, - flags, mode); -+ up_write(&EXT4_I(inode)->i_mmap_sem); - if (ret) - goto out_dio; - } -@@ -5524,17 +5518,22 @@ int ext4_collapse_range(struct inode *inode, loff_t offset, loff_t len) - goto out_mutex; - } - -- truncate_pagecache(inode, ioffset); -- - /* Wait for existing dio to complete */ - ext4_inode_block_unlocked_dio(inode); - inode_dio_wait(inode); - -+ /* -+ * Prevent page faults from reinstantiating pages we have released from -+ * page cache. -+ */ -+ down_write(&EXT4_I(inode)->i_mmap_sem); -+ truncate_pagecache(inode, ioffset); -+ - credits = ext4_writepage_trans_blocks(inode); - handle = ext4_journal_start(inode, EXT4_HT_TRUNCATE, credits); - if (IS_ERR(handle)) { - ret = PTR_ERR(handle); -- goto out_dio; -+ goto out_mmap; - } - - down_write(&EXT4_I(inode)->i_data_sem); -@@ -5573,7 +5572,8 @@ int ext4_collapse_range(struct inode *inode, loff_t offset, loff_t len) - - out_stop: - ext4_journal_stop(handle); --out_dio: -+out_mmap: -+ up_write(&EXT4_I(inode)->i_mmap_sem); - ext4_inode_resume_unlocked_dio(inode); - out_mutex: - mutex_unlock(&inode->i_mutex); -@@ -5660,17 +5660,22 @@ int ext4_insert_range(struct inode *inode, loff_t offset, loff_t len) - goto out_mutex; - } - -- truncate_pagecache(inode, ioffset); -- - /* Wait for existing dio to complete */ - ext4_inode_block_unlocked_dio(inode); - inode_dio_wait(inode); - -+ /* -+ * Prevent page faults from reinstantiating pages we have released from -+ * page cache. -+ */ -+ down_write(&EXT4_I(inode)->i_mmap_sem); -+ truncate_pagecache(inode, ioffset); -+ - credits = ext4_writepage_trans_blocks(inode); - handle = ext4_journal_start(inode, EXT4_HT_TRUNCATE, credits); - if (IS_ERR(handle)) { - ret = PTR_ERR(handle); -- goto out_dio; -+ goto out_mmap; - } - - /* Expand file to avoid data loss if there is error while shifting */ -@@ -5741,7 +5746,8 @@ int ext4_insert_range(struct inode *inode, loff_t offset, loff_t len) - - out_stop: - ext4_journal_stop(handle); --out_dio: -+out_mmap: -+ up_write(&EXT4_I(inode)->i_mmap_sem); - ext4_inode_resume_unlocked_dio(inode); - out_mutex: - mutex_unlock(&inode->i_mutex); -diff --git a/fs/ext4/file.c b/fs/ext4/file.c -index 113837e7ba98..0d24ebcd7c9e 100644 ---- a/fs/ext4/file.c -+++ b/fs/ext4/file.c -@@ -209,15 +209,18 @@ static int ext4_dax_fault(struct vm_area_struct *vma, struct vm_fault *vmf) - { - int result; - handle_t *handle = NULL; -- struct super_block *sb = file_inode(vma->vm_file)->i_sb; -+ struct inode *inode = file_inode(vma->vm_file); -+ struct super_block *sb = inode->i_sb; - bool write = vmf->flags & FAULT_FLAG_WRITE; - - if (write) { - sb_start_pagefault(sb); - file_update_time(vma->vm_file); -+ down_read(&EXT4_I(inode)->i_mmap_sem); - handle = ext4_journal_start_sb(sb, EXT4_HT_WRITE_PAGE, - EXT4_DATA_TRANS_BLOCKS(sb)); -- } -+ } else -+ down_read(&EXT4_I(inode)->i_mmap_sem); - - if (IS_ERR(handle)) - result = VM_FAULT_SIGBUS; -@@ -228,8 +231,10 @@ static int ext4_dax_fault(struct vm_area_struct *vma, struct vm_fault *vmf) - if (write) { - if (!IS_ERR(handle)) - ext4_journal_stop(handle); -+ up_read(&EXT4_I(inode)->i_mmap_sem); - sb_end_pagefault(sb); -- } -+ } else -+ up_read(&EXT4_I(inode)->i_mmap_sem); - - return result; - } -@@ -246,10 +251,12 @@ static int ext4_dax_pmd_fault(struct vm_area_struct *vma, unsigned long addr, - if (write) { - sb_start_pagefault(sb); - file_update_time(vma->vm_file); -+ down_read(&EXT4_I(inode)->i_mmap_sem); - handle = ext4_journal_start_sb(sb, EXT4_HT_WRITE_PAGE, - ext4_chunk_trans_blocks(inode, - PMD_SIZE / PAGE_SIZE)); -- } -+ } else -+ down_read(&EXT4_I(inode)->i_mmap_sem); - - if (IS_ERR(handle)) - result = VM_FAULT_SIGBUS; -@@ -260,30 +267,71 @@ static int ext4_dax_pmd_fault(struct vm_area_struct *vma, unsigned long addr, - if (write) { - if (!IS_ERR(handle)) - ext4_journal_stop(handle); -+ up_read(&EXT4_I(inode)->i_mmap_sem); - sb_end_pagefault(sb); -- } -+ } else -+ up_read(&EXT4_I(inode)->i_mmap_sem); - - return result; - } - - static int ext4_dax_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf) - { -- return dax_mkwrite(vma, vmf, ext4_get_block_dax, -- ext4_end_io_unwritten); -+ int err; -+ struct inode *inode = file_inode(vma->vm_file); -+ -+ sb_start_pagefault(inode->i_sb); -+ file_update_time(vma->vm_file); -+ down_read(&EXT4_I(inode)->i_mmap_sem); -+ err = __dax_mkwrite(vma, vmf, ext4_get_block_dax, -+ ext4_end_io_unwritten); -+ up_read(&EXT4_I(inode)->i_mmap_sem); -+ sb_end_pagefault(inode->i_sb); -+ -+ return err; -+} -+ -+/* -+ * Handle write fault for VM_MIXEDMAP mappings. Similarly to ext4_dax_mkwrite() -+ * handler we check for races agaist truncate. Note that since we cycle through -+ * i_mmap_sem, we are sure that also any hole punching that began before we -+ * were called is finished by now and so if it included part of the file we -+ * are working on, our pte will get unmapped and the check for pte_same() in -+ * wp_pfn_shared() fails. Thus fault gets retried and things work out as -+ * desired. -+ */ -+static int ext4_dax_pfn_mkwrite(struct vm_area_struct *vma, -+ struct vm_fault *vmf) -+{ -+ struct inode *inode = file_inode(vma->vm_file); -+ struct super_block *sb = inode->i_sb; -+ int ret = VM_FAULT_NOPAGE; -+ loff_t size; -+ -+ sb_start_pagefault(sb); -+ file_update_time(vma->vm_file); -+ down_read(&EXT4_I(inode)->i_mmap_sem); -+ size = (i_size_read(inode) + PAGE_SIZE - 1) >> PAGE_SHIFT; -+ if (vmf->pgoff >= size) -+ ret = VM_FAULT_SIGBUS; -+ up_read(&EXT4_I(inode)->i_mmap_sem); -+ sb_end_pagefault(sb); -+ -+ return ret; - } - - static const struct vm_operations_struct ext4_dax_vm_ops = { - .fault = ext4_dax_fault, - .pmd_fault = ext4_dax_pmd_fault, - .page_mkwrite = ext4_dax_mkwrite, -- .pfn_mkwrite = dax_pfn_mkwrite, -+ .pfn_mkwrite = ext4_dax_pfn_mkwrite, - }; - #else - #define ext4_dax_vm_ops ext4_file_vm_ops - #endif - - static const struct vm_operations_struct ext4_file_vm_ops = { -- .fault = filemap_fault, -+ .fault = ext4_filemap_fault, - .map_pages = filemap_map_pages, - .page_mkwrite = ext4_page_mkwrite, - }; -diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c -index ea433a7f4bca..d1207d03c961 100644 ---- a/fs/ext4/inode.c -+++ b/fs/ext4/inode.c -@@ -3623,6 +3623,15 @@ int ext4_punch_hole(struct inode *inode, loff_t offset, loff_t length) - - } - -+ /* Wait all existing dio workers, newcomers will block on i_mutex */ -+ ext4_inode_block_unlocked_dio(inode); -+ inode_dio_wait(inode); -+ -+ /* -+ * Prevent page faults from reinstantiating pages we have released from -+ * page cache. -+ */ -+ down_write(&EXT4_I(inode)->i_mmap_sem); - first_block_offset = round_up(offset, sb->s_blocksize); - last_block_offset = round_down((offset + length), sb->s_blocksize) - 1; - -@@ -3631,10 +3640,6 @@ int ext4_punch_hole(struct inode *inode, loff_t offset, loff_t length) - truncate_pagecache_range(inode, first_block_offset, - last_block_offset); - -- /* Wait all existing dio workers, newcomers will block on i_mutex */ -- ext4_inode_block_unlocked_dio(inode); -- inode_dio_wait(inode); -- - if (ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)) - credits = ext4_writepage_trans_blocks(inode); - else -@@ -3680,16 +3685,12 @@ int ext4_punch_hole(struct inode *inode, loff_t offset, loff_t length) - if (IS_SYNC(inode)) - ext4_handle_sync(handle); - -- /* Now release the pages again to reduce race window */ -- if (last_block_offset > first_block_offset) -- truncate_pagecache_range(inode, first_block_offset, -- last_block_offset); -- - inode->i_mtime = inode->i_ctime = ext4_current_time(inode); - ext4_mark_inode_dirty(handle, inode); - out_stop: - ext4_journal_stop(handle); - out_dio: -+ up_write(&EXT4_I(inode)->i_mmap_sem); - ext4_inode_resume_unlocked_dio(inode); - out_mutex: - mutex_unlock(&inode->i_mutex); -@@ -4823,6 +4824,7 @@ int ext4_setattr(struct dentry *dentry, struct iattr *attr) - } else - ext4_wait_for_tail_page_commit(inode); - } -+ down_write(&EXT4_I(inode)->i_mmap_sem); - /* - * Truncate pagecache after we've waited for commit - * in data=journal mode to make pages freeable. -@@ -4830,6 +4832,7 @@ int ext4_setattr(struct dentry *dentry, struct iattr *attr) - truncate_pagecache(inode, inode->i_size); - if (shrink) - ext4_truncate(inode); -+ up_write(&EXT4_I(inode)->i_mmap_sem); - } - - if (!rc) { -@@ -5278,6 +5281,8 @@ int ext4_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf) - - sb_start_pagefault(inode->i_sb); - file_update_time(vma->vm_file); -+ -+ down_read(&EXT4_I(inode)->i_mmap_sem); - /* Delalloc case is easy... */ - if (test_opt(inode->i_sb, DELALLOC) && - !ext4_should_journal_data(inode) && -@@ -5347,6 +5352,19 @@ retry_alloc: - out_ret: - ret = block_page_mkwrite_return(ret); - out: -+ up_read(&EXT4_I(inode)->i_mmap_sem); - sb_end_pagefault(inode->i_sb); - return ret; - } -+ -+int ext4_filemap_fault(struct vm_area_struct *vma, struct vm_fault *vmf) -+{ -+ struct inode *inode = file_inode(vma->vm_file); -+ int err; -+ -+ down_read(&EXT4_I(inode)->i_mmap_sem); -+ err = filemap_fault(vma, vmf); -+ up_read(&EXT4_I(inode)->i_mmap_sem); -+ -+ return err; -+} -diff --git a/fs/ext4/super.c b/fs/ext4/super.c -index c9ab67da6e5a..493370e6590e 100644 ---- a/fs/ext4/super.c -+++ b/fs/ext4/super.c -@@ -958,6 +958,7 @@ static void init_once(void *foo) - INIT_LIST_HEAD(&ei->i_orphan); - init_rwsem(&ei->xattr_sem); - init_rwsem(&ei->i_data_sem); -+ init_rwsem(&ei->i_mmap_sem); - inode_init_once(&ei->vfs_inode); - } - -diff --git a/fs/ext4/truncate.h b/fs/ext4/truncate.h -index 011ba6670d99..c70d06a383e2 100644 ---- a/fs/ext4/truncate.h -+++ b/fs/ext4/truncate.h -@@ -10,8 +10,10 @@ - */ - static inline void ext4_truncate_failed_write(struct inode *inode) - { -+ down_write(&EXT4_I(inode)->i_mmap_sem); - truncate_inode_pages(inode->i_mapping, inode->i_size); - ext4_truncate(inode); -+ up_write(&EXT4_I(inode)->i_mmap_sem); - } - - /* --- -2.5.5 - diff --git a/ext4-fix-races-of-writeback-with-punch-hole-and-zero.patch b/ext4-fix-races-of-writeback-with-punch-hole-and-zero.patch deleted file mode 100644 index 9ff9e2761..000000000 --- a/ext4-fix-races-of-writeback-with-punch-hole-and-zero.patch +++ /dev/null @@ -1,110 +0,0 @@ -From 011278485ecc3cd2a3954b5d4c73101d919bf1fa Mon Sep 17 00:00:00 2001 -From: Jan Kara <jack@suse.com> -Date: Mon, 7 Dec 2015 14:34:49 -0500 -Subject: [PATCH 4/4] ext4: fix races of writeback with punch hole and zero - range - -When doing delayed allocation, update of on-disk inode size is postponed -until IO submission time. However hole punch or zero range fallocate -calls can end up discarding the tail page cache page and thus on-disk -inode size would never be properly updated. - -Make sure the on-disk inode size is updated before truncating page -cache. - -Signed-off-by: Jan Kara <jack@suse.com> -Signed-off-by: Theodore Ts'o <tytso@mit.edu> ---- - fs/ext4/ext4.h | 3 +++ - fs/ext4/extents.c | 5 +++++ - fs/ext4/inode.c | 35 ++++++++++++++++++++++++++++++++++- - 3 files changed, 42 insertions(+), 1 deletion(-) - -diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h -index 348a5ff4a0e2..80f76f092079 100644 ---- a/fs/ext4/ext4.h -+++ b/fs/ext4/ext4.h -@@ -2858,6 +2858,9 @@ static inline int ext4_update_inode_size(struct inode *inode, loff_t newsize) - return changed; - } - -+int ext4_update_disksize_before_punch(struct inode *inode, loff_t offset, -+ loff_t len); -+ - struct ext4_group_info { - unsigned long bb_state; - struct rb_root bb_free_root; -diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c -index 4b105c96df08..3578b25fccfd 100644 ---- a/fs/ext4/extents.c -+++ b/fs/ext4/extents.c -@@ -4847,6 +4847,11 @@ static long ext4_zero_range(struct file *file, loff_t offset, - * released from page cache. - */ - down_write(&EXT4_I(inode)->i_mmap_sem); -+ ret = ext4_update_disksize_before_punch(inode, offset, len); -+ if (ret) { -+ up_write(&EXT4_I(inode)->i_mmap_sem); -+ goto out_dio; -+ } - /* Now release the pages and zero block aligned part of pages */ - truncate_pagecache_range(inode, start, end - 1); - inode->i_mtime = inode->i_ctime = ext4_current_time(inode); -diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c -index d1207d03c961..472e608da13d 100644 ---- a/fs/ext4/inode.c -+++ b/fs/ext4/inode.c -@@ -3559,6 +3559,35 @@ int ext4_can_truncate(struct inode *inode) - } - - /* -+ * We have to make sure i_disksize gets properly updated before we truncate -+ * page cache due to hole punching or zero range. Otherwise i_disksize update -+ * can get lost as it may have been postponed to submission of writeback but -+ * that will never happen after we truncate page cache. -+ */ -+int ext4_update_disksize_before_punch(struct inode *inode, loff_t offset, -+ loff_t len) -+{ -+ handle_t *handle; -+ loff_t size = i_size_read(inode); -+ -+ WARN_ON(!mutex_is_locked(&inode->i_mutex)); -+ if (offset > size || offset + len < size) -+ return 0; -+ -+ if (EXT4_I(inode)->i_disksize >= size) -+ return 0; -+ -+ handle = ext4_journal_start(inode, EXT4_HT_MISC, 1); -+ if (IS_ERR(handle)) -+ return PTR_ERR(handle); -+ ext4_update_i_disksize(inode, size); -+ ext4_mark_inode_dirty(handle, inode); -+ ext4_journal_stop(handle); -+ -+ return 0; -+} -+ -+/* - * ext4_punch_hole: punches a hole in a file by releaseing the blocks - * associated with the given offset and length - * -@@ -3636,9 +3665,13 @@ int ext4_punch_hole(struct inode *inode, loff_t offset, loff_t length) - last_block_offset = round_down((offset + length), sb->s_blocksize) - 1; - - /* Now release the pages and zero block aligned part of pages*/ -- if (last_block_offset > first_block_offset) -+ if (last_block_offset > first_block_offset) { -+ ret = ext4_update_disksize_before_punch(inode, offset, length); -+ if (ret) -+ goto out_dio; - truncate_pagecache_range(inode, first_block_offset, - last_block_offset); -+ } - - if (ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)) - credits = ext4_writepage_trans_blocks(inode); --- -2.5.5 - diff --git a/ext4-move-unlocked-dio-protection-from-ext4_alloc_fi.patch b/ext4-move-unlocked-dio-protection-from-ext4_alloc_fi.patch deleted file mode 100644 index 3bf6765fa..000000000 --- a/ext4-move-unlocked-dio-protection-from-ext4_alloc_fi.patch +++ /dev/null @@ -1,93 +0,0 @@ -From 17048e8a083fec7ad841d88ef0812707fbc7e39f Mon Sep 17 00:00:00 2001 -From: Jan Kara <jack@suse.com> -Date: Mon, 7 Dec 2015 14:29:17 -0500 -Subject: [PATCH 2/4] ext4: move unlocked dio protection from - ext4_alloc_file_blocks() - -Currently ext4_alloc_file_blocks() was handling protection against -unlocked DIO. However we now need to sometimes call it under i_mmap_sem -and sometimes not and DIO protection ranks above it (although strictly -speaking this cannot currently create any deadlocks). Also -ext4_zero_range() was actually getting & releasing unlocked DIO -protection twice in some cases. Luckily it didn't introduce any real bug -but it was a land mine waiting to be stepped on. So move DIO protection -out from ext4_alloc_file_blocks() into the two callsites. - -Signed-off-by: Jan Kara <jack@suse.com> -Signed-off-by: Theodore Ts'o <tytso@mit.edu> ---- - fs/ext4/extents.c | 21 ++++++++++----------- - 1 file changed, 10 insertions(+), 11 deletions(-) - -diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c -index 5be9ca5a8a7a..65b5ada2833f 100644 ---- a/fs/ext4/extents.c -+++ b/fs/ext4/extents.c -@@ -4685,10 +4685,6 @@ static int ext4_alloc_file_blocks(struct file *file, ext4_lblk_t offset, - if (len <= EXT_UNWRITTEN_MAX_LEN) - flags |= EXT4_GET_BLOCKS_NO_NORMALIZE; - -- /* Wait all existing dio workers, newcomers will block on i_mutex */ -- ext4_inode_block_unlocked_dio(inode); -- inode_dio_wait(inode); -- - /* - * credits to insert 1 extent into extent tree - */ -@@ -4752,8 +4748,6 @@ retry: - goto retry; - } - -- ext4_inode_resume_unlocked_dio(inode); -- - return ret > 0 ? ret2 : ret; - } - -@@ -4827,6 +4821,10 @@ static long ext4_zero_range(struct file *file, loff_t offset, - if (mode & FALLOC_FL_KEEP_SIZE) - flags |= EXT4_GET_BLOCKS_KEEP_SIZE; - -+ /* Wait all existing dio workers, newcomers will block on i_mutex */ -+ ext4_inode_block_unlocked_dio(inode); -+ inode_dio_wait(inode); -+ - /* Preallocate the range including the unaligned edges */ - if (partial_begin || partial_end) { - ret = ext4_alloc_file_blocks(file, -@@ -4835,7 +4833,7 @@ static long ext4_zero_range(struct file *file, loff_t offset, - round_down(offset, 1 << blkbits)) >> blkbits, - new_size, flags, mode); - if (ret) -- goto out_mutex; -+ goto out_dio; - - } - -@@ -4844,10 +4842,6 @@ static long ext4_zero_range(struct file *file, loff_t offset, - flags |= (EXT4_GET_BLOCKS_CONVERT_UNWRITTEN | - EXT4_EX_NOCACHE); - -- /* Wait all existing dio workers, newcomers will block on i_mutex */ -- ext4_inode_block_unlocked_dio(inode); -- inode_dio_wait(inode); -- - /* - * Prevent page faults from reinstantiating pages we have - * released from page cache. -@@ -4992,8 +4986,13 @@ long ext4_fallocate(struct file *file, int mode, loff_t offset, loff_t len) - goto out; - } - -+ /* Wait all existing dio workers, newcomers will block on i_mutex */ -+ ext4_inode_block_unlocked_dio(inode); -+ inode_dio_wait(inode); -+ - ret = ext4_alloc_file_blocks(file, lblk, max_blocks, new_size, - flags, mode); -+ ext4_inode_resume_unlocked_dio(inode); - if (ret) - goto out; - --- -2.5.5 - diff --git a/input-gtco-fix-crash-on-detecting-device-without-end.patch b/input-gtco-fix-crash-on-detecting-device-without-end.patch deleted file mode 100644 index 849f607a5..000000000 --- a/input-gtco-fix-crash-on-detecting-device-without-end.patch +++ /dev/null @@ -1,49 +0,0 @@ -Subject: [PATCH] Input: gtco: fix crash on detecting device without endpoints -From: Vladis Dronov <vdronov@redhat.com> -Date: 2016-03-18 18:35:00 - -The gtco driver expects at least one valid endpoint. If given -malicious descriptors that specify 0 for the number of endpoints, -it will crash in the probe function. Ensure there is at least -one endpoint on the interface before using it. Fix minor coding -style issue. - -The full report of this issue can be found here: -http://seclists.org/bugtraq/2016/Mar/86 - -Reported-by: Ralf Spenneberg <ralf@spenneberg.net> -Signed-off-by: Vladis Dronov <vdronov@redhat.com> ---- - drivers/input/tablet/gtco.c | 10 +++++++++- - 1 file changed, 9 insertions(+), 1 deletion(-) - -diff --git a/drivers/input/tablet/gtco.c b/drivers/input/tablet/gtco.c -index 3a7f3a4..7c18249 100644 ---- a/drivers/input/tablet/gtco.c -+++ b/drivers/input/tablet/gtco.c -@@ -858,6 +858,14 @@ static int gtco_probe(struct usb_interface *usbinterface, - goto err_free_buf; - } - -+ /* Sanity check that a device has an endpoint */ -+ if (usbinterface->altsetting[0].desc.bNumEndpoints < 1) { -+ dev_err(&usbinterface->dev, -+ "Invalid number of endpoints\n"); -+ error = -EINVAL; -+ goto err_free_urb; -+ } -+ - /* - * The endpoint is always altsetting 0, we know this since we know - * this device only has one interrupt endpoint -@@ -879,7 +887,7 @@ static int gtco_probe(struct usb_interface *usbinterface, - * HID report descriptor - */ - if (usb_get_extra_descriptor(usbinterface->cur_altsetting, -- HID_DEVICE_TYPE, &hid_desc) != 0){ -+ HID_DEVICE_TYPE, &hid_desc) != 0) { - dev_err(&usbinterface->dev, - "Can't retrieve exta USB descriptor to get hid report descriptor length\n"); - error = -EIO; --- -2.5.0 diff --git a/kernel.spec b/kernel.spec index 11f9a9940..4271c3150 100644 --- a/kernel.spec +++ b/kernel.spec @@ -52,7 +52,7 @@ Summary: The Linux kernel %if 0%{?released_kernel} # Do we have a -stable update to apply? -%define stable_update 8 +%define stable_update 9 # Set rpm version accordingly %if 0%{?stable_update} %define stablerev %{stable_update} @@ -620,30 +620,15 @@ Patch664: netfilter-x_tables-check-for-size-overflow.patch #CVE-2016-3134 rhbz 1317383 1317384 Patch665: netfilter-x_tables-deal-with-bogus-nextoffset-values.patch -#CVE-2016-2187 rhbz 1317017 1317010 -Patch686: input-gtco-fix-crash-on-detecting-device-without-end.patch - # CVE-2016-3672 rhbz 1324749 1324750 Patch690: x86-mm-32-Enable-full-randomization-on-i386-and-X86_.patch -#CVE-2015-8839 rhbz 1323577 1323579 -Patch691: ext4-fix-races-between-page-faults-and-hole-punching.patch -Patch692: ext4-move-unlocked-dio-protection-from-ext4_alloc_fi.patch -Patch693: ext4-fix-races-between-buffered-IO-and-collapse-inse.patch -Patch694: ext4-fix-races-of-writeback-with-punch-hole-and-zero.patch - #CVE-2016-3951 rhbz 1324782 1324815 Patch695: cdc_ncm-do-not-call-usbnet_link_change-from-cdc_ncm_.patch #rhbz 1309980 Patch698: 0001-ACPI-processor-Request-native-thermal-interrupt-hand.patch -# CVE-2016-3961 rhbz 1327219 1323956 -Patch699: x86-xen-suppress-hugetlbfs-in-PV-guests.patch - -# CVE-2016-3955 rhbz 1328478 1328479 -Patch700: USB-usbip-fix-potential-out-of-bounds-write.patch - #rhbz 1309487 Patch701: antenna_select.patch @@ -2099,6 +2084,9 @@ fi # # %changelog +* Wed May 04 2016 Laura Abbott <labbott@fedoraproject.org> - 4.4.9-300 +- Linux v4.4.9 + * Wed May 04 2016 Josh Boyer <jwboyer@fedoraproject.org> - Enable NFC_NXP_NCI options (rhbz 1290556) - CVE-2016-4482 info leak in devio.c (rhbz 1332931 1332932) @@ -1,3 +1,3 @@ 9a78fa2eb6c68ca5a40ed5af08142599 linux-4.4.tar.xz dcbc8fe378a676d5d0dd208cf524e144 perf-man-4.4.tar.gz -c1d8f46e5b2ee7c925fc38f20a3726d3 patch-4.4.8.xz +b0c445b438e7563f2e33dba9edc926eb patch-4.4.9.xz diff --git a/x86-xen-suppress-hugetlbfs-in-PV-guests.patch b/x86-xen-suppress-hugetlbfs-in-PV-guests.patch deleted file mode 100644 index 1b7c8f24a..000000000 --- a/x86-xen-suppress-hugetlbfs-in-PV-guests.patch +++ /dev/null @@ -1,70 +0,0 @@ -From 72c339e0c6d9969e664c2cf63e162753d7d859ae Mon Sep 17 00:00:00 2001 -From: Jan Beulich <jbeulich@suse.com> -Date: Thu, 14 Apr 2016 13:03:47 +0000 -Subject: [PATCH] x86/xen: suppress hugetlbfs in PV guests - -Huge pages are not normally available to PV guests. Not suppressing -hugetlbfs use results in an endless loop of page faults when user mode -code tries to access a hugetlbfs mapped area (since the hypervisor -denies such PTEs to be created, but error indications can't be -propagated out of xen_set_pte_at(), just like for various of its -siblings), and - once killed in an oops like this: - -kernel BUG at .../fs/hugetlbfs/inode.c:428! -invalid opcode: 0000 [#1] SMP -Modules linked in: ... -Supported: Yes -CPU: 2 PID: 6088 Comm: hugetlbfs Tainted: G W 4.4.0-2016-01-20-pv #2 -Hardware name: ... -task: ffff8808059205c0 ti: ffff880803c84000 task.ti: ffff880803c84000 -RIP: e030:[<ffffffff811c333b>] [<ffffffff811c333b>] remove_inode_hugepages+0x25b/0x320 -RSP: e02b:ffff880803c879a8 EFLAGS: 00010202 -RAX: 000000000077a4db RBX: ffffea001acff000 RCX: 0000000078417d38 -RDX: 0000000000000000 RSI: 000000007e154fa7 RDI: ffff880805d70960 -RBP: 0000000000000960 R08: 0000000000000000 R09: 0000000000000000 -R10: 0000000000000000 R11: 0000000000000001 R12: 0000000000000000 -R13: ffff880807486018 R14: 0000000000000000 R15: ffff880803c87af0 -FS: 00007f85fa8b8700(0000) GS:ffff88080b640000(0000) knlGS:0000000000000000 -CS: e033 DS: 0000 ES: 0000 CR0: 000000008005003b -CR2: 00007f85fa000000 CR3: 0000000001a0a000 CR4: 0000000000040660 -Stack: - ffff880000000fb0 ffff880803c87a18 ffff880803c87ae8 ffff8808059205c0 - ffff880803c87af0 ffff880803c87ae8 ffff880807486018 0000000000000000 - ffffffff81bf6e60 ffff880807486168 000003ffffffffff 0000000003c87758 -Call Trace: - [<ffffffff811c3415>] hugetlbfs_evict_inode+0x15/0x40 - [<ffffffff81167b3d>] evict+0xbd/0x1b0 - [<ffffffff8116514a>] __dentry_kill+0x19a/0x1f0 - [<ffffffff81165b0e>] dput+0x1fe/0x220 - [<ffffffff81150535>] __fput+0x155/0x200 - [<ffffffff81079fc0>] task_work_run+0x60/0xa0 - [<ffffffff81063510>] do_exit+0x160/0x400 - [<ffffffff810637eb>] do_group_exit+0x3b/0xa0 - [<ffffffff8106e8bd>] get_signal+0x1ed/0x470 - [<ffffffff8100f854>] do_signal+0x14/0x110 - [<ffffffff810030e9>] prepare_exit_to_usermode+0xe9/0xf0 - [<ffffffff814178a5>] retint_user+0x8/0x13 - -This is XSA-174. - -Signed-off-by: Jan Beulich <jbeulich@suse.com> -Cc: stable@vger.kernel.org ---- - arch/x86/include/asm/hugetlb.h | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/arch/x86/include/asm/hugetlb.h b/arch/x86/include/asm/hugetlb.h -index f8a29d2c97b0..e6a8613fbfb0 100644 ---- a/arch/x86/include/asm/hugetlb.h -+++ b/arch/x86/include/asm/hugetlb.h -@@ -4,6 +4,7 @@ - #include <asm/page.h> - #include <asm-generic/hugetlb.h> - -+#define hugepages_supported() cpu_has_pse - - static inline int is_hugepage_only_range(struct mm_struct *mm, - unsigned long addr, --- -2.5.5 - |