diff options
author | Ilya Dryomov <idryomov@gmail.com> | 2023-07-08 16:16:59 +0200 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2023-08-03 10:26:13 +0200 |
commit | 44f442aa19f0c992728c5af79f6aa9e6df2ad01a (patch) | |
tree | 2e164eaa37932bf30b17e59e8c58944589ff4842 | |
parent | 0a83f816a8f1ed381907c99107652832965308bd (diff) | |
download | linux-stable-44f442aa19f0c992728c5af79f6aa9e6df2ad01a.tar.gz linux-stable-44f442aa19f0c992728c5af79f6aa9e6df2ad01a.tar.bz2 linux-stable-44f442aa19f0c992728c5af79f6aa9e6df2ad01a.zip |
rbd: harden get_lock_owner_info() a bit
commit 8ff2c64c9765446c3cef804fb99da04916603e27 upstream.
- we want the exclusive lock type, so test for it directly
- use sscanf() to actually parse the lock cookie and avoid admitting
invalid handles
- bail if locker has a blank address
Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
Reviewed-by: Dongsheng Yang <dongsheng.yang@easystack.cn>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r-- | drivers/block/rbd.c | 21 | ||||
-rw-r--r-- | net/ceph/messenger.c | 1 |
2 files changed, 16 insertions, 6 deletions
diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c index 7c37c047dbea..a6210dfae001 100644 --- a/drivers/block/rbd.c +++ b/drivers/block/rbd.c @@ -3862,10 +3862,9 @@ static struct ceph_locker *get_lock_owner_info(struct rbd_device *rbd_dev) u32 num_lockers; u8 lock_type; char *lock_tag; + u64 handle; int ret; - dout("%s rbd_dev %p\n", __func__, rbd_dev); - ret = ceph_cls_lock_info(osdc, &rbd_dev->header_oid, &rbd_dev->header_oloc, RBD_LOCK_NAME, &lock_type, &lock_tag, &lockers, &num_lockers); @@ -3886,18 +3885,28 @@ static struct ceph_locker *get_lock_owner_info(struct rbd_device *rbd_dev) goto err_busy; } - if (lock_type == CEPH_CLS_LOCK_SHARED) { - rbd_warn(rbd_dev, "shared lock type detected"); + if (lock_type != CEPH_CLS_LOCK_EXCLUSIVE) { + rbd_warn(rbd_dev, "incompatible lock type detected"); goto err_busy; } WARN_ON(num_lockers != 1); - if (strncmp(lockers[0].id.cookie, RBD_LOCK_COOKIE_PREFIX, - strlen(RBD_LOCK_COOKIE_PREFIX))) { + ret = sscanf(lockers[0].id.cookie, RBD_LOCK_COOKIE_PREFIX " %llu", + &handle); + if (ret != 1) { rbd_warn(rbd_dev, "locked by external mechanism, cookie %s", lockers[0].id.cookie); goto err_busy; } + if (ceph_addr_is_blank(&lockers[0].info.addr)) { + rbd_warn(rbd_dev, "locker has a blank address"); + goto err_busy; + } + + dout("%s rbd_dev %p got locker %s%llu@%pISpc/%u handle %llu\n", + __func__, rbd_dev, ENTITY_NAME(lockers[0].id.name), + &lockers[0].info.addr.in_addr, + le32_to_cpu(lockers[0].info.addr.nonce), handle); out: kfree(lock_tag); diff --git a/net/ceph/messenger.c b/net/ceph/messenger.c index cd7b0bf5369e..5eb4898cccd4 100644 --- a/net/ceph/messenger.c +++ b/net/ceph/messenger.c @@ -1123,6 +1123,7 @@ bool ceph_addr_is_blank(const struct ceph_entity_addr *addr) return true; } } +EXPORT_SYMBOL(ceph_addr_is_blank); int ceph_addr_port(const struct ceph_entity_addr *addr) { |