Skip to content

Commit

Permalink
drivers/block/zram/zram_drv.c: fix idle/writeback string compare
Browse files Browse the repository at this point in the history
Makoto report a below KASAN error: zram does out-of-bounds read.  Because
strscpy copies from source up to count bytes unconditionally.  It could
cause out-of-bounds read on next object in slab.

To prevent it, use strlcpy which checks source's length automatically.

   BUG: KASAN: slab-out-of-bounds in strscpy+0x68/0x154
   Read of size 8 at addr ffffffc0c3495a00 by task system_server/1314
   ..
   Call trace:
     strscpy+0x68/0x154
     idle_store+0xc4/0x34c
     dev_attr_store+0x50/0x6c
     sysfs_kf_write+0x98/0xb4
     kernfs_fop_write+0x198/0x260
     __vfs_write+0x10c/0x338
     vfs_write+0x114/0x238
     SyS_write+0xc8/0x168
     __sys_trace_return+0x0/0x4

   Allocated by task 1314:
    __kmalloc+0x280/0x318
    kernfs_fop_write+0xac/0x260
    __vfs_write+0x10c/0x338
    vfs_write+0x114/0x238
    SyS_write+0xc8/0x168
    __sys_trace_return+0x0/0x4

   Freed by task 2855:
    kfree+0x138/0x630
    kernfs_put_open_node+0x10c/0x124
    kernfs_fop_release+0xd8/0x114
    __fput+0x130/0x2a4
    ____fput+0x1c/0x28
    task_work_run+0x16c/0x1c8
    do_notify_resume+0x2bc/0x107c
    work_pending+0x8/0x10

   The buggy address belongs to the object at ffffffc0c3495a00
    which belongs to the cache kmalloc-128 of size 128
   The buggy address is located 0 bytes inside of
    128-byte region [ffffffc0c3495a00, ffffffc0c3495a80)
   The buggy address belongs to the page:
   page:ffffffbf030d2500 count:1 mapcount:0 mapping:          (null) index:0x0 compound_mapcount: 0
   flags: 0x4000000000010200(slab|head)
   page dumped because: kasan: bad access detected

   Memory state around the buggy address:
    ffffffc0c3495900: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    ffffffc0c3495980: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
   >ffffffc0c3495a00: 04 fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
                      ^
    ffffffc0c3495a80: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
    ffffffc0c3495b00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

Link: http://lkml.kernel.org/r/[email protected]
Cc: <[email protected]>	[5.0]
Signed-off-by: Minchan Kim <[email protected]>
Reported-by: Makoto Wu <[email protected]>
Reviewed-by: Sergey Senozhatsky <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
  • Loading branch information
minchank authored and torvalds committed Mar 29, 2019
1 parent f5777bc commit 0bc9f5d
Showing 1 changed file with 6 additions and 26 deletions.
32 changes: 6 additions & 26 deletions drivers/block/zram/zram_drv.c
Original file line number Diff line number Diff line change
Expand Up @@ -290,18 +290,8 @@ static ssize_t idle_store(struct device *dev,
struct zram *zram = dev_to_zram(dev);
unsigned long nr_pages = zram->disksize >> PAGE_SHIFT;
int index;
char mode_buf[8];
ssize_t sz;

sz = strscpy(mode_buf, buf, sizeof(mode_buf));
if (sz <= 0)
return -EINVAL;

/* ignore trailing new line */
if (mode_buf[sz - 1] == '\n')
mode_buf[sz - 1] = 0x00;

if (strcmp(mode_buf, "all"))
if (!sysfs_streq(buf, "all"))
return -EINVAL;

down_read(&zram->init_lock);
Expand Down Expand Up @@ -635,25 +625,15 @@ static ssize_t writeback_store(struct device *dev,
struct bio bio;
struct bio_vec bio_vec;
struct page *page;
ssize_t ret, sz;
char mode_buf[8];
int mode = -1;
ssize_t ret;
int mode;
unsigned long blk_idx = 0;

sz = strscpy(mode_buf, buf, sizeof(mode_buf));
if (sz <= 0)
return -EINVAL;

/* ignore trailing newline */
if (mode_buf[sz - 1] == '\n')
mode_buf[sz - 1] = 0x00;

if (!strcmp(mode_buf, "idle"))
if (sysfs_streq(buf, "idle"))
mode = IDLE_WRITEBACK;
else if (!strcmp(mode_buf, "huge"))
else if (sysfs_streq(buf, "huge"))
mode = HUGE_WRITEBACK;

if (mode == -1)
else
return -EINVAL;

down_read(&zram->init_lock);
Expand Down

0 comments on commit 0bc9f5d

Please sign in to comment.