Skip to content

Commit 1eb9364

Browse files
committed
IB/uverbs: Fix ordering of ucontext check in ib_uverbs_write
During disassociation the ucontext will become NULL, however due to how the SRCU locking works the ucontext must only be examined after looking at the ib_dev, which governs the RCU control flow. With the wrong ordering userspace will see EINVAL instead of EIO for a disassociated uverbs FD, which breaks rdma-core. Cc: [email protected] Fixes: 491d5c6 ("RDMA/uverbs: Move uncontext check before SRCU read lock") Reported-by: Mark Bloch <[email protected]> Signed-off-by: Jason Gunthorpe <[email protected]> Reviewed-by: Leon Romanovsky <[email protected]>
1 parent 3dc7c7b commit 1eb9364

File tree

1 file changed

+10
-4
lines changed

1 file changed

+10
-4
lines changed

drivers/infiniband/core/uverbs_main.c

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -736,10 +736,6 @@ static ssize_t ib_uverbs_write(struct file *filp, const char __user *buf,
736736
if (ret)
737737
return ret;
738738

739-
if (!file->ucontext &&
740-
(command != IB_USER_VERBS_CMD_GET_CONTEXT || extended))
741-
return -EINVAL;
742-
743739
if (extended) {
744740
if (count < (sizeof(hdr) + sizeof(ex_hdr)))
745741
return -EINVAL;
@@ -759,6 +755,16 @@ static ssize_t ib_uverbs_write(struct file *filp, const char __user *buf,
759755
goto out;
760756
}
761757

758+
/*
759+
* Must be after the ib_dev check, as once the RCU clears ib_dev ==
760+
* NULL means ucontext == NULL
761+
*/
762+
if (!file->ucontext &&
763+
(command != IB_USER_VERBS_CMD_GET_CONTEXT || extended)) {
764+
ret = -EINVAL;
765+
goto out;
766+
}
767+
762768
if (!verify_command_mask(ib_dev, command, extended)) {
763769
ret = -EOPNOTSUPP;
764770
goto out;

0 commit comments

Comments
 (0)