Skip to content

Commit 2c292db

Browse files
Boris Pismennydledford
Boris Pismenny
authored andcommitted
IB/mlx5: Fix out-of-bounds read in create_raw_packet_qp_rq
Add a check for the length of the qpin structure to prevent out-of-bounds reads BUG: KASAN: slab-out-of-bounds in create_raw_packet_qp+0x114c/0x15e2 Read of size 8192 at addr ffff880066b99290 by task syz-executor3/549 CPU: 3 PID: 549 Comm: syz-executor3 Not tainted 4.15.0-rc2+ #27 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.7.5-0-ge51488c-20140602_164612-nilsson.home.kraxel.org 04/01/2014 Call Trace: dump_stack+0x8d/0xd4 print_address_description+0x73/0x290 kasan_report+0x25c/0x370 ? create_raw_packet_qp+0x114c/0x15e2 memcpy+0x1f/0x50 create_raw_packet_qp+0x114c/0x15e2 ? create_raw_packet_qp_tis.isra.28+0x13d/0x13d ? lock_acquire+0x370/0x370 create_qp_common+0x2245/0x3b50 ? destroy_qp_user.isra.47+0x100/0x100 ? kasan_kmalloc+0x13d/0x170 ? sched_clock_cpu+0x18/0x180 ? fs_reclaim_acquire.part.15+0x5/0x30 ? __lock_acquire+0xa11/0x1da0 ? sched_clock_cpu+0x18/0x180 ? kmem_cache_alloc_trace+0x17e/0x310 ? mlx5_ib_create_qp+0x30e/0x17b0 mlx5_ib_create_qp+0x33d/0x17b0 ? sched_clock_cpu+0x18/0x180 ? create_qp_common+0x3b50/0x3b50 ? lock_acquire+0x370/0x370 ? __radix_tree_lookup+0x180/0x220 ? uverbs_try_lock_object+0x68/0xc0 ? rdma_lookup_get_uobject+0x114/0x240 create_qp.isra.5+0xce4/0x1e20 ? ib_uverbs_ex_create_cq_cb+0xa0/0xa0 ? copy_ah_attr_from_uverbs.isra.2+0xa00/0xa00 ? ib_uverbs_cq_event_handler+0x160/0x160 ? __might_fault+0x17c/0x1c0 ib_uverbs_create_qp+0x21b/0x2a0 ? ib_uverbs_destroy_cq+0x2e0/0x2e0 ib_uverbs_write+0x55a/0xad0 ? ib_uverbs_destroy_cq+0x2e0/0x2e0 ? ib_uverbs_destroy_cq+0x2e0/0x2e0 ? ib_uverbs_open+0x760/0x760 ? futex_wake+0x147/0x410 ? check_prev_add+0x1680/0x1680 ? do_futex+0x3d3/0xa60 ? sched_clock_cpu+0x18/0x180 __vfs_write+0xf7/0x5c0 ? ib_uverbs_open+0x760/0x760 ? kernel_read+0x110/0x110 ? lock_acquire+0x370/0x370 ? __fget+0x264/0x3b0 vfs_write+0x18a/0x460 SyS_write+0xc7/0x1a0 ? SyS_read+0x1a0/0x1a0 ? trace_hardirqs_on_thunk+0x1a/0x1c entry_SYSCALL_64_fastpath+0x18/0x85 RIP: 0033:0x4477b9 RSP: 002b:00007f1822cadc18 EFLAGS: 00000292 ORIG_RAX: 0000000000000001 RAX: ffffffffffffffda RBX: 0000000000000005 RCX: 00000000004477b9 RDX: 0000000000000070 RSI: 000000002000a000 RDI: 0000000000000005 RBP: 0000000000708000 R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000292 R12: 00000000ffffffff R13: 0000000000005d70 R14: 00000000006e6e30 R15: 0000000020010ff0 Allocated by task 549: __kmalloc+0x15e/0x340 kvmalloc_node+0xa1/0xd0 create_user_qp.isra.46+0xd42/0x1610 create_qp_common+0x2e63/0x3b50 mlx5_ib_create_qp+0x33d/0x17b0 create_qp.isra.5+0xce4/0x1e20 ib_uverbs_create_qp+0x21b/0x2a0 ib_uverbs_write+0x55a/0xad0 __vfs_write+0xf7/0x5c0 vfs_write+0x18a/0x460 SyS_write+0xc7/0x1a0 entry_SYSCALL_64_fastpath+0x18/0x85 Freed by task 368: kfree+0xeb/0x2f0 kernfs_fop_release+0x140/0x180 __fput+0x266/0x700 task_work_run+0x104/0x180 exit_to_usermode_loop+0xf7/0x110 syscall_return_slowpath+0x298/0x370 entry_SYSCALL_64_fastpath+0x83/0x85 The buggy address belongs to the object at ffff880066b99180 which belongs to the cache kmalloc-512 of size 512 The buggy address is located 272 bytes inside of 512-byte region [ffff880066b99180, ffff880066b99380) The buggy address belongs to the page: page:000000006040eedd count:1 mapcount:0 mapping: (null) index:0x0 compound_mapcount: 0 flags: 0x4000000000008100(slab|head) raw: 4000000000008100 0000000000000000 0000000000000000 0000000180190019 raw: ffffea00019a7500 0000000b0000000b ffff88006c403080 0000000000000000 page dumped because: kasan: bad access detected Memory state around the buggy address: ffff880066b99180: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ffff880066b99200: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 >ffff880066b99280: 00 00 fc fc fc fc fc fc fc fc fc fc fc fc fc fc ^ ffff880066b99300: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc ffff880066b99380: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc Cc: syzkaller <[email protected]> Fixes: 0fb2ed6 ("IB/mlx5: Add create and destroy functionality for Raw Packet QP") Signed-off-by: Boris Pismenny <[email protected]> Signed-off-by: Leon Romanovsky <[email protected]> Signed-off-by: Doug Ledford <[email protected]>
1 parent 28e9091 commit 2c292db

File tree

1 file changed

+16
-7
lines changed
  • drivers/infiniband/hw/mlx5

1 file changed

+16
-7
lines changed

drivers/infiniband/hw/mlx5/qp.c

+16-7
Original file line numberDiff line numberDiff line change
@@ -1161,7 +1161,7 @@ static void destroy_raw_packet_qp_sq(struct mlx5_ib_dev *dev,
11611161
ib_umem_release(sq->ubuffer.umem);
11621162
}
11631163

1164-
static int get_rq_pas_size(void *qpc)
1164+
static size_t get_rq_pas_size(void *qpc)
11651165
{
11661166
u32 log_page_size = MLX5_GET(qpc, qpc, log_page_size) + 12;
11671167
u32 log_rq_stride = MLX5_GET(qpc, qpc, log_rq_stride);
@@ -1177,7 +1177,8 @@ static int get_rq_pas_size(void *qpc)
11771177
}
11781178

11791179
static int create_raw_packet_qp_rq(struct mlx5_ib_dev *dev,
1180-
struct mlx5_ib_rq *rq, void *qpin)
1180+
struct mlx5_ib_rq *rq, void *qpin,
1181+
size_t qpinlen)
11811182
{
11821183
struct mlx5_ib_qp *mqp = rq->base.container_mibqp;
11831184
__be64 *pas;
@@ -1186,9 +1187,12 @@ static int create_raw_packet_qp_rq(struct mlx5_ib_dev *dev,
11861187
void *rqc;
11871188
void *wq;
11881189
void *qpc = MLX5_ADDR_OF(create_qp_in, qpin, qpc);
1189-
int inlen;
1190+
size_t rq_pas_size = get_rq_pas_size(qpc);
1191+
size_t inlen;
11901192
int err;
1191-
u32 rq_pas_size = get_rq_pas_size(qpc);
1193+
1194+
if (qpinlen < rq_pas_size + MLX5_BYTE_OFF(create_qp_in, pas))
1195+
return -EINVAL;
11921196

11931197
inlen = MLX5_ST_SZ_BYTES(create_rq_in) + rq_pas_size;
11941198
in = kvzalloc(inlen, GFP_KERNEL);
@@ -1277,7 +1281,7 @@ static void destroy_raw_packet_qp_tir(struct mlx5_ib_dev *dev,
12771281
}
12781282

12791283
static int create_raw_packet_qp(struct mlx5_ib_dev *dev, struct mlx5_ib_qp *qp,
1280-
u32 *in,
1284+
u32 *in, size_t inlen,
12811285
struct ib_pd *pd)
12821286
{
12831287
struct mlx5_ib_raw_packet_qp *raw_packet_qp = &qp->raw_packet_qp;
@@ -1309,7 +1313,7 @@ static int create_raw_packet_qp(struct mlx5_ib_dev *dev, struct mlx5_ib_qp *qp,
13091313
rq->flags |= MLX5_IB_RQ_CVLAN_STRIPPING;
13101314
if (qp->flags & MLX5_IB_QP_PCI_WRITE_END_PADDING)
13111315
rq->flags |= MLX5_IB_RQ_PCI_WRITE_END_PADDING;
1312-
err = create_raw_packet_qp_rq(dev, rq, in);
1316+
err = create_raw_packet_qp_rq(dev, rq, in, inlen);
13131317
if (err)
13141318
goto err_destroy_sq;
13151319

@@ -1872,11 +1876,16 @@ static int create_qp_common(struct mlx5_ib_dev *dev, struct ib_pd *pd,
18721876
}
18731877
}
18741878

1879+
if (inlen < 0) {
1880+
err = -EINVAL;
1881+
goto err;
1882+
}
1883+
18751884
if (init_attr->qp_type == IB_QPT_RAW_PACKET ||
18761885
qp->flags & MLX5_IB_QP_UNDERLAY) {
18771886
qp->raw_packet_qp.sq.ubuffer.buf_addr = ucmd.sq_buf_addr;
18781887
raw_packet_qp_copy_info(qp, &qp->raw_packet_qp);
1879-
err = create_raw_packet_qp(dev, qp, in, pd);
1888+
err = create_raw_packet_qp(dev, qp, in, inlen, pd);
18801889
} else {
18811890
err = mlx5_core_create_qp(dev->mdev, &base->mqp, in, inlen);
18821891
}

0 commit comments

Comments
 (0)