diff options
author | Ilya Dryomov | 2023-07-08 16:16:59 +0200 |
---|---|---|
committer | Greg Kroah-Hartman | 2023-08-03 10:24:17 +0200 |
commit | 0c0b6412c96691bc3cc16f2f4b27591b327e627f (patch) | |
tree | c8eb388198ef3d66e8ab88bb8d654d36676c1bee | |
parent | c0d067c79b238e1458689adc6a2ca31efaf6e7b7 (diff) |
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 523a903d6ae5..2615ab99eb9a 100644 --- a/drivers/block/rbd.c +++ b/drivers/block/rbd.c @@ -3863,10 +3863,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); @@ -3887,18 +3886,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 dfa237fbd5a3..09feb3f1fcaa 100644 --- a/net/ceph/messenger.c +++ b/net/ceph/messenger.c @@ -1118,6 +1118,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) { |