Skip to content

Commit ab868c1

Browse files
committed
Merge tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma
Pull rdma fixes from Jason Gunthorpe: - syzbot triggred crash in rxe due to concurrent plug/unplug - Possible non-zero'd memory exposed to userspace in bnxt_re - Malicous 'magic packet' with SIW causes a buffer overflow - Tighten the new uAPI validation code to not crash in debugging prints and have the right module dependencies in drivers - mana was missing the max_msg_sz report to userspace - UAF in rtrs on an error path * tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma: RDMA/rtrs: Fix use-after-free in path file creation cleanup RDMA/mana_ib: Report max_msg_sz in mana_ib_query_port RDMA/core: Do not read wild stack memory in uverbs_get_handler_fn() RDMA/core: Move the _ib_copy_validate_udata* functions to ib_core_uverbs RDMA/siw: Reject MPA FPDU length underflow before signed receive math RDMA/bnxt_re: zero shared page before exposing to userspace selftests/rdma: explicitly skip tests when required modules are missing RDMA/nldev: Add mutual exclusion in nldev_dellink()
2 parents f53a244 + 5b74373 commit ab868c1

13 files changed

Lines changed: 178 additions & 140 deletions

File tree

drivers/infiniband/core/ib_core_uverbs.c

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include <linux/dma-resv.h>
1010
#include "uverbs.h"
1111
#include "core_priv.h"
12+
#include "rdma_core.h"
1213

1314
MODULE_IMPORT_NS("DMA_BUF");
1415

@@ -416,3 +417,89 @@ struct ib_device *rdma_udata_to_dev(struct ib_udata *udata)
416417
}
417418
EXPORT_SYMBOL(rdma_udata_to_dev);
418419

420+
#if IS_ENABLED(CONFIG_INFINIBAND_USER_ACCESS)
421+
uverbs_api_ioctl_handler_fn uverbs_get_handler_fn(struct ib_udata *udata)
422+
{
423+
struct uverbs_attr_bundle *bundle =
424+
rdma_udata_to_uverbs_attr_bundle(udata);
425+
426+
lockdep_assert_held(&bundle->ufile->device->disassociate_srcu);
427+
428+
return srcu_dereference(bundle->method_elm->handler,
429+
&bundle->ufile->device->disassociate_srcu);
430+
}
431+
432+
int _ib_copy_validate_udata_in(struct ib_udata *udata, void *req,
433+
size_t kernel_size, size_t minimum_size)
434+
{
435+
int err;
436+
437+
if (udata->inlen < minimum_size) {
438+
ibdev_dbg(
439+
rdma_udata_to_dev(udata),
440+
"System call driver input udata too small (%zu < %zu) for ioctl %ps called by %pSR\n",
441+
udata->inlen, minimum_size,
442+
uverbs_get_handler_fn(udata),
443+
__builtin_return_address(0));
444+
return -EINVAL;
445+
}
446+
447+
err = copy_struct_from_user(req, kernel_size, udata->inbuf,
448+
udata->inlen);
449+
if (err) {
450+
if (err == -E2BIG) {
451+
ibdev_dbg(
452+
rdma_udata_to_dev(udata),
453+
"System call driver input udata not zero from %zu -> %zu for ioctl %ps called by %pSR\n",
454+
minimum_size, udata->inlen,
455+
uverbs_get_handler_fn(udata),
456+
__builtin_return_address(0));
457+
return -EOPNOTSUPP;
458+
}
459+
ibdev_dbg(
460+
rdma_udata_to_dev(udata),
461+
"System call driver input udata EFAULT for ioctl %ps called by %pSR\n",
462+
uverbs_get_handler_fn(udata),
463+
__builtin_return_address(0));
464+
return err;
465+
}
466+
return 0;
467+
}
468+
EXPORT_SYMBOL(_ib_copy_validate_udata_in);
469+
470+
int _ib_copy_validate_udata_cm_fail(struct ib_udata *udata, u64 req_cm,
471+
u64 valid_cm)
472+
{
473+
ibdev_dbg(
474+
rdma_udata_to_dev(udata),
475+
"System call driver input udata has unsupported comp_mask %llx & ~%llx = %llx for ioctl %ps called by %pSR\n",
476+
req_cm, valid_cm, req_cm & ~valid_cm,
477+
uverbs_get_handler_fn(udata), __builtin_return_address(0));
478+
return -EOPNOTSUPP;
479+
}
480+
EXPORT_SYMBOL(_ib_copy_validate_udata_cm_fail);
481+
482+
int _ib_respond_udata(struct ib_udata *udata, const void *src, size_t len)
483+
{
484+
size_t copy_len;
485+
486+
/* 0 length copy_len is a NOP for copy_to_user() and doesn't fail. */
487+
copy_len = min(len, udata->outlen);
488+
if (copy_to_user(udata->outbuf, src, copy_len))
489+
goto err_fault;
490+
if (copy_len < udata->outlen) {
491+
if (clear_user(udata->outbuf + copy_len,
492+
udata->outlen - copy_len))
493+
goto err_fault;
494+
}
495+
return 0;
496+
err_fault:
497+
ibdev_dbg(
498+
rdma_udata_to_dev(udata),
499+
"System call driver out udata has EFAULT (%zu into %zu) for ioctl %ps called by %pSR\n",
500+
len, udata->outlen, uverbs_get_handler_fn(udata),
501+
__builtin_return_address(0));
502+
return -EFAULT;
503+
}
504+
EXPORT_SYMBOL(_ib_respond_udata);
505+
#endif

drivers/infiniband/core/nldev.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
* a controlled QKEY.
5252
*/
5353
static bool privileged_qkey;
54+
static DEFINE_MUTEX(nldev_dellink_mutex);
5455

5556
typedef int (*res_fill_func_t)(struct sk_buff*, bool,
5657
struct rdma_restrack_entry*, uint32_t);
@@ -1846,7 +1847,9 @@ static int nldev_dellink(struct sk_buff *skb, struct nlmsghdr *nlh,
18461847
* implicitly scoped to the driver supporting dynamic link deletion like RXE.
18471848
*/
18481849
if (device->link_ops && device->link_ops->dellink) {
1850+
mutex_lock(&nldev_dellink_mutex);
18491851
err = device->link_ops->dellink(device);
1852+
mutex_unlock(&nldev_dellink_mutex);
18501853
if (err)
18511854
return err;
18521855
}

drivers/infiniband/core/uverbs.h

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,40 @@ int uverbs_dealloc_mw(struct ib_mw *mw);
229229
void ib_uverbs_detach_umcast(struct ib_qp *qp,
230230
struct ib_uqp_object *uobj);
231231

232+
struct bundle_alloc_head {
233+
struct_group_tagged(bundle_alloc_head_hdr, hdr,
234+
struct bundle_alloc_head *next;
235+
);
236+
u8 data[];
237+
};
238+
239+
struct bundle_priv {
240+
/* Must be first */
241+
struct bundle_alloc_head_hdr alloc_head;
242+
struct bundle_alloc_head *allocated_mem;
243+
size_t internal_avail;
244+
size_t internal_used;
245+
246+
struct radix_tree_root *radix;
247+
void __rcu **radix_slots;
248+
unsigned long radix_slots_len;
249+
u32 method_key;
250+
251+
struct ib_uverbs_attr __user *user_attrs;
252+
struct ib_uverbs_attr *uattrs;
253+
254+
DECLARE_BITMAP(uobj_finalize, UVERBS_API_ATTR_BKEY_LEN);
255+
DECLARE_BITMAP(spec_finalize, UVERBS_API_ATTR_BKEY_LEN);
256+
DECLARE_BITMAP(uobj_hw_obj_valid, UVERBS_API_ATTR_BKEY_LEN);
257+
258+
/*
259+
* Must be last. bundle ends in a flex array which overlaps
260+
* internal_buffer.
261+
*/
262+
struct uverbs_attr_bundle_hdr bundle;
263+
u64 internal_buffer[32];
264+
};
265+
232266
long ib_uverbs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg);
233267

234268
struct ib_uverbs_flow_spec {

drivers/infiniband/core/uverbs_ioctl.c

Lines changed: 14 additions & 134 deletions
Original file line numberDiff line numberDiff line change
@@ -35,54 +35,6 @@
3535
#include "rdma_core.h"
3636
#include "uverbs.h"
3737

38-
struct bundle_alloc_head {
39-
struct_group_tagged(bundle_alloc_head_hdr, hdr,
40-
struct bundle_alloc_head *next;
41-
);
42-
u8 data[];
43-
};
44-
45-
struct bundle_priv {
46-
/* Must be first */
47-
struct bundle_alloc_head_hdr alloc_head;
48-
struct bundle_alloc_head *allocated_mem;
49-
size_t internal_avail;
50-
size_t internal_used;
51-
52-
struct radix_tree_root *radix;
53-
const struct uverbs_api_ioctl_method *method_elm;
54-
void __rcu **radix_slots;
55-
unsigned long radix_slots_len;
56-
u32 method_key;
57-
58-
struct ib_uverbs_attr __user *user_attrs;
59-
struct ib_uverbs_attr *uattrs;
60-
61-
DECLARE_BITMAP(uobj_finalize, UVERBS_API_ATTR_BKEY_LEN);
62-
DECLARE_BITMAP(spec_finalize, UVERBS_API_ATTR_BKEY_LEN);
63-
DECLARE_BITMAP(uobj_hw_obj_valid, UVERBS_API_ATTR_BKEY_LEN);
64-
65-
/*
66-
* Must be last. bundle ends in a flex array which overlaps
67-
* internal_buffer.
68-
*/
69-
struct uverbs_attr_bundle_hdr bundle;
70-
u64 internal_buffer[32];
71-
};
72-
73-
uverbs_api_ioctl_handler_fn uverbs_get_handler_fn(struct ib_udata *udata)
74-
{
75-
struct uverbs_attr_bundle *bundle =
76-
rdma_udata_to_uverbs_attr_bundle(udata);
77-
struct bundle_priv *pbundle =
78-
container_of(&bundle->hdr, struct bundle_priv, bundle);
79-
80-
lockdep_assert_held(&bundle->ufile->device->disassociate_srcu);
81-
82-
return srcu_dereference(pbundle->method_elm->handler,
83-
&bundle->ufile->device->disassociate_srcu);
84-
}
85-
8638
/*
8739
* Each method has an absolute minimum amount of memory it needs to allocate,
8840
* precompute that amount and determine if the onstack memory can be used or
@@ -445,13 +397,13 @@ static int ib_uverbs_run_method(struct bundle_priv *pbundle,
445397
struct uverbs_attr_bundle *bundle =
446398
container_of(&pbundle->bundle, struct uverbs_attr_bundle, hdr);
447399
size_t uattrs_size = array_size(sizeof(*pbundle->uattrs), num_attrs);
448-
unsigned int destroy_bkey = pbundle->method_elm->destroy_bkey;
400+
unsigned int destroy_bkey = bundle->method_elm->destroy_bkey;
449401
unsigned int i;
450402
int ret;
451403

452404
/* See uverbs_disassociate_api() */
453405
handler = srcu_dereference(
454-
pbundle->method_elm->handler,
406+
bundle->method_elm->handler,
455407
&pbundle->bundle.ufile->device->disassociate_srcu);
456408
if (!handler)
457409
return -EIO;
@@ -469,12 +421,12 @@ static int ib_uverbs_run_method(struct bundle_priv *pbundle,
469421
}
470422

471423
/* User space did not provide all the mandatory attributes */
472-
if (unlikely(!bitmap_subset(pbundle->method_elm->attr_mandatory,
424+
if (unlikely(!bitmap_subset(bundle->method_elm->attr_mandatory,
473425
pbundle->bundle.attr_present,
474-
pbundle->method_elm->key_bitmap_len)))
426+
bundle->method_elm->key_bitmap_len)))
475427
return -EINVAL;
476428

477-
if (pbundle->method_elm->has_udata)
429+
if (bundle->method_elm->has_udata)
478430
uverbs_fill_udata(bundle, &pbundle->bundle.driver_udata,
479431
UVERBS_ATTR_UHW_IN, UVERBS_ATTR_UHW_OUT);
480432
else
@@ -499,7 +451,7 @@ static int ib_uverbs_run_method(struct bundle_priv *pbundle,
499451
* assume that the driver wrote to its UHW_OUT and flag userspace
500452
* appropriately.
501453
*/
502-
if (!ret && pbundle->method_elm->has_udata) {
454+
if (!ret && bundle->method_elm->has_udata) {
503455
const struct uverbs_attr *attr =
504456
uverbs_attr_get(bundle, UVERBS_ATTR_UHW_OUT);
505457

@@ -520,7 +472,7 @@ static int ib_uverbs_run_method(struct bundle_priv *pbundle,
520472

521473
static void bundle_destroy(struct bundle_priv *pbundle, bool commit)
522474
{
523-
unsigned int key_bitmap_len = pbundle->method_elm->key_bitmap_len;
475+
unsigned int key_bitmap_len = pbundle->bundle.method_elm->key_bitmap_len;
524476
struct uverbs_attr_bundle *bundle =
525477
container_of(&pbundle->bundle, struct uverbs_attr_bundle, hdr);
526478
struct bundle_alloc_head *memblock;
@@ -608,7 +560,7 @@ static int ib_uverbs_cmd_verbs(struct ib_uverbs_file *ufile,
608560
}
609561

610562
/* Space for the pbundle->bundle.attrs flex array */
611-
pbundle->method_elm = method_elm;
563+
pbundle->bundle.method_elm = method_elm;
612564
pbundle->method_key = attrs_iter.index;
613565
pbundle->bundle.ufile = ufile;
614566
pbundle->bundle.context = NULL; /* only valid if bundle has uobject */
@@ -617,10 +569,12 @@ static int ib_uverbs_cmd_verbs(struct ib_uverbs_file *ufile,
617569
pbundle->radix_slots_len = radix_tree_chunk_size(&attrs_iter);
618570
pbundle->user_attrs = user_attrs;
619571

620-
pbundle->internal_used = ALIGN(pbundle->method_elm->key_bitmap_len *
621-
sizeof(*container_of(&pbundle->bundle,
622-
struct uverbs_attr_bundle, hdr)->attrs),
623-
sizeof(*pbundle->internal_buffer));
572+
pbundle->internal_used = ALIGN(
573+
pbundle->bundle.method_elm->key_bitmap_len *
574+
sizeof(*container_of(&pbundle->bundle,
575+
struct uverbs_attr_bundle, hdr)
576+
->attrs),
577+
sizeof(*pbundle->internal_buffer));
624578
memset(pbundle->bundle.attr_present, 0,
625579
sizeof(pbundle->bundle.attr_present));
626580
memset(pbundle->uobj_finalize, 0, sizeof(pbundle->uobj_finalize));
@@ -860,77 +814,3 @@ void uverbs_finalize_uobj_create(const struct uverbs_attr_bundle *bundle,
860814
pbundle->uobj_hw_obj_valid);
861815
}
862816
EXPORT_SYMBOL(uverbs_finalize_uobj_create);
863-
864-
int _ib_copy_validate_udata_in(struct ib_udata *udata, void *req,
865-
size_t kernel_size, size_t minimum_size)
866-
{
867-
int err;
868-
869-
if (udata->inlen < minimum_size) {
870-
ibdev_dbg(
871-
rdma_udata_to_dev(udata),
872-
"System call driver input udata too small (%zu < %zu) for ioctl %ps called by %pSR\n",
873-
udata->inlen, minimum_size,
874-
uverbs_get_handler_fn(udata),
875-
__builtin_return_address(0));
876-
return -EINVAL;
877-
}
878-
879-
err = copy_struct_from_user(req, kernel_size, udata->inbuf,
880-
udata->inlen);
881-
if (err) {
882-
if (err == -E2BIG) {
883-
ibdev_dbg(
884-
rdma_udata_to_dev(udata),
885-
"System call driver input udata not zero from %zu -> %zu for ioctl %ps called by %pSR\n",
886-
minimum_size, udata->inlen,
887-
uverbs_get_handler_fn(udata),
888-
__builtin_return_address(0));
889-
return -EOPNOTSUPP;
890-
}
891-
ibdev_dbg(
892-
rdma_udata_to_dev(udata),
893-
"System call driver input udata EFAULT for ioctl %ps called by %pSR\n",
894-
uverbs_get_handler_fn(udata),
895-
__builtin_return_address(0));
896-
return err;
897-
}
898-
return 0;
899-
}
900-
EXPORT_SYMBOL(_ib_copy_validate_udata_in);
901-
902-
int _ib_copy_validate_udata_cm_fail(struct ib_udata *udata, u64 req_cm,
903-
u64 valid_cm)
904-
{
905-
ibdev_dbg(
906-
rdma_udata_to_dev(udata),
907-
"System call driver input udata has unsupported comp_mask %llx & ~%llx = %llx for ioctl %ps called by %pSR\n",
908-
req_cm, valid_cm, req_cm & ~valid_cm,
909-
uverbs_get_handler_fn(udata), __builtin_return_address(0));
910-
return -EOPNOTSUPP;
911-
}
912-
EXPORT_SYMBOL(_ib_copy_validate_udata_cm_fail);
913-
914-
int _ib_respond_udata(struct ib_udata *udata, const void *src, size_t len)
915-
{
916-
size_t copy_len;
917-
918-
/* 0 length copy_len is a NOP for copy_to_user() and doesn't fail. */
919-
copy_len = min(len, udata->outlen);
920-
if (copy_to_user(udata->outbuf, src, copy_len))
921-
goto err_fault;
922-
if (copy_len < udata->outlen) {
923-
if (clear_user(udata->outbuf + copy_len,
924-
udata->outlen - copy_len))
925-
goto err_fault;
926-
}
927-
return 0;
928-
err_fault:
929-
ibdev_dbg(
930-
rdma_udata_to_dev(udata),
931-
"System call driver out udata has EFAULT (%zu into %zu) for ioctl %ps called by %pSR\n",
932-
len, udata->outlen, uverbs_get_handler_fn(udata),
933-
__builtin_return_address(0));
934-
return -EFAULT;
935-
}
936-
EXPORT_SYMBOL(_ib_respond_udata);

drivers/infiniband/hw/bnxt_re/ib_verbs.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4638,7 +4638,7 @@ int bnxt_re_alloc_ucontext(struct ib_ucontext *ctx, struct ib_udata *udata)
46384638

46394639
uctx->rdev = rdev;
46404640

4641-
uctx->shpg = (void *)__get_free_page(GFP_KERNEL);
4641+
uctx->shpg = (void *)get_zeroed_page(GFP_KERNEL);
46424642
if (!uctx->shpg) {
46434643
rc = -ENOMEM;
46444644
goto fail;

drivers/infiniband/hw/mana/main.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -606,6 +606,7 @@ int mana_ib_query_port(struct ib_device *ibdev, u32 port,
606606
if (mana_ib_is_rnic(dev)) {
607607
props->gid_tbl_len = 16;
608608
props->ip_gids = true;
609+
props->max_msg_sz = SZ_16M;
609610
if (port == 1)
610611
props->port_cap_flags = IB_PORT_CM_SUP;
611612
}

0 commit comments

Comments
 (0)