3.18.115-stable review
Subsystems (2)
Greg Kroah-Hartman
maintainercover 3.18.115-stable review
This is the start of the stable review cycle for the 3.18.115 release. There are 23 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Thu Jul 12 18:22:59 UTC 2018. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
https://www.kernel.org/pub/linux/kernel/v3.x/stable-review/patch-3.18.115-rc1.gz
or in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-3.18.y
and the diffstat can be found below.
thanks,
greg k-h
-------------
Pseudo-Shortlog of commits:
Greg Kroah-Hartman <[email protected]>
Linux 3.18.115-rc1
Jann Horn <[email protected]>
netfilter: nf_log: don't hold nf_log_mutex during user access
Tokunori Ikegami <[email protected]>
mtd: cfi_cmdset_0002: Change erase functions to check chip good only
Tokunori Ikegami <[email protected]>
mtd: cfi_cmdset_0002: Change erase functions to retry for error
Tokunori Ikegami <[email protected]>
mtd: cfi_cmdset_0002: Change definition naming to retry write operation
Martin Kaiser <[email protected]>
mtd: rawnand: mxc: set spare area size register explicitly
Mikulas Patocka <[email protected]>
dm bufio: drop the lock when doing GFP_NOIO allocation
Douglas Anderson <[email protected]>
dm bufio: avoid sleeping while holding the dm_bufio lock
Brad Love <[email protected]>
media: cx25840: Use subdev host data for PLL override
Daniel Rosenberg <[email protected]>
HID: debug: check length before copy_to_user()
Jason Andryuk <[email protected]>
HID: i2c-hid: Fix "incomplete report" noise
Theodore Ts'o <[email protected]>
ext4: add more mount time checks of the superblock
Theodore Ts'o <[email protected]>
ext4: clear i_data in ext4_inode_info when removing inline data
Theodore Ts'o <[email protected]>
ext4: make sure bitmaps and the inode table don't overlap with bg descriptors
Paulo Alcantara <[email protected]>
cifs: Fix infinite loop when using hard mount option
Jann Horn <[email protected]>
scsi: sg: mitigate read/write abuse
Finn Thain <[email protected]>
net/sonic: Use dma_mapping_error()
Josh Hill <[email protected]>
net: qmi_wwan: Add Netgear Aircard 779S
Ivan Bornyakov <[email protected]>
atm: zatm: fix memcmp casting
Paolo Abeni <[email protected]>
netfilter: ebtables: handle string from userspace with care
Richard Weinberger <[email protected]>
ubi: fastmap: Correctly handle interrupted erasures in EBA
Dave Hansen <[email protected]>
x86/boot: Fix early command-line parsing when matching at end
Laura Abbott <[email protected]>
staging: android: ion: Return an ERR_PTR in ion_map_kernel
Tetsuo Handa <[email protected]>
n_tty: Fix stall at n_tty_receive_char_special().
-------------
Diffstat:
Makefile | 4 +- arch/x86/lib/cmdline.c | 34 ++++++++---- drivers/atm/zatm.c | 4 +- drivers/hid/hid-debug.c | 8 ++- drivers/hid/i2c-hid/i2c-hid.c | 2 +- drivers/md/dm-bufio.c | 15 +++++- drivers/media/i2c/cx25840/cx25840-core.c | 28 +++++++--- drivers/mtd/chips/cfi_cmdset_0002.c | 30 +++++++---- drivers/mtd/nand/mxc_nand.c | 5 +- drivers/mtd/ubi/eba.c | 92 +++++++++++++++++++++++++++++++- drivers/net/ethernet/natsemi/sonic.c | 2 +- drivers/net/usb/qmi_wwan.c | 1 + drivers/scsi/sg.c | 42 ++++++++++++++- drivers/staging/android/ion/ion_heap.c | 2 +- drivers/tty/n_tty.c | 13 +++-- fs/cifs/cifssmb.c | 10 +++- fs/cifs/smb2pdu.c | 18 ++++--- fs/ext4/inline.c | 1 + fs/ext4/super.c | 62 +++++++++++++++++---- net/bridge/netfilter/ebtables.c | 3 +- net/netfilter/nf_log.c | 9 ++-- 21 files changed, 318 insertions(+), 67 deletions(-)
Greg Kroah-Hartman
maintainerPATCH 1/23 n_tty: Fix stall at n_tty_receive_char_special().
3.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tetsuo Handa <[email protected]>
commit 3d63b7e4ae0dc5e02d28ddd2fa1f945defc68d81 upstream.
syzbot is reporting stalls at n_tty_receive_char_special() [1]. This is because comparison is not working as expected since ldata->read_head can change at any moment. Mitigate this by explicitly masking with buffer size when checking condition for "while" loops.
[1] https://syzkaller.appspot.com/bug?id=3d7481a346958d9469bebbeb0537d5f056bdd6e8
--- drivers/tty/n_tty.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-)
drivers/tty/n_tty.c +8 -5
@@ -127,6 +127,8 @@ struct n_tty_data {struct mutex output_lock; }; +#define MASK (x) ((x) & (N_TTY_BUF_SIZE - 1)) +static inline size_t read_cnt (struct n_tty_data *ldata) {return ldata->read_head - ldata->read_tail;
@@ -1032,14 +1034,15 @@ static void eraser(unsigned char c, stru } seen_alnums =0 ; -while (ldata->read_head != ldata->canon_head) { +while (MASK (ldata->read_head) !=MASK (ldata->canon_head)) { head = ldata->read_head;/* erase a single possibly multibyte character */ do { head--; c =read_buf (ldata, head); - }while (is_continuation (c, tty) && head != ldata->canon_head); + }while (is_continuation (c, tty) && +MASK (head) !=MASK (ldata->canon_head));/* do not partially erase */ if (is_continuation (c, tty))
@@ -1081,7 +1084,7 @@ static void eraser(unsigned char c, stru* This info is used to go back the correct * number of columns. */ -while (tail != ldata->canon_head) { +while (MASK (tail) !=MASK (ldata->canon_head)) { tail--; c =read_buf (ldata, tail);if (c =='\t' ) {
@@ -1341,7 +1344,7 @@ n_tty_receive_char_special(struct tty_stfinish_erasing (ldata);echo_char (c, tty);echo_char_raw ('\n' , ldata); -while (tail != ldata->read_head) { +while (MASK (tail) !=MASK (ldata->read_head)) {echo_char (read_buf (ldata, tail), tty); tail++; }
@@ -2505,7 +2508,7 @@ static unsigned long inq_canon(struct n_ tail = ldata->read_tail; nr = head - tail;/* Skip EOF-chars.. */ -while (head != tail) { +while (MASK (head) !=MASK (tail)) {if (test_bit (tail & (N_TTY_BUF_SIZE -1 ), ldata->read_flags) &&read_buf (ldata, tail) == __DISABLED_CHAR) nr--;
Greg Kroah-Hartman
maintainerPATCH 2/23 staging: android: ion: Return an ERR_PTR in ion_map_kernel
In reply to Greg Kroah-Hartman3.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Laura Abbott <[email protected]>
commit 0a2bc00341dcfcc793c0dbf4f8d43adf60458b05 upstream.
The expected return value from ion_map_kernel is an ERR_PTR. The error path for a vmalloc failure currently just returns NULL, triggering a warning in ion_buffer_kmap_get. Encode the vmalloc failure as an ERR_PTR.
--- drivers/staging/android/ion/ion_heap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/staging/android/ion/ion_heap.c +1 -1
@@ -38,7 +38,7 @@ void *ion_heap_map_kernel(struct ion_heastruct page **tmp = pages;if (!pages) -return NULL ; +return ERR_PTR (-ENOMEM );if (buffer->flags &ION_FLAG_CACHED ) pgprot =PAGE_KERNEL ;
Greg Kroah-Hartman
maintainerPATCH 3/23 x86/boot: Fix early command-line parsing when matching at end
In reply to Greg Kroah-Hartman3.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dave Hansen <[email protected]>
commit 02afeaae9843733a39cd9b11053748b2d1dc5ae7 upstream.
The x86 early command line parsing in cmdline_find_option_bool() is buggy. If it matches a specified 'option' all the way to the end of the command-line, it will consider it a match.
For instance,
cmdline = "foo"; cmdline_find_option_bool(cmdline, "fool");
will return 1. This is particularly annoying since we have actual FPU options like "noxsave" and "noxsaves" So, command-line "foo bar noxsave" will match *BOTH* a "noxsave" and "noxsaves". (This turns out not to be an actual problem because "noxsave" implies "noxsaves", but it's still confusing.)
To fix this, we simplify the code and stop tracking 'len'. 'len' was trying to indicate either the NULL terminator *OR* the end of a non-NULL-terminated command line at 'COMMAND_LINE_SIZE'. But, each of the three states is *already* checking 'cmdline' for a NULL terminator.
We _only_ need to check if we have overrun 'COMMAND_LINE_SIZE', and that we can do without keeping 'len' around.
Also add some commends to clarify what is going on.
--- arch/x86/lib/cmdline.c | 34 ++++++++++++++++++++++++---------- 1 file changed, 24 insertions(+), 10 deletions(-)
arch/x86/lib/cmdline.c +24 -10
@@ -21,12 +21,14 @@ static inline int myisspace(u8 c)* @option: option string to look for * * Returns the position of that @option (starts counting with 1) -* or 0 on not found. +* or 0 on not found. @option will only be found if it is found +* as an entire word in @cmdline. For instance, if @option="car" +* then a cmdline which contains "cart" will not match. */ int cmdline_find_option_bool (const char *cmdline,const char *option) {char c; -int len, pos =0 , wstart =0 ; +int pos =0 , wstart =0 ;const char *opptr =NULL ;enum { st_wordstart =0 ,/* Start of word/after whitespace */
@@ -37,11 +39,14 @@ int cmdline_find_option_bool(const charif (!cmdline)return -1 ;/* No command line */ - len =min_t (int,strlen (cmdline),COMMAND_LINE_SIZE ); -if (!len) +if (!strlen (cmdline))return 0 ; -while (len--) { +/* +* This 'pos' check ensures we do not overrun +* a non-NULL-terminated 'cmdline' +*/ +while (pos <COMMAND_LINE_SIZE ) { c = *(char *)cmdline++; pos++;
@@ -58,17 +63,26 @@ int cmdline_find_option_bool(const char/* fall through */ case st_wordcmp: -if (!*opptr) +if (!*opptr) { +/* +* We matched all the way to the end of the +* option we were looking for. If the +* command-line has a space _or_ ends, then +* we matched! +*/ if (!c ||myisspace (c))return wstart;else state = st_wordskip; -else if (!c) + }else if (!c) { +/* +* Hit the NULL terminator on the end of +* cmdline. +*/ return 0 ; -else if (c != *opptr++) + }else if (c != *opptr++) { state = st_wordskip; -else if (!len)/* last word and is matching */ -return wstart; + }break ;case st_wordskip:
Greg Kroah-Hartman
maintainerPATCH 4/23 ubi: fastmap: Correctly handle interrupted erasures in EBA
In reply to Greg Kroah-Hartman3.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Richard Weinberger <[email protected]>
commit 781932375ffc6411713ee0926ccae8596ed0261c upstream.
Fastmap cannot track the LEB unmap operation, therefore it can happen that after an interrupted erasure the mapping still looks good from Fastmap's point of view, while reading from the PEB will cause an ECC error and confuses the upper layer.
Instead of teaching users of UBI how to deal with that, we read back the VID header and check for errors. If the PEB is empty or shows ECC errors we fixup the mapping and schedule the PEB for erasure.
--- drivers/mtd/ubi/eba.c | 92 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 91 insertions(+), 1 deletion(-)
drivers/mtd/ubi/eba.c +91 -1
@@ -350,6 +350,82 @@ out_unlock:return err; } +#ifdef CONFIG_MTD_UBI_FASTMAP +/** +* check_mapping - check and fixup a mapping +* @ubi: UBI device description object +* @vol: volume description object +* @lnum: logical eraseblock number +* @pnum: physical eraseblock number +* +* Checks whether a given mapping is valid. Fastmap cannot track LEB unmap +* operations, if such an operation is interrupted the mapping still looks +* good, but upon first read an ECC is reported to the upper layer. +* Normaly during the full-scan at attach time this is fixed, for Fastmap +* we have to deal with it while reading. +* If the PEB behind a LEB shows this symthom we change the mapping to +* %UBI_LEB_UNMAPPED and schedule the PEB for erasure. +* +* Returns 0 on success, negative error code in case of failure. +*/ +static int check_mapping (struct ubi_device *ubi,struct ubi_volume *vol,int lnum, +int *pnum) +{ +int err; +struct ubi_vid_hdr *vid_hdr; + +if (!ubi->fast_attach) +return 0 ; + + vid_hdr =ubi_zalloc_vid_hdr (ubi,GFP_NOFS ); +if (!vid_hdr) +return -ENOMEM ; + + err =ubi_io_read_vid_hdr (ubi, *pnum, vid_hdr,0 ); +if (err >0 && err !=UBI_IO_BITFLIPS ) { +int torture =0 ; + +switch (err) { +case UBI_IO_FF : +case UBI_IO_FF_BITFLIPS : +case UBI_IO_BAD_HDR : +case UBI_IO_BAD_HDR_EBADMSG : +break ; +default : +ubi_assert (0 ); + } + +if (err ==UBI_IO_BAD_HDR_EBADMSG || err ==UBI_IO_FF_BITFLIPS ) + torture =1 ; + +down_read (&ubi->fm_sem); + vol->eba_tbl[lnum] =UBI_LEB_UNMAPPED ; +up_read (&ubi->fm_sem); +ubi_wl_put_peb (ubi, vol->vol_id, lnum, *pnum, torture); + + *pnum =UBI_LEB_UNMAPPED ; + }else if (err <0 ) { +ubi_err ("unable to read VID header back from PEB %i: %i" , + *pnum, err); + + goto out_free; + } + + err =0 ; + +out_free: +ubi_free_vid_hdr (ubi, vid_hdr); + +return err; +} +#else +static int check_mapping (struct ubi_device *ubi,struct ubi_volume *vol,int lnum, +int *pnum) +{ +return 0 ; +} +#endif +/** * ubi_eba_read_leb - read data. * @ubi: UBI device description object
@@ -381,7 +457,13 @@ int ubi_eba_read_leb(struct ubi_device *return err; pnum = vol->eba_tbl[lnum]; -if (pnum <0 ) { +if (pnum >=0 ) { + err =check_mapping (ubi, vol, lnum, &pnum); +if (err <0 ) + goto out_unlock; + } + +if (pnum ==UBI_LEB_UNMAPPED ) {/* * The logical eraseblock is not mapped, fill the whole buffer * with 0xFF bytes. The exception is static volumes for which
@@ -627,6 +709,14 @@ int ubi_eba_write_leb(struct ubi_device pnum = vol->eba_tbl[lnum];if (pnum >=0 ) { + err =check_mapping (ubi, vol, lnum, &pnum); +if (err <0 ) { +leb_write_unlock (ubi, vol_id, lnum); +return err; + } + } + +if (pnum >=0 ) {dbg_eba ("write %d bytes at offset %d of LEB %d:%d, PEB %d" , len, offset, vol_id, lnum, pnum);
Greg Kroah-Hartman
maintainerPATCH 5/23 netfilter: ebtables: handle string from userspace with care
In reply to Greg Kroah-Hartman3.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Paolo Abeni <[email protected]>
[ Upstream commit 94c752f99954797da583a84c4907ff19e92550a4 ]
strlcpy() can't be safely used on a user-space provided string, as it can try to read beyond the buffer's end, if the latter is not NULL terminated.
Leveraging the above, syzbot has been able to trigger the following splat:
BUG: KASAN: stack-out-of-bounds in strlcpy include/linux/string.h:300 [inline] BUG: KASAN: stack-out-of-bounds in compat_mtw_from_user net/bridge/netfilter/ebtables.c:1957 [inline] BUG: KASAN: stack-out-of-bounds in ebt_size_mwt net/bridge/netfilter/ebtables.c:2059 [inline] BUG: KASAN: stack-out-of-bounds in size_entry_mwt net/bridge/netfilter/ebtables.c:2155 [inline] BUG: KASAN: stack-out-of-bounds in compat_copy_entries+0x96c/0x14a0 net/bridge/netfilter/ebtables.c:2194 Write of size 33 at addr ffff8801b0abf888 by task syz-executor0/4504 CPU: 0 PID: 4504 Comm: syz-executor0 Not tainted 4.17.0-rc2+ #40 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 Call Trace: __dump_stack lib/dump_stack.c:77 [inline] dump_stack+0x1b9/0x294 lib/dump_stack.c:113 print_address_description+0x6c/0x20b mm/kasan/report.c:256 kasan_report_error mm/kasan/report.c:354 [inline] kasan_report.cold.7+0x242/0x2fe mm/kasan/report.c:412 check_memory_region_inline mm/kasan/kasan.c:260 [inline] check_memory_region+0x13e/0x1b0 mm/kasan/kasan.c:267 memcpy+0x37/0x50 mm/kasan/kasan.c:303 strlcpy include/linux/string.h:300 [inline] compat_mtw_from_user net/bridge/netfilter/ebtables.c:1957 [inline] ebt_size_mwt net/bridge/netfilter/ebtables.c:2059 [inline] size_entry_mwt net/bridge/netfilter/ebtables.c:2155 [inline] compat_copy_entries+0x96c/0x14a0 net/bridge/netfilter/ebtables.c:2194 compat_do_replace+0x483/0x900 net/bridge/netfilter/ebtables.c:2285 compat_do_ebt_set_ctl+0x2ac/0x324 net/bridge/netfilter/ebtables.c:2367 compat_nf_sockopt net/netfilter/nf_sockopt.c:144 [inline] compat_nf_setsockopt+0x9b/0x140 net/netfilter/nf_sockopt.c:156 compat_ip_setsockopt+0xff/0x140 net/ipv4/ip_sockglue.c:1279 inet_csk_compat_setsockopt+0x97/0x120 net/ipv4/inet_connection_sock.c:1041 compat_tcp_setsockopt+0x49/0x80 net/ipv4/tcp.c:2901 compat_sock_common_setsockopt+0xb4/0x150 net/core/sock.c:3050 __compat_sys_setsockopt+0x1ab/0x7c0 net/compat.c:403 __do_compat_sys_setsockopt net/compat.c:416 [inline] __se_compat_sys_setsockopt net/compat.c:413 [inline] __ia32_compat_sys_setsockopt+0xbd/0x150 net/compat.c:413 do_syscall_32_irqs_on arch/x86/entry/common.c:323 [inline] do_fast_syscall_32+0x345/0xf9b arch/x86/entry/common.c:394 entry_SYSENTER_compat+0x70/0x7f arch/x86/entry/entry_64_compat.S:139 RIP: 0023:0xf7fb3cb9 RSP: 002b:00000000fff0c26c EFLAGS: 00000282 ORIG_RAX: 000000000000016e RAX: ffffffffffffffda RBX: 0000000000000003 RCX: 0000000000000000 RDX: 0000000000000080 RSI: 0000000020000300 RDI: 00000000000005f4 RBP: 0000000000000000 R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000000 R12: 0000000000000000 R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000000 The buggy address belongs to the page: page:ffffea0006c2afc0 count:0 mapcount:0 mapping:0000000000000000 index:0x0 flags: 0x2fffc0000000000() raw: 02fffc0000000000 0000000000000000 0000000000000000 00000000ffffffff raw: 0000000000000000 ffffea0006c20101 0000000000000000 0000000000000000 page dumped because: kasan: bad access detected
Fix the issue replacing the unsafe function with strscpy() and taking care of possible errors.
--- net/bridge/netfilter/ebtables.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
net/bridge/netfilter/ebtables.c +2 -1
@@ -1910,7 +1910,8 @@ static int compat_mtw_from_user(struct cint off, pad =0 ;unsigned int size_kern, match_size = mwt->match_size; -strlcpy (name, mwt->u.name,sizeof (name)); +if (strscpy (name, mwt->u.name,sizeof (name)) <0 ) +return -EINVAL ;if (state->buf_kern_start) dst = state->buf_kern_start + state->buf_kern_offset;
Greg Kroah-Hartman
maintainerPATCH 6/23 atm: zatm: fix memcmp casting
In reply to Greg Kroah-Hartman3.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ivan Bornyakov <[email protected]>
[ Upstream commit f9c6442a8f0b1dde9e755eb4ff6fa22bcce4eabc ]
memcmp() returns int, but eprom_try_esi() cast it to unsigned char. One can lose significant bits and get 0 from non-0 value returned by the memcmp().
--- drivers/atm/zatm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/atm/zatm.c +2 -2
@@ -1148,8 +1148,8 @@ static void eprom_get_byte(struct zatm_d } -static unsigned char eprom_try_esi (struct atm_dev *dev,unsigned short cmd, -int offset,int swap) +static int eprom_try_esi (struct atm_dev *dev,unsigned short cmd,int offset, +int swap) {unsigned char buf[ZEPROM_SIZE ];struct zatm_dev *zatm_dev;
Greg Kroah-Hartman
maintainerPATCH 7/23 net: qmi_wwan: Add Netgear Aircard 779S
In reply to Greg Kroah-Hartman3.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Josh Hill <[email protected]>
[ Upstream commit 2415f3bd059fe050eb98aedf93664d000ceb4e92 ]
Add support for Netgear Aircard 779S
--- drivers/net/usb/qmi_wwan.c | 1 + 1 file changed, 1 insertion(+)
drivers/net/usb/qmi_wwan.c +1 -0
@@ -677,6 +677,7 @@ static const struct usb_device_id produc {QMI_FIXED_INTF(0x05c6, 0x920d, 0)}, {QMI_FIXED_INTF(0x05c6, 0x920d, 5)}, {QMI_FIXED_INTF(0x0846, 0x68a2, 8)}, + {QMI_FIXED_INTF(0x0846, 0x68d3, 8)}, /* Netgear Aircard 779S */ {QMI_FIXED_INTF(0x12d1, 0x140c, 1)}, /* Huawei E173 */ {QMI_FIXED_INTF(0x12d1, 0x14ac, 1)}, /* Huawei E1820 */ {QMI_FIXED_INTF(0x1435, 0xd181, 3)}, /* Wistron NeWeb D18Q1 */
Greg Kroah-Hartman
maintainerPATCH 8/23 net/sonic: Use dma_mapping_error()
In reply to Greg Kroah-Hartman3.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Finn Thain <[email protected]>
[ Upstream commit 26de0b76d9ba3200f09c6cb9d9618bda338be5f7 ]
With CONFIG_DMA_API_DEBUG=y, calling sonic_open() produces the message, "DMA-API: device driver failed to check map error". Add the missing dma_mapping_error() call.
--- drivers/net/ethernet/natsemi/sonic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/ethernet/natsemi/sonic.c +1 -1
@@ -71,7 +71,7 @@ static int sonic_open(struct net_devicefor (i =0 ; i <SONIC_NUM_RRS ; i++) {dma_addr_t laddr =dma_map_single (lp->device,skb_put (lp->rx_skb[i],SONIC_RBSIZE ),SONIC_RBSIZE ,DMA_FROM_DEVICE ); -if (!laddr) { +if (dma_mapping_error (lp->device, laddr)) {while (i >0 ) {/* free any that were mapped successfully */ i--;dma_unmap_single (lp->device, lp->rx_laddr[i],SONIC_RBSIZE ,DMA_FROM_DEVICE );
Greg Kroah-Hartman
maintainerPATCH 9/23 scsi: sg: mitigate read/write abuse
In reply to Greg Kroah-Hartman3.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jann Horn <[email protected]>
commit 26b5b874aff5659a7e26e5b1997e3df2c41fa7fd upstream.
As Al Viro noted in commit 128394eff343 ("sg_write()/bsg_write() is not fit to be called under KERNEL_DS"), sg improperly accesses userspace memory outside the provided buffer, permitting kernel memory corruption via splice(). But it doesn't just do it on ->write(), also on ->read().
As a band-aid, make sure that the ->read() and ->write() handlers can not be called in weird contexts (kernel context or credentials different from file opener), like for ib_safe_file_access().
If someone needs to use these interfaces from different security contexts, a new interface should be written that goes through the ->ioctl() handler.
I've mostly copypasted ib_safe_file_access() over as sg_safe_file_access() because I couldn't find a good common header - please tell me if you know a better way.
[mkp: s/_safe_/_check_/]
--- drivers/scsi/sg.c | 42 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 40 insertions(+), 2 deletions(-)
drivers/scsi/sg.c +40 -2
@@ -52,6 +52,7 @@ static int sg_version_num = 30536; /* 2#include <linux/atomic.h> #include <linux/ratelimit.h> #include <linux/sizes.h> +#include <linux/cred.h> /* for sg_check_file_access() */ #include "scsi.h" #include <scsi/scsi_dbg.h>
@@ -222,6 +223,33 @@ static void sg_device_destroy(struct kre sdev_printk(prefix, (sdp)->device, "[%s] " fmt, \ (sdp)->disk->disk_name, ##a) +/* +* The SCSI interfaces that use read() and write() as an asynchronous variant of +* ioctl(..., SG_IO, ...) are fundamentally unsafe, since there are lots of ways +* to trigger read() and write() calls from various contexts with elevated +* privileges. This can lead to kernel memory corruption (e.g. if these +* interfaces are called through splice()) and privilege escalation inside +* userspace (e.g. if a process with access to such a device passes a file +* descriptor to a SUID binary as stdin/stdout/stderr). +* +* This function provides protection for the legacy API by restricting the +* calling context. +*/ +static int sg_check_file_access (struct file *filp,const char *caller) +{ +if (filp->f_cred !=current_real_cred ()) { +pr_err_once ("%s: process %d (%s) changed security contexts after opening file descriptor, this is not allowed.\n" , + caller,task_tgid_vnr (current), current->comm); +return -EPERM ; + } +if (unlikely (segment_eq (get_fs (),KERNEL_DS ))) { +pr_err_once ("%s: process %d (%s) called from kernel context, this is not allowed.\n" , + caller,task_tgid_vnr (current), current->comm); +return -EACCES ; + } +return 0 ; +} +static int sg_allow_access (struct file *filp,unsigned char *cmd) {struct sg_fd *sfp = filp->private_data;
@@ -406,6 +434,14 @@ sg_read(struct file *filp, char __user *struct sg_header *old_hdr =NULL ;int retval =0 ; +/* +* This could cause a response to be stranded. Close the associated +* file descriptor to free up any resources being held. +*/ + retval =sg_check_file_access (filp, __func__); +if (retval) +return retval; +if ((!(sfp = (Sg_fd *) filp->private_data)) || (!(sdp = sfp->parentdp)))return -ENXIO ; SCSI_LOG_TIMEOUT(3, sg_printk(KERN_INFO, sdp,
@@ -593,9 +629,11 @@ sg_write(struct file *filp, const char _struct sg_header old_hdr;sg_io_hdr_t *hp;unsigned char cmnd[SG_MAX_CDB_SIZE ]; +int retval; -if (unlikely (segment_eq (get_fs (),KERNEL_DS ))) -return -EINVAL ; + retval =sg_check_file_access (filp, __func__); +if (retval) +return retval;if ((!(sfp = (Sg_fd *) filp->private_data)) || (!(sdp = sfp->parentdp)))return -ENXIO ;
Greg Kroah-Hartman
maintainerPATCH 10/23 cifs: Fix infinite loop when using hard mount option
In reply to Greg Kroah-Hartman3.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Paulo Alcantara <[email protected]>
commit 7ffbe65578b44fafdef577a360eb0583929f7c6e upstream.
For every request we send, whether it is SMB1 or SMB2+, we attempt to reconnect tcon (cifs_reconnect_tcon or smb2_reconnect) before carrying out the request.
So, while server->tcpStatus != CifsNeedReconnect, we wait for the reconnection to succeed on wait_event_interruptible_timeout(). If it returns, that means that either the condition was evaluated to true, or timeout elapsed, or it was interrupted by a signal.
Since we're not handling the case where the process woke up due to a received signal (-ERESTARTSYS), the next call to wait_event_interruptible_timeout() will _always_ fail and we end up looping forever inside either cifs_reconnect_tcon() or smb2_reconnect().
Here's an example of how to trigger that:
$ mount.cifs //foo/share /mnt/test -o username=foo,password=foo,vers=1.0,hard
(break connection to server before executing bellow cmd)
$ stat -f /mnt/test & sleep 140 [1] 2511
$ ps -aux -q 2511 USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND root 2511 0.0 0.0 12892 1008 pts/0 S 12:24 0:00 stat -f /mnt/test
$ kill -9 2511
(wait for a while; process is stuck in the kernel)
$ ps -aux -q 2511 USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND root 2511 83.2 0.0 12892 1008 pts/0 R 12:24 30:01 stat -f /mnt/test
By using 'hard' mount point means that cifs.ko will keep retrying indefinitely, however we must allow the process to be killed otherwise it would hang the system.
--- fs/cifs/cifssmb.c | 10 ++++++++-- fs/cifs/smb2pdu.c | 18 ++++++++++++------ 2 files changed, 20 insertions(+), 8 deletions(-)
fs/cifs/cifssmb.c +8 -2
@@ -150,8 +150,14 @@ cifs_reconnect_tcon(struct cifs_tcon *tc* greater than cifs socket timeout which is 7 seconds */ while (server->tcpStatus == CifsNeedReconnect) { -wait_event_interruptible_timeout (server->response_q, - (server->tcpStatus != CifsNeedReconnect),10 *HZ ); + rc =wait_event_interruptible_timeout (server->response_q, + (server->tcpStatus != CifsNeedReconnect), +10 *HZ ); +if (rc <0 ) { +cifs_dbg (FYI ,"%s: aborting reconnect due to a received" +" signal by the process\n" , __func__); +return -ERESTARTSYS ; + }/* are we still trying to reconnect? */ if (server->tcpStatus != CifsNeedReconnect)
fs/cifs/smb2pdu.c +12 -6
@@ -144,7 +144,7 @@ out:static int smb2_reconnect (__le16 smb2_command,struct cifs_tcon *tcon) { -int rc =0 ; +int rc;struct nls_table *nls_codepage;struct cifs_ses *ses;struct TCP_Server_Info *server;
@@ -155,10 +155,10 @@ smb2_reconnect(__le16 smb2_command, stru* for those three - in the calling routine. */ if (tcon ==NULL ) -return rc; +return 0 ;if (smb2_command ==SMB2_TREE_CONNECT ) -return rc; +return 0 ;if (tcon->tidStatus == CifsExiting) {/*
@@ -201,8 +201,14 @@ smb2_reconnect(__le16 smb2_command, strureturn -EAGAIN ; } -wait_event_interruptible_timeout (server->response_q, - (server->tcpStatus != CifsNeedReconnect),10 *HZ ); + rc =wait_event_interruptible_timeout (server->response_q, + (server->tcpStatus != CifsNeedReconnect), +10 *HZ ); +if (rc <0 ) { +cifs_dbg (FYI ,"%s: aborting reconnect due to a received" +" signal by the process\n" , __func__); +return -ERESTARTSYS ; + }/* are we still trying to reconnect? */ if (server->tcpStatus != CifsNeedReconnect)
@@ -220,7 +226,7 @@ smb2_reconnect(__le16 smb2_command, stru }if (!tcon->ses->need_reconnect && !tcon->need_reconnect) -return rc; +return 0 ; nls_codepage =load_nls_default ();
Greg Kroah-Hartman
maintainerPATCH 11/23 ext4: make sure bitmaps and the inode table dont overlap with bg descriptors
In reply to Greg Kroah-Hartman3.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Theodore Ts'o <[email protected]>
commit 77260807d1170a8cf35dbb06e07461a655f67eee upstream.
It's really bad when the allocation bitmaps and the inode table overlap with the block group descriptors, since it causes random corruption of the bg descriptors. So we really want to head those off at the pass.
https://bugzilla.kernel.org/show_bug.cgi?id=199865
--- fs/ext4/super.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+)
fs/ext4/super.c +25 -0
@@ -2064,6 +2064,7 @@ static int ext4_check_descriptors(structstruct ext4_sb_info *sbi =EXT4_SB (sb);ext4_fsblk_t first_block =le32_to_cpu (sbi->s_es->s_first_data_block);ext4_fsblk_t last_block; +ext4_fsblk_t last_bg_block = sb_block +ext4_bg_num_gdb (sb,0 ) +1 ;ext4_fsblk_t block_bitmap;ext4_fsblk_t inode_bitmap;ext4_fsblk_t inode_table;
@@ -2096,6 +2097,14 @@ static int ext4_check_descriptors(structif (!(sb->s_flags &MS_RDONLY ))return 0 ; } +if (block_bitmap >= sb_block +1 && + block_bitmap <= last_bg_block) { +ext4_msg (sb,KERN_ERR ,"ext4_check_descriptors: " +"Block bitmap for group %u overlaps " +"block group descriptors" , i); +if (!(sb->s_flags &MS_RDONLY )) +return 0 ; + }if (block_bitmap < first_block || block_bitmap > last_block) {ext4_msg (sb,KERN_ERR ,"ext4_check_descriptors: " "Block bitmap for group %u not in group "
@@ -2110,6 +2119,14 @@ static int ext4_check_descriptors(structif (!(sb->s_flags &MS_RDONLY ))return 0 ; } +if (inode_bitmap >= sb_block +1 && + inode_bitmap <= last_bg_block) { +ext4_msg (sb,KERN_ERR ,"ext4_check_descriptors: " +"Inode bitmap for group %u overlaps " +"block group descriptors" , i); +if (!(sb->s_flags &MS_RDONLY )) +return 0 ; + }if (inode_bitmap < first_block || inode_bitmap > last_block) {ext4_msg (sb,KERN_ERR ,"ext4_check_descriptors: " "Inode bitmap for group %u not in group "
@@ -2124,6 +2141,14 @@ static int ext4_check_descriptors(structif (!(sb->s_flags &MS_RDONLY ))return 0 ; } +if (inode_table >= sb_block +1 && + inode_table <= last_bg_block) { +ext4_msg (sb,KERN_ERR ,"ext4_check_descriptors: " +"Inode table for group %u overlaps " +"block group descriptors" , i); +if (!(sb->s_flags &MS_RDONLY )) +return 0 ; + }if (inode_table < first_block || inode_table + sbi->s_itb_per_group -1 > last_block) { ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: "
Greg Kroah-Hartman
maintainerPATCH 12/23 ext4: clear i_data in ext4_inode_info when removing inline data
In reply to Greg Kroah-Hartman3.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Theodore Ts'o <[email protected]>
commit 6e8ab72a812396996035a37e5ca4b3b99b5d214b upstream.
When converting from an inode from storing the data in-line to a data block, ext4_destroy_inline_data_nolock() was only clearing the on-disk copy of the i_blocks[] array. It was not clearing copy of the i_blocks[] in ext4_inode_info, in i_data[], which is the copy actually used by ext4_map_blocks().
This didn't matter much if we are using extents, since the extents header would be invalid and thus the extents could would re-initialize the extents tree. But if we are using indirect blocks, the previous contents of the i_blocks array will be treated as block numbers, with potentially catastrophic results to the file system integrity and/or user data.
This gets worse if the file system is using a 1k block size and s_first_data is zero, but even without this, the file system can get quite badly corrupted.
This addresses CVE-2018-10881.
https://bugzilla.kernel.org/show_bug.cgi?id=200015
--- fs/ext4/inline.c | 1 + 1 file changed, 1 insertion(+)
fs/ext4/inline.c +1 -0
@@ -432,6 +432,7 @@ static int ext4_destroy_inline_data_nolomemset ((void *)ext4_raw_inode (&is.iloc)->i_block,0 ,EXT4_MIN_INLINE_DATA_SIZE ); +memset (ei->i_data,0 ,EXT4_MIN_INLINE_DATA_SIZE );if (EXT4_HAS_INCOMPAT_FEATURE (inode->i_sb,EXT4_FEATURE_INCOMPAT_EXTENTS )) {
Greg Kroah-Hartman
maintainerPATCH 13/23 ext4: add more mount time checks of the superblock
In reply to Greg Kroah-Hartman3.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Theodore Ts'o <[email protected]>
commit bfe0a5f47ada40d7984de67e59a7d3390b9b9ecc upstream.
The kernel's ext4 mount-time checks were more permissive than e2fsprogs's libext2fs checks when opening a file system. The superblock is considered too insane for debugfs or e2fsck to operate on it, the kernel has no business trying to mount it.
This will make file system fuzzing tools work harder, but the failure cases that they find will be more useful and be easier to evaluate.
--- fs/ext4/super.c | 37 ++++++++++++++++++++++++++----------- 1 file changed, 26 insertions(+), 11 deletions(-)
fs/ext4/super.c +26 -11
@@ -3738,6 +3738,13 @@ static int ext4_fill_super(struct super_ le32_to_cpu(es->s_log_block_size)); goto failed_mount; } +if (le32_to_cpu (es->s_log_cluster_size) > + (EXT4_MAX_CLUSTER_LOG_SIZE -EXT4_MIN_BLOCK_LOG_SIZE )) { +ext4_msg (sb,KERN_ERR , +"Invalid log cluster size: %u" , +le32_to_cpu (es->s_log_cluster_size)); + goto failed_mount; + }if (le16_to_cpu (sbi->s_es->s_reserved_gdt_blocks) > (blocksize /4 )) { ext4_msg(sb, KERN_ERR,
@@ -3861,13 +3868,6 @@ static int ext4_fill_super(struct super_ "block size (%d)", clustersize, blocksize); goto failed_mount; } -if (le32_to_cpu (es->s_log_cluster_size) > - (EXT4_MAX_CLUSTER_LOG_SIZE -EXT4_MIN_BLOCK_LOG_SIZE )) { -ext4_msg (sb,KERN_ERR , -"Invalid log cluster size: %u" , -le32_to_cpu (es->s_log_cluster_size)); - goto failed_mount; - } sbi->s_cluster_bits =le32_to_cpu (es->s_log_cluster_size) -le32_to_cpu (es->s_log_block_size); sbi->s_clusters_per_group =
@@ -3888,10 +3888,10 @@ static int ext4_fill_super(struct super_ } }else {if (clustersize != blocksize) { -ext4_warning (sb,"fragment/cluster size (%d) != " -"block size (%d)" , clustersize, - blocksize); - clustersize = blocksize; +ext4_msg (sb,KERN_ERR , +"fragment/cluster size (%d) != " +"block size (%d)" , clustersize, blocksize); + goto failed_mount; }if (sbi->s_blocks_per_group > blocksize *8 ) { ext4_msg(sb, KERN_ERR,
@@ -3945,6 +3945,13 @@ static int ext4_fill_super(struct super_ ext4_blocks_count(es)); goto failed_mount; } +if ((es->s_first_data_block ==0 ) && (es->s_log_block_size ==0 ) && + (sbi->s_cluster_ratio ==1 )) { +ext4_msg (sb,KERN_WARNING ,"bad geometry: first data " +"block is 0 with a 1k block and cluster size" ); + goto failed_mount; + } + blocks_count = (ext4_blocks_count (es) -le32_to_cpu (es->s_first_data_block) +EXT4_BLOCKS_PER_GROUP (sb) -1 );
@@ -3980,6 +3987,14 @@ static int ext4_fill_super(struct super_ ret = -ENOMEM ; goto failed_mount; } +if (((u64 )sbi->s_groups_count * sbi->s_inodes_per_group) != +le32_to_cpu (es->s_inodes_count)) { +ext4_msg (sb,KERN_ERR ,"inodes count not valid: %u vs %llu" , +le32_to_cpu (es->s_inodes_count), + ((u64 )sbi->s_groups_count * sbi->s_inodes_per_group)); + ret = -EINVAL ; + goto failed_mount; + }if (ext4_proc_root) sbi->s_proc =proc_mkdir (sb->s_id, ext4_proc_root);
Greg Kroah-Hartman
maintainerPATCH 14/23 HID: i2c-hid: Fix "incomplete report" noise
In reply to Greg Kroah-Hartman3.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jason Andryuk <[email protected]>
commit ef6eaf27274c0351f7059163918f3795da13199c upstream.
Commit ac75a041048b ("HID: i2c-hid: fix size check and type usage") started writing messages when the ret_size is <= 2 from i2c_master_recv. However, my device i2c-DLL07D1 returns 2 for a short period of time (~0.5s) after I stop moving the pointing stick or touchpad. It varies, but you get ~50 messages each time which spams the log hard.
[ 95.925055] i2c_hid i2c-DLL07D1:01: i2c_hid_get_input: incomplete report (83/2)
This has also been observed with a i2c-ALP0017.
[ 1781.266353] i2c_hid i2c-ALP0017:00: i2c_hid_get_input: incomplete report (30/2)
Only print the message when ret_size is totally invalid and less than 2 to cut down on the log spam.
--- drivers/hid/i2c-hid/i2c-hid.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/hid/i2c-hid/i2c-hid.c +1 -1
@@ -399,7 +399,7 @@ static void i2c_hid_get_input(struct i2creturn ; } -if ((ret_size > size) || (ret_size <=2 )) { +if ((ret_size > size) || (ret_size <2 )) {dev_err (&ihid->client->dev,"%s: incomplete report (%d/%d)\n" , __func__, size, ret_size);return ;
Greg Kroah-Hartman
maintainerPATCH 15/23 HID: debug: check length before copy_to_user()
In reply to Greg Kroah-Hartman3.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Daniel Rosenberg <[email protected]>
commit 717adfdaf14704fd3ec7fa2c04520c0723247eac upstream.
If our length is greater than the size of the buffer, we overflow the buffer
--- drivers/hid/hid-debug.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
drivers/hid/hid-debug.c +7 -1
@@ -1150,6 +1150,8 @@ copy_rest: goto out;if (list->tail > list->head) { len = list->tail - list->head; +if (len > count) + len = count;if (copy_to_user (buffer + ret, &list->hid_debug_buf[list->head], len)) { ret = -EFAULT ;
@@ -1159,6 +1161,8 @@ copy_rest: list->head += len; }else { len =HID_DEBUG_BUFSIZE - list->head; +if (len > count) + len = count;if (copy_to_user (buffer, &list->hid_debug_buf[list->head], len)) { ret = -EFAULT ;
@@ -1166,7 +1170,9 @@ copy_rest: } list->head =0 ; ret += len; - goto copy_rest; + count -= len; +if (count >0 ) + goto copy_rest; } }
Greg Kroah-Hartman
maintainerPATCH 16/23 media: cx25840: Use subdev host data for PLL override
In reply to Greg Kroah-Hartman3.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Brad Love <[email protected]>
commit 3ee9bc12342cf546313d300808ff47d7dbb8e7db upstream.
The cx25840 driver currently configures 885, 887, and 888 using default divisors for each chip. This check to see if the cx23885 driver has passed the cx25840 a non-default clock rate for a specific chip. If a cx23885 board has left clk_freq at 0, the clock default values will be used to configure the PLLs.
This patch only has effect on 888 boards who set clk_freq to 25M.
--- drivers/media/i2c/cx25840/cx25840-core.c | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-)
drivers/media/i2c/cx25840/cx25840-core.c +22 -6
@@ -467,8 +467,13 @@ static void cx23885_initialize(struct i2 {DEFINE_WAIT (wait);struct cx25840_state *state =to_state (i2c_get_clientdata (client)); +u32 clk_freq =0 ;struct workqueue_struct *q; +/* cx23885 sets hostdata to clk_freq pointer */ +if (v4l2_get_subdev_hostdata (&state->sd)) + clk_freq = *((u32 *)v4l2_get_subdev_hostdata (&state->sd)); +/* * Come out of digital power down * The CX23888, at least, needs this, otherwise registers aside from
@@ -504,8 +509,13 @@ static void cx23885_initialize(struct i2* 50.0 MHz * (0xb + 0xe8ba26/0x2000000)/4 = 5 * 28.636363 MHz * 572.73 MHz before post divide */ -/* HVR1850 or 50MHz xtal */ -cx25840_write (client,0x2 ,0x71 ); +if (clk_freq ==25000000 ) { +/* 888/ImpactVCBe or 25Mhz xtal */ + ;/* nothing to do */ + }else { +/* HVR1850 or 50MHz xtal */ +cx25840_write (client,0x2 ,0x71 ); + }cx25840_write4 (client,0x11c ,0x01d1744c );cx25840_write4 (client,0x118 ,0x00000416 );cx25840_write4 (client,0x404 ,0x0010253e );
@@ -548,9 +558,15 @@ static void cx23885_initialize(struct i2/* HVR1850 */ switch (state->id) {case CX23888_AV : -/* 888/HVR1250 specific */ -cx25840_write4 (client,0x10c ,0x13333333 ); -cx25840_write4 (client,0x108 ,0x00000515 ); +if (clk_freq ==25000000 ) { +/* 888/ImpactVCBe or 25MHz xtal */ +cx25840_write4 (client,0x10c ,0x01b6db7b ); +cx25840_write4 (client,0x108 ,0x00000512 ); + }else { +/* 888/HVR1250 or 50MHz xtal */ +cx25840_write4 (client,0x10c ,0x13333333 ); +cx25840_write4 (client,0x108 ,0x00000515 ); + }break ;default :cx25840_write4 (client,0x10c ,0x002be2c9 );
@@ -577,7 +593,7 @@ static void cx23885_initialize(struct i2* 368.64 MHz before post divide * 122.88 MHz / 0xa = 12.288 MHz */ -/* HVR1850 or 50MHz xtal */ +/* HVR1850 or 50MHz xtal or 25MHz xtal */ cx25840_write4 (client,0x114 ,0x017dbf48 );cx25840_write4 (client,0x110 ,0x000a030e );break ;
Greg Kroah-Hartman
maintainerPATCH 17/23 dm bufio: avoid sleeping while holding the dm_bufio lock
In reply to Greg Kroah-Hartman3.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Douglas Anderson <[email protected]>
commit 9ea61cac0b1ad0c09022f39fd97e9b99a2cfc2dc upstream.
We've seen in-field reports showing _lots_ (18 in one case, 41 in another) of tasks all sitting there blocked on:
mutex_lock+0x4c/0x68 dm_bufio_shrink_count+0x38/0x78 shrink_slab.part.54.constprop.65+0x100/0x464 shrink_zone+0xa8/0x198
In the two cases analyzed, we see one task that looks like this:
Workqueue: kverityd verity_prefetch_io __switch_to+0x9c/0xa8 __schedule+0x440/0x6d8 schedule+0x94/0xb4 schedule_timeout+0x204/0x27c schedule_timeout_uninterruptible+0x44/0x50 wait_iff_congested+0x9c/0x1f0 shrink_inactive_list+0x3a0/0x4cc shrink_lruvec+0x418/0x5cc shrink_zone+0x88/0x198 try_to_free_pages+0x51c/0x588 __alloc_pages_nodemask+0x648/0xa88 __get_free_pages+0x34/0x7c alloc_buffer+0xa4/0x144 __bufio_new+0x84/0x278 dm_bufio_prefetch+0x9c/0x154 verity_prefetch_io+0xe8/0x10c process_one_work+0x240/0x424 worker_thread+0x2fc/0x424 kthread+0x10c/0x114
...and that looks to be the one holding the mutex.
The problem has been reproduced on fairly easily:
0. Be running Chrome OS w/ verity enabled on the root filesystem
1. Pick test patch: http://crosreview.com/412360
2. Install launchBalloons.sh and balloon.arm from
http://crbug.com/468342 ...that's just a memory stress test app. 3. On a 4GB rk3399 machine, run nice ./launchBalloons.sh 4 900 100000
...that tries to eat 4 * 900 MB of memory and keep accessing.
4. Login to the Chrome web browser and restore many tabs
With that, I've seen printouts like:
DOUG: long bufio 90758 ms
...and stack trace always show's we're in dm_bufio_prefetch().
The problem is that we try to allocate memory with GFP_NOIO while we're holding the dm_bufio lock. Instead we should be using GFP_NOWAIT. Using GFP_NOIO can cause us to sleep while holding the lock and that causes the above problems.
The current behavior explained by David Rientjes:
It will still try reclaim initially because __GFP_WAIT (or __GFP_KSWAPD_RECLAIM) is set by GFP_NOIO. This is the cause of contention on dm_bufio_lock() that the thread holds. You want to pass GFP_NOWAIT instead of GFP_NOIO to alloc_buffer() when holding a mutex that can be contended by a concurrent slab shrinker (if count_objects didn't use a trylock, this pattern would trivially deadlock).
This change significantly increases responsiveness of the system while in this state. It makes a real difference because it unblocks kswapd. In the bug report analyzed, kswapd was hung:
kswapd0 D ffffffc000204fd8 0 72 2 0x00000000
Call trace: [<ffffffc000204fd8>] __switch_to+0x9c/0xa8 [<ffffffc00090b794>] __schedule+0x440/0x6d8 [<ffffffc00090bac0>] schedule+0x94/0xb4 [<ffffffc00090be44>] schedule_preempt_disabled+0x28/0x44 [<ffffffc00090d900>] __mutex_lock_slowpath+0x120/0x1ac [<ffffffc00090d9d8>] mutex_lock+0x4c/0x68 [<ffffffc000708e7c>] dm_bufio_shrink_count+0x38/0x78 [<ffffffc00030b268>] shrink_slab.part.54.constprop.65+0x100/0x464 [<ffffffc00030dbd8>] shrink_zone+0xa8/0x198 [<ffffffc00030e578>] balance_pgdat+0x328/0x508 [<ffffffc00030eb7c>] kswapd+0x424/0x51c [<ffffffc00023f06c>] kthread+0x10c/0x114 [<ffffffc000203dd0>] ret_from_fork+0x10/0x40
By unblocking kswapd memory pressure should be reduced.
--- drivers/md/dm-bufio.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
drivers/md/dm-bufio.c +3 -2
@@ -766,7 +766,8 @@ static struct dm_buffer *__alloc_buffer_* dm-bufio is resistant to allocation failures (it just keeps * one buffer reserved in cases all the allocations fail). * So set flags to not try too hard: -* GFP_NOIO: don't recurse into the I/O layer +* GFP_NOWAIT: don't wait; if we need to sleep we'll release our +* mutex and wait ourselves. * __GFP_NORETRY: don't retry and rather return failure * __GFP_NOMEMALLOC: don't use emergency reserves * __GFP_NOWARN: don't print a warning in case of failure
@@ -776,7 +777,7 @@ static struct dm_buffer *__alloc_buffer_*/ while (1 ) {if (dm_bufio_cache_size_latch !=1 ) { - b =alloc_buffer (c,GFP_NOIO | __GFP_NORETRY | __GFP_NOMEMALLOC | __GFP_NOWARN); + b =alloc_buffer (c,GFP_NOWAIT | __GFP_NORETRY | __GFP_NOMEMALLOC | __GFP_NOWARN);if (b)return b; }
Greg Kroah-Hartman
maintainerPATCH 18/23 dm bufio: drop the lock when doing GFP_NOIO allocation
In reply to Greg Kroah-Hartman3.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mikulas Patocka <[email protected]>
commit 41c73a49df31151f4ff868f28fe4f129f113fa2c upstream.
If the first allocation attempt using GFP_NOWAIT fails, drop the lock and retry using GFP_NOIO allocation (lock is dropped because the allocation can take some time).
Note that we won't do GFP_NOIO allocation when we loop for the second time, because the lock shouldn't be dropped between __wait_for_free_buffer and __get_unclaimed_buffer.
--- drivers/md/dm-bufio.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
drivers/md/dm-bufio.c +10 -0
@@ -761,6 +761,7 @@ enum new_flag {static struct dm_buffer *__alloc_buffer_wait_no_callback (struct dm_bufio_client *c,enum new_flag nf) {struct dm_buffer *b; +bool tried_noio_alloc = false;/* * dm-bufio is resistant to allocation failures (it just keeps
@@ -785,6 +786,15 @@ static struct dm_buffer *__alloc_buffer_if (nf ==NF_PREFETCH )return NULL ; +if (dm_bufio_cache_size_latch !=1 && !tried_noio_alloc) { +dm_bufio_unlock (c); + b =alloc_buffer (c,GFP_NOIO | __GFP_NORETRY | __GFP_NOMEMALLOC | __GFP_NOWARN); +dm_bufio_lock (c); +if (b) +return b; + tried_noio_alloc = true; + } +if (!list_empty (&c->reserved_buffers)) { b =list_entry (c->reserved_buffers.next, struct dm_buffer, lru_list);
Greg Kroah-Hartman
maintainerPATCH 19/23 mtd: rawnand: mxc: set spare area size register explicitly
In reply to Greg Kroah-Hartman3.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Martin Kaiser <[email protected]>
commit 3f77f244d8ec28e3a0a81240ffac7d626390060c upstream.
The v21 version of the NAND flash controller contains a Spare Area Size Register (SPAS) at offset 0x10. Its setting defaults to the maximum spare area size of 218 bytes. The size that is set in this register is used by the controller when it calculates the ECC bytes internally in hardware.
Usually, this register is updated from settings in the IIM fuses when the system is booting from NAND flash. For other boot media, however, the SPAS register remains at the default setting, which may not work for the particular flash chip on the board. The same goes for flash chips whose configuration cannot be set in the IIM fuses (e.g. chips with 2k sector size and 128 bytes spare area size can't be configured in the IIM fuses on imx25 systems).
Set the SPAS register explicitly during the preset operation. Derive the register value from mtd->oobsize that was detected during probe by decoding the flash chip's ID bytes.
While at it, rename the define for the spare area register's offset to NFC_V21_RSLTSPARE_AREA. The register at offset 0x10 on v1 controllers is different from the register on v21 controllers.
--- drivers/mtd/nand/mxc_nand.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
drivers/mtd/nand/mxc_nand.c +4 -1
@@ -49,7 +49,7 @@#define NFC_V1_V2_CONFIG (host->regs + 0x0a)#define NFC_V1_V2_ECC_STATUS_RESULT (host->regs + 0x0c)#define NFC_V1_V2_RSLTMAIN_AREA (host->regs + 0x0e) -#define NFC_V1_V2_RSLTSPARE_AREA (host->regs + 0x10) +#define NFC_V21_RSLTSPARE_AREA (host->regs + 0x10)#define NFC_V1_V2_WRPROT (host->regs + 0x12)#define NFC_V1_UNLOCKSTART_BLKADDR (host->regs + 0x14)#define NFC_V1_UNLOCKEND_BLKADDR (host->regs + 0x16)
@@ -958,6 +958,9 @@ static void preset_v2(struct mtd_info *mwritew (config1,NFC_V1_V2_CONFIG1 );/* preset operation */ +/* spare area size in 16-bit half-words */ +writew (mtd->oobsize /2 ,NFC_V21_RSLTSPARE_AREA ); +/* Unlock the internal RAM Buffer */ writew (0x2 ,NFC_V1_V2_CONFIG );
Greg Kroah-Hartman
maintainerPATCH 20/23 mtd: cfi_cmdset_0002: Change definition naming to retry write operation
In reply to Greg Kroah-Hartman3.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tokunori Ikegami <[email protected]>
commit 85a82e28b023de9b259a86824afbd6ba07bd6475 upstream.
The definition can be used for other program and erase operations also. So change the naming to MAX_RETRIES from MAX_WORD_RETRIES.
--- drivers/mtd/chips/cfi_cmdset_0002.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/mtd/chips/cfi_cmdset_0002.c +3 -3
@@ -42,7 +42,7 @@#define AMD_BOOTLOC_BUG #define FORCE_WORD_WRITE 0 -#define MAX_WORD_RETRIES 3 +#define MAX_RETRIES 3#define SST49LF004B 0x0060#define SST49LF040B 0x0050
@@ -1645,7 +1645,7 @@ static int __xipram do_write_oneword(strmap_write ( map,CMD (0xF0 ), chip->start );/* FIXME - should have reset delay before continuing */ -if (++retry_cnt <=MAX_WORD_RETRIES ) +if (++retry_cnt <=MAX_RETRIES ) goto retry; ret = -EIO ;
@@ -2104,7 +2104,7 @@ retry:map_write (map,CMD (0xF0 ), chip->start);/* FIXME - should have reset delay before continuing */ -if (++retry_cnt <=MAX_WORD_RETRIES ) +if (++retry_cnt <=MAX_RETRIES ) goto retry; ret = -EIO ;
Greg Kroah-Hartman
maintainerPATCH 21/23 mtd: cfi_cmdset_0002: Change erase functions to retry for error
In reply to Greg Kroah-Hartman3.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tokunori Ikegami <[email protected]>
commit 45f75b8a919a4255f52df454f1ffdee0e42443b2 upstream.
For the word write functions it is retried for error. But it is not implemented to retry for the erase functions. To make sure for the erase functions change to retry as same.
This is needed to prevent the flash erase error caused only once. It was caused by the error case of chip_good() in the do_erase_oneblock(). Also it was confirmed on the MACRONIX flash device MX29GL512FHT2I-11G. But the error issue behavior is not able to reproduce at this moment. The flash controller is parallel Flash interface integrated on BCM53003.
--- drivers/mtd/chips/cfi_cmdset_0002.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
drivers/mtd/chips/cfi_cmdset_0002.c +10 -0
@@ -2239,6 +2239,7 @@ static int __xipram do_erase_chip(structunsigned long int adr;DECLARE_WAITQUEUE (wait, current);int ret =0 ; +int retry_cnt =0 ; adr = cfi->addr_unlock1;
@@ -2256,6 +2257,7 @@ static int __xipram do_erase_chip(structENABLE_VPP (map);xip_disable (map, chip, adr); + retry:cfi_send_gen_cmd (0xAA , cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type,NULL );cfi_send_gen_cmd (0x55 , cfi->addr_unlock2, chip->start, map, cfi, cfi->device_type,NULL );cfi_send_gen_cmd (0x80 , cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type,NULL );
@@ -2310,6 +2312,9 @@ static int __xipram do_erase_chip(structmap_write ( map,CMD (0xF0 ), chip->start );/* FIXME - should have reset delay before continuing */ +if (++retry_cnt <=MAX_RETRIES ) + goto retry; + ret = -EIO ; }
@@ -2329,6 +2334,7 @@ static int __xipram do_erase_oneblock(stunsigned long timeo = jiffies +HZ ;DECLARE_WAITQUEUE (wait, current);int ret =0 ; +int retry_cnt =0 ; adr += chip->start;
@@ -2346,6 +2352,7 @@ static int __xipram do_erase_oneblock(stENABLE_VPP (map);xip_disable (map, chip, adr); + retry:cfi_send_gen_cmd (0xAA , cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type,NULL );cfi_send_gen_cmd (0x55 , cfi->addr_unlock2, chip->start, map, cfi, cfi->device_type,NULL );cfi_send_gen_cmd (0x80 , cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type,NULL );
@@ -2403,6 +2410,9 @@ static int __xipram do_erase_oneblock(stmap_write ( map,CMD (0xF0 ), chip->start );/* FIXME - should have reset delay before continuing */ +if (++retry_cnt <=MAX_RETRIES ) + goto retry; + ret = -EIO ; }
Greg Kroah-Hartman
maintainerPATCH 22/23 mtd: cfi_cmdset_0002: Change erase functions to check chip good only
In reply to Greg Kroah-Hartman3.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tokunori Ikegami <[email protected]>
commit 79ca484b613041ca223f74b34608bb6f5221724b upstream.
Currently the functions use to check both chip ready and good. But the chip ready is not enough to check the operation status. So change this to check the chip good instead of this. About the retry functions to make sure the error handling remain it.
--- drivers/mtd/chips/cfi_cmdset_0002.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-)
drivers/mtd/chips/cfi_cmdset_0002.c +12 -10
@@ -2294,12 +2294,13 @@ static int __xipram do_erase_chip(struct chip->erase_suspended =0 ; } -if (chip_ready (map, adr)) +if (chip_good (map, adr,map_word_ff (map)))break ;if (time_after (jiffies, timeo)) {printk (KERN_WARNING "MTD %s(): software timeout\n" , __func__ ); + ret = -EIO ;break ; }
@@ -2307,15 +2308,15 @@ static int __xipram do_erase_chip(structUDELAY (map, chip, adr,1000000 /HZ ); }/* Did we succeed? */ -if (!chip_good (map, adr,map_word_ff (map))) { +if (ret) {/* reset on all failures. */ map_write ( map,CMD (0xF0 ), chip->start );/* FIXME - should have reset delay before continuing */ -if (++retry_cnt <=MAX_RETRIES ) +if (++retry_cnt <=MAX_RETRIES ) { + ret =0 ; goto retry; - - ret = -EIO ; + } } chip->state =FL_READY ;
@@ -2389,7 +2390,7 @@ static int __xipram do_erase_oneblock(st chip->erase_suspended =0 ; } -if (chip_ready (map, adr)) { +if (chip_good (map, adr,map_word_ff (map))) {xip_enable (map, chip, adr);break ; }
@@ -2398,6 +2399,7 @@ static int __xipram do_erase_oneblock(stxip_enable (map, chip, adr);printk (KERN_WARNING "MTD %s(): software timeout\n" , __func__ ); + ret = -EIO ;break ; }
@@ -2405,15 +2407,15 @@ static int __xipram do_erase_oneblock(stUDELAY (map, chip, adr,1000000 /HZ ); }/* Did we succeed? */ -if (!chip_good (map, adr,map_word_ff (map))) { +if (ret) {/* reset on all failures. */ map_write ( map,CMD (0xF0 ), chip->start );/* FIXME - should have reset delay before continuing */ -if (++retry_cnt <=MAX_RETRIES ) +if (++retry_cnt <=MAX_RETRIES ) { + ret =0 ; goto retry; - - ret = -EIO ; + } } chip->state =FL_READY ;
Greg Kroah-Hartman
maintainerPATCH 23/23 netfilter: nf_log: dont hold nf_log_mutex during user access
In reply to Greg Kroah-Hartman3.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jann Horn <[email protected]>
commit ce00bf07cc95a57cd20b208e02b3c2604e532ae8 upstream.
The old code would indefinitely block other users of nf_log_mutex if a userspace access in proc_dostring() blocked e.g. due to a userfaultfd region. Fix it by moving proc_dostring() out of the locked region.
This is a followup to commit 266d07cb1c9a ("netfilter: nf_log: fix sleeping function called from invalid context"), which changed this code from using rcu_read_lock() to taking nf_log_mutex.
--- net/netfilter/nf_log.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
net/netfilter/nf_log.c +6 -3
@@ -387,14 +387,17 @@ static int nf_log_proc_dostring(struct crcu_assign_pointer (net->nf.nf_loggers[tindex], logger);mutex_unlock (&nf_log_mutex); }else { +struct ctl_table tmp = *table; + + tmp.data = buf;mutex_lock (&nf_log_mutex); logger =nft_log_dereference (net->nf.nf_loggers[tindex]);if (!logger) - table->data ="NONE" ; +strlcpy (buf,"NONE" ,sizeof (buf));else - table->data = logger->name; - r =proc_dostring (table, write, buffer, lenp, ppos); +strlcpy (buf, logger->name,sizeof (buf));mutex_unlock (&nf_log_mutex); + r =proc_dostring (&tmp, write, buffer, lenp, ppos); }return r;
Quoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 3.18.115 release. There are 23 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Thu Jul 12 18:22:59 UTC 2018. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 9 lines
https://www.kernel.org/pub/linux/kernel/v3.x/stable-review/patch-3.18.115-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-3.18.y
and the diffstat can be found below.thanks,
greg k-h
Merged, compiled with -Werror, and installed on my Pixel XL.
No initial issues noticed in dmesg or general usage.
Thanks!
Nathan
Quoted 10 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 3.18.115 release. There are 23 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Thu Jul 12 18:22:59 UTC 2018. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
https://www.kernel.org/pub/linux/kernel/v3.x/stable-review/patch-3.18.115-rc1.gz
Quoted 8 lines
or in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git
linux-3.18.y
and the diffstat can be found below.thanks,
greg k-h
Builds with -Werror and boots fine on the OnePlus3T, no immediate regressions noticed. Thanks for the update!
Signature · 1 line
Harsh Shandilya, PRJKT Development LLC
Greg Kroah-Hartman
maintainerQuoted 16 lines · Harsh 'Shandilya
Quoted 15 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 3.18.115 release. There are 23 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Thu Jul 12 18:22:59 UTC 2018. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
https://www.kernel.org/pub/linux/kernel/v3.x/stable-review/patch-3.18.115-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git
linux-3.18.y
and the diffstat can be found below.
Quoted 5 lines
Quoted 3 lines
thanks,
greg k-h
Builds with -Werror and boots fine on the OnePlus3T, no immediate regressions noticed. Thanks for the update!
Great, thanks for testing and letting me know.
greg k-h
Quoted 8 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 3.18.115 release. There are 23 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Thu Jul 12 18:22:59 UTC 2018. Anything received after that time might be too late.
Build results:
total: 138 pass: 137 fail: 1 Failed builds: i386:tools/perf Qemu test results: total: 129 pass: 129 fail: 0
Ignore the perf build error; it only fails to build under certain conditions (such as building into a separate object directory) and would be difficult to fix in 3.18. I'll remove it from my 3.18 build tests.
Details are available at http://kerneltests.org/builders/.
Guenter
Quoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 3.18.115 release. There are 23 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Thu Jul 12 18:22:59 UTC 2018. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 9 lines
https://www.kernel.org/pub/linux/kernel/v3.x/stable-review/patch-3.18.115-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-3.18.y
and the diffstat can be found below.thanks,
greg k-h
Compiled and booted on my test system. No dmesg regressions.
thanks,
-- Shuah