]>
Commit | Line | Data |
---|---|---|
80347ec8 GKH |
1 | From foo@baz Mon Oct 8 18:01:43 CEST 2018 |
2 | From: Jann Horn <jannh@google.com> | |
3 | Date: Mon, 3 Sep 2018 18:54:14 +0200 | |
4 | Subject: RDMA/ucma: check fd type in ucma_migrate_id() | |
5 | ||
6 | From: Jann Horn <jannh@google.com> | |
7 | ||
8 | [ Upstream commit 0d23ba6034b9cf48b8918404367506da3e4b3ee5 ] | |
9 | ||
10 | The current code grabs the private_data of whatever file descriptor | |
11 | userspace has supplied and implicitly casts it to a `struct ucma_file *`, | |
12 | potentially causing a type confusion. | |
13 | ||
14 | This is probably fine in practice because the pointer is only used for | |
15 | comparisons, it is never actually dereferenced; and even in the | |
16 | comparisons, it is unlikely that a file from another filesystem would have | |
17 | a ->private_data pointer that happens to also be valid in this context. | |
18 | But ->private_data is not always guaranteed to be a valid pointer to an | |
19 | object owned by the file's filesystem; for example, some filesystems just | |
20 | cram numbers in there. | |
21 | ||
22 | Check the type of the supplied file descriptor to be safe, analogous to how | |
23 | other places in the kernel do it. | |
24 | ||
25 | Fixes: 88314e4dda1e ("RDMA/cma: add support for rdma_migrate_id()") | |
26 | Signed-off-by: Jann Horn <jannh@google.com> | |
27 | Signed-off-by: Jason Gunthorpe <jgg@mellanox.com> | |
28 | Signed-off-by: Sasha Levin <alexander.levin@microsoft.com> | |
29 | Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | |
30 | --- | |
31 | drivers/infiniband/core/ucma.c | 6 ++++++ | |
32 | 1 file changed, 6 insertions(+) | |
33 | ||
34 | --- a/drivers/infiniband/core/ucma.c | |
35 | +++ b/drivers/infiniband/core/ucma.c | |
36 | @@ -124,6 +124,8 @@ static DEFINE_MUTEX(mut); | |
37 | static DEFINE_IDR(ctx_idr); | |
38 | static DEFINE_IDR(multicast_idr); | |
39 | ||
40 | +static const struct file_operations ucma_fops; | |
41 | + | |
42 | static inline struct ucma_context *_ucma_find_context(int id, | |
43 | struct ucma_file *file) | |
44 | { | |
45 | @@ -1545,6 +1547,10 @@ static ssize_t ucma_migrate_id(struct uc | |
46 | f = fdget(cmd.fd); | |
47 | if (!f.file) | |
48 | return -ENOENT; | |
49 | + if (f.file->f_op != &ucma_fops) { | |
50 | + ret = -EINVAL; | |
51 | + goto file_put; | |
52 | + } | |
53 | ||
54 | /* Validate current fd and prevent destruction of id. */ | |
55 | ctx = ucma_get_ctx(f.file->private_data, cmd.id); |