A handful of tiny fixes, with the main ones being a follow-up for

CEPH_IOC_SET_LAYOUT{,_POLICY} ioctl permissions check that went into
 -rc5 and a userspace compatibility fixup.  The rest mostly harden
 against malformed network input.  All marked for stable.
 -----BEGIN PGP SIGNATURE-----
 
 iQFHBAABCgAxFiEEydHwtzie9C7TfviiSn/eOAIR84sFAmp/SyQTHGlkcnlvbW92
 QGdtYWlsLmNvbQAKCRBKf944AhHzi+OMB/9DOUyMrxqGptG9BhzMmHPIMNE7PI+m
 jHh0zEnMsE2rKaYfkLNf/p7RrcvcK4PSMCYZKXSUx0D6n3PoEccDW/JTC/rro5B/
 3fZIAaZBg8B25o6b0uGjO29e7BY+WouoNAC6fU9F/DtVTnYp4bk40DsvQS6pvFiN
 K2sVLIsSBhDZ7czmVlMlpc/er64TRYnWGmaxaAPMuiW5HEhWxvFDav3/r3gsP/fk
 mFJ5QU4qcq/q0QmMW7gO9Q+GXjOK2+9eaplNF3wCOSdHIF2nX5knbvgu5n7a4Qoh
 GNf0ak7PfFCzUoRdC/4XkMRQAO9IYgzq45EivApJQKvKmETWrzFLQ1uP
 =pOld
 -----END PGP SIGNATURE-----

Merge tag 'ceph-for-7.2-rc8' of https://github.com/ceph/ceph-client

Pull ceph fixes from Ilya Dryomov:
 "A handful of tiny fixes, with the main ones being a follow-up for
  CEPH_IOC_SET_LAYOUT{,_POLICY} ioctl permissions check that went into
  rc5 and a userspace compatibility fixup.  The rest mostly harden
  against malformed network input.  All marked for stable"

* tag 'ceph-for-7.2-rc8' of https://github.com/ceph/ceph-client:
  ceph: use the mount idmap for the owner checks in the SET_LAYOUT ioctls
  ceph: fix MDS random selection readiness predicate
  libceph: Avoid using invalid osd indices from primary_temp
  libceph: fix OOB read in decode_watchers() via missing bounds check
  libceph: fix multiple unsafe decodes in decode_locker()
  libceph: tolerate addrvecs with multiple entries of the same type
This commit is contained in:
Linus Torvalds 2026-08-14 10:18:06 -07:00
commit c5890ac6d5
6 changed files with 28 additions and 19 deletions

View File

@ -72,7 +72,7 @@ static long ceph_ioctl_set_layout(struct file *file, void __user *arg)
struct ceph_ioctl_layout nl;
int err;
if (!inode_owner_or_capable(&nop_mnt_idmap, inode))
if (!inode_owner_or_capable(file_mnt_idmap(file), inode))
return -EACCES;
if (copy_from_user(&l, arg, sizeof(l)))
@ -145,7 +145,7 @@ static long ceph_ioctl_set_layout_policy (struct file *file, void __user *arg)
int err;
struct ceph_mds_client *mdsc = ceph_sb_to_fs_client(inode->i_sb)->mdsc;
if (!inode_owner_or_capable(&nop_mnt_idmap, inode))
if (!inode_owner_or_capable(file_mnt_idmap(file), inode))
return -EACCES;
/* copy and validate */

View File

@ -15,7 +15,7 @@
#include "super.h"
#define CEPH_MDS_IS_READY(i, ignore_laggy) \
(m->m_info[i].state > 0 && ignore_laggy ? true : !m->m_info[i].laggy)
(m->m_info[i].state > 0 && (ignore_laggy ? true : !m->m_info[i].laggy))
static int __mdsmap_get_random_mds(struct ceph_mdsmap *m, bool ignore_laggy)
{

View File

@ -259,7 +259,8 @@ static int decode_locker(void **p, void *end, struct ceph_locker *locker)
if (ret)
return ret;
ceph_decode_copy(p, &locker->id.name, sizeof(locker->id.name));
ceph_decode_copy_safe(p, end, &locker->id.name,
sizeof(locker->id.name), bad);
s = ceph_extract_encoded_string(p, end, NULL, GFP_NOIO);
if (IS_ERR(s))
return PTR_ERR(s);
@ -270,19 +271,23 @@ static int decode_locker(void **p, void *end, struct ceph_locker *locker)
if (ret)
return ret;
*p += sizeof(struct ceph_timespec); /* skip expiration */
/* skip expiration */
ceph_decode_skip_n(p, end, sizeof(struct ceph_timespec), bad);
ret = ceph_decode_entity_addr(p, end, &locker->info.addr);
if (ret)
return ret;
len = ceph_decode_32(p);
*p += len; /* skip description */
/* skip description */
ceph_decode_skip_string(p, end, bad);
dout("%s %s%llu cookie %s addr %s\n", __func__,
ENTITY_NAME(locker->id.name), locker->id.cookie,
ceph_pr_addr(&locker->info.addr));
return 0;
bad:
return -EINVAL;
}
static int decode_lockers(void **p, void *end, u8 *type, char **tag,

View File

@ -87,8 +87,9 @@ ceph_decode_entity_addr(void **p, void *end, struct ceph_entity_addr *addr)
EXPORT_SYMBOL(ceph_decode_entity_addr);
/*
* Return addr of desired type (MSGR2 or LEGACY) or error.
* Make sure there is only one match.
* Return addr of desired type (MSGR2 or LEGACY) or error. In case of
* multiple matches, use the first one for compatibility with userspace
* messenger.
*
* Assume encoding with MSG_ADDR2.
*/
@ -121,14 +122,13 @@ int ceph_decode_entity_addrvec(void **p, void *end, bool msgr2,
dout("%s i %d addr %s\n", __func__, i, ceph_pr_addr(&tmp_addr));
if (tmp_addr.type == my_type) {
if (found) {
pr_err("another match of type %d in addrvec\n",
le32_to_cpu(my_type));
return -EINVAL;
if (!found) {
memcpy(addr, &tmp_addr, sizeof(*addr));
found = true;
} else {
dout("%s skipping extra match of type %d in addrvec\n",
__func__, le32_to_cpu(my_type));
}
memcpy(addr, &tmp_addr, sizeof(*addr));
found = true;
}
}

View File

@ -5030,7 +5030,7 @@ static int decode_watchers(void **p, void *end,
if (ret)
return ret;
*num_watchers = ceph_decode_32(p);
ceph_decode_32_safe(p, end, *num_watchers, bad);
*watchers = kzalloc_objs(**watchers, *num_watchers, GFP_NOIO);
if (!*watchers)
return -ENOMEM;
@ -5044,6 +5044,9 @@ static int decode_watchers(void **p, void *end,
}
return 0;
bad:
return -EINVAL;
}
/*

View File

@ -2809,9 +2809,10 @@ static void get_temp_osds(struct ceph_osdmap *osdmap,
}
}
/* primary_temp? */
/* primary_temp? (shouldn't ever be a nonexistent or down OSD) */
pg = lookup_pg_mapping(&osdmap->primary_temp, pgid);
if (pg)
if (pg && !WARN_ON_ONCE(ceph_osd_is_down(osdmap,
pg->primary_temp.osd)))
temp->primary = pg->primary_temp.osd;
}