Skip to content

Commit 4fae7f1

Browse files
Leon Romanovskyjgunthorpe
Leon Romanovsky
authored andcommitted
RDMA/uverbs: Fix slab-out-of-bounds in ib_uverbs_ex_create_flow
The check of cmd.flow_attr.size should check into account the size of the reserved field (2 bytes), otherwise user can provide a size which will cause a slab-out-of-bounds warning below. ================================================================== BUG: KASAN: slab-out-of-bounds in ib_uverbs_ex_create_flow+0x1740/0x1d00 Read of size 2 at addr ffff880068dff1a6 by task syz-executor775/269 CPU: 0 PID: 269 Comm: syz-executor775 Not tainted 4.18.0-rc1+ #245 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.11.0-0-g63451fca13-prebuilt.qemu-project.org 04/01/2014 Call Trace: dump_stack+0xef/0x17e print_address_description+0x83/0x3b0 kasan_report+0x18d/0x4d0 ib_uverbs_ex_create_flow+0x1740/0x1d00 ib_uverbs_write+0x923/0x1010 __vfs_write+0x10d/0x720 vfs_write+0x1b0/0x550 ksys_write+0xc6/0x1a0 do_syscall_64+0xa7/0x590 entry_SYSCALL_64_after_hwframe+0x49/0xbe RIP: 0033:0x433899 Code: fd ff 48 81 c4 80 00 00 00 e9 f1 fe ff ff 0f 1f 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 0f 83 3b 91 fd ff c3 66 2e 0f 1f 84 00 00 00 00 RSP: 002b:00007ffc2724db58 EFLAGS: 00000217 ORIG_RAX: 0000000000000001 RAX: ffffffffffffffda RBX: 0000000020006880 RCX: 0000000000433899 RDX: 00000000000000e0 RSI: 0000000020002480 RDI: 0000000000000003 RBP: 00000000006d7018 R08: 00000000004002f8 R09: 00000000004002f8 R10: 00000000004002f8 R11: 0000000000000217 R12: 0000000000000000 R13: 000000000040cd20 R14: 000000000040cdb0 R15: 0000000000000006 Allocated by task 269: kasan_kmalloc+0xa0/0xd0 __kmalloc+0x1a9/0x510 ib_uverbs_ex_create_flow+0x26c/0x1d00 ib_uverbs_write+0x923/0x1010 __vfs_write+0x10d/0x720 vfs_write+0x1b0/0x550 ksys_write+0xc6/0x1a0 do_syscall_64+0xa7/0x590 entry_SYSCALL_64_after_hwframe+0x49/0xbe Freed by task 0: __kasan_slab_free+0x12e/0x180 kfree+0x159/0x630 detach_buf+0x559/0x7a0 virtqueue_get_buf_ctx+0x3cc/0xab0 virtblk_done+0x1eb/0x3d0 vring_interrupt+0x16d/0x2b0 __handle_irq_event_percpu+0x10a/0x980 handle_irq_event_percpu+0x77/0x190 handle_irq_event+0xc6/0x1a0 handle_edge_irq+0x211/0xd80 handle_irq+0x3d/0x60 do_IRQ+0x9b/0x220 The buggy address belongs to the object at ffff880068dff180 which belongs to the cache kmalloc-64 of size 64 The buggy address is located 38 bytes inside of 64-byte region [ffff880068dff180, ffff880068dff1c0) The buggy address belongs to the page: page:ffffea0001a37fc0 count:1 mapcount:0 mapping:ffff88006c401780 index:0x0 flags: 0x4000000000000100(slab) raw: 4000000000000100 ffffea0001a31100 0000001100000011 ffff88006c401780 raw: 0000000000000000 00000000802a002a 00000001ffffffff 0000000000000000 page dumped because: kasan: bad access detected Memory state around the buggy address: ffff880068dff080: fb fb fb fb fc fc fc fc fb fb fb fb fb fb fb fb ffff880068dff100: fc fc fc fc fb fb fb fb fb fb fb fb fc fc fc fc >ffff880068dff180: 00 00 00 00 07 fc fc fc fc fc fc fc fb fb fb fb ^ ffff880068dff200: fb fb fb fb fc fc fc fc 00 00 00 00 00 00 fc fc ffff880068dff280: fc fc fc fc 00 00 00 00 00 00 00 00 fc fc fc fc ================================================================== Cc: <[email protected]> # 3.12 Fixes: f884827 ("IB/core: clarify overflow/underflow checks on ib_create/destroy_flow") Cc: syzkaller <[email protected]> Reported-by: Noa Osherovich <[email protected]> Signed-off-by: Leon Romanovsky <[email protected]> Signed-off-by: Jason Gunthorpe <[email protected]>
1 parent 940efcc commit 4fae7f1

File tree

1 file changed

+12
-11
lines changed

1 file changed

+12
-11
lines changed

drivers/infiniband/core/uverbs_cmd.c

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3488,8 +3488,8 @@ int ib_uverbs_ex_create_flow(struct ib_uverbs_file *file,
34883488
struct ib_flow_attr *flow_attr;
34893489
struct ib_qp *qp;
34903490
struct ib_uflow_resources *uflow_res;
3491+
struct ib_uverbs_flow_spec_hdr *kern_spec;
34913492
int err = 0;
3492-
void *kern_spec;
34933493
void *ib_spec;
34943494
int i;
34953495

@@ -3538,8 +3538,8 @@ int ib_uverbs_ex_create_flow(struct ib_uverbs_file *file,
35383538
if (!kern_flow_attr)
35393539
return -ENOMEM;
35403540

3541-
memcpy(kern_flow_attr, &cmd.flow_attr, sizeof(*kern_flow_attr));
3542-
err = ib_copy_from_udata(kern_flow_attr + 1, ucore,
3541+
*kern_flow_attr = cmd.flow_attr;
3542+
err = ib_copy_from_udata(&kern_flow_attr->flow_specs, ucore,
35433543
cmd.flow_attr.size);
35443544
if (err)
35453545
goto err_free_attr;
@@ -3583,21 +3583,22 @@ int ib_uverbs_ex_create_flow(struct ib_uverbs_file *file,
35833583
flow_attr->flags = kern_flow_attr->flags;
35843584
flow_attr->size = sizeof(*flow_attr);
35853585

3586-
kern_spec = kern_flow_attr + 1;
3586+
kern_spec = kern_flow_attr->flow_specs;
35873587
ib_spec = flow_attr + 1;
35883588
for (i = 0; i < flow_attr->num_of_specs &&
3589-
cmd.flow_attr.size > offsetof(struct ib_uverbs_flow_spec, reserved) &&
3590-
cmd.flow_attr.size >=
3591-
((struct ib_uverbs_flow_spec *)kern_spec)->size; i++) {
3592-
err = kern_spec_to_ib_spec(file->ucontext, kern_spec, ib_spec,
3593-
uflow_res);
3589+
cmd.flow_attr.size > sizeof(*kern_spec) &&
3590+
cmd.flow_attr.size >= kern_spec->size;
3591+
i++) {
3592+
err = kern_spec_to_ib_spec(
3593+
file->ucontext, (struct ib_uverbs_flow_spec *)kern_spec,
3594+
ib_spec, uflow_res);
35943595
if (err)
35953596
goto err_free;
35963597

35973598
flow_attr->size +=
35983599
((union ib_flow_spec *) ib_spec)->size;
3599-
cmd.flow_attr.size -= ((struct ib_uverbs_flow_spec *)kern_spec)->size;
3600-
kern_spec += ((struct ib_uverbs_flow_spec *) kern_spec)->size;
3600+
cmd.flow_attr.size -= kern_spec->size;
3601+
kern_spec = ((void *)kern_spec) + kern_spec->size;
36013602
ib_spec += ((union ib_flow_spec *) ib_spec)->size;
36023603
}
36033604
if (cmd.flow_attr.size || (i != flow_attr->num_of_specs)) {

0 commit comments

Comments
 (0)