| From 2fc825a447a2e578b25eefe36f50d39879fdb9ed Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Thu, 7 May 2020 10:10:12 +0300 |
| Subject: IB/core: Fix potential NULL pointer dereference in pkey cache |
| |
| From: Jack Morgenstein <jackm@dev.mellanox.co.il> |
| |
| [ Upstream commit 1901b91f99821955eac2bd48fe25ee983385dc00 ] |
| |
| The IB core pkey cache is populated by procedure ib_cache_update(). |
| Initially, the pkey cache pointer is NULL. ib_cache_update allocates a |
| buffer and populates it with the device's pkeys, via repeated calls to |
| procedure ib_query_pkey(). |
| |
| If there is a failure in populating the pkey buffer via ib_query_pkey(), |
| ib_cache_update does not replace the old pkey buffer cache with the |
| updated one -- it leaves the old cache as is. |
| |
| Since initially the pkey buffer cache is NULL, when calling |
| ib_cache_update the first time, a failure in ib_query_pkey() will cause |
| the pkey buffer cache pointer to remain NULL. |
| |
| In this situation, any calls subsequent to ib_get_cached_pkey(), |
| ib_find_cached_pkey(), or ib_find_cached_pkey_exact() will try to |
| dereference the NULL pkey cache pointer, causing a kernel panic. |
| |
| Fix this by checking the ib_cache_update() return value. |
| |
| Fixes: 8faea9fd4a39 ("RDMA/cache: Move the cache per-port data into the main ib_port_data") |
| Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") |
| Link: https://lore.kernel.org/r/20200507071012.100594-1-leon@kernel.org |
| Signed-off-by: Jack Morgenstein <jackm@dev.mellanox.co.il> |
| Signed-off-by: Leon Romanovsky <leonro@mellanox.com> |
| Signed-off-by: Jason Gunthorpe <jgg@mellanox.com> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| drivers/infiniband/core/cache.c | 7 +++++-- |
| 1 file changed, 5 insertions(+), 2 deletions(-) |
| |
| diff --git a/drivers/infiniband/core/cache.c b/drivers/infiniband/core/cache.c |
| index 17bfedd24cc34..4619629b958cd 100644 |
| --- a/drivers/infiniband/core/cache.c |
| +++ b/drivers/infiniband/core/cache.c |
| @@ -1536,8 +1536,11 @@ int ib_cache_setup_one(struct ib_device *device) |
| if (err) |
| return err; |
| |
| - rdma_for_each_port (device, p) |
| - ib_cache_update(device, p, true); |
| + rdma_for_each_port (device, p) { |
| + err = ib_cache_update(device, p, true); |
| + if (err) |
| + return err; |
| + } |
| |
| return 0; |
| } |
| -- |
| 2.20.1 |
| |