From nobody Mon Jun 8 08:28:03 2026 Received: from mail-qt1-f171.google.com (mail-qt1-f171.google.com [209.85.160.171]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 91E283A75B1 for ; Thu, 4 Jun 2026 18:09:11 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.160.171 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780596553; cv=none; b=KEY+VweMXOawP63g0jZsz5y4E1OYACng5/uTB06vc9wbm9t+EDurhU4PvUBXi4UZe4Cxjr2kMv/JHl7iBqxkhhScDPQz6KjGL2LDT86BO/0FVprou8EJ7CI8oSWlg7v1tDOTUvx0T6e4QwxY8T+LpOuC44U1jvu0DNxFrzjBLp8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780596553; c=relaxed/simple; bh=bT58V/InFAWfeakk78BgVqBWmxLwpXGinvWy6zPUJf8=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=CCRe/qzKNOXTBknNePGfWT3709voU9ps6nFnABa0F9olVYSPmMRXs8lqiNYWr79VKIgKsmmps+RnKak38GG7HK0Nie/68SwqlPGyv1GUxW3ufbUUm9zu+XB9X6zxhnAch/lRSHs2yAGsLvYqLj2pS58tONuvvaoIQDA4HSs6+xM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=A6xGcdsg; arc=none smtp.client-ip=209.85.160.171 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="A6xGcdsg" Received: by mail-qt1-f171.google.com with SMTP id d75a77b69052e-51784eb2ba0so7921491cf.2 for ; Thu, 04 Jun 2026 11:09:11 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1780596550; x=1781201350; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=ZRBmb4WQIMwOp8EJqjAWjm9PjUUHk3D5HPtS2dDVrls=; b=A6xGcdsgzCcGOqoAjMfEDfRTvQBBJszQ0GM3jVbP65DDzfkevXrSXQQ3kkSw7HAgv0 YtQ5D/PrRRC3g2Ixs1KilJEjSsPp6IdJ+x2z7wCXBbxOUja+bADxqUWuVxLH6F9wOpBR FItw3wtmV/SkpH/9WNiPS5DwGTK3p57U7Zg1qcDYlCyj/tpS0BkJjxoWDLt06VgiDAAB 92p8Bh9in89XJLKOTA3kphDY3uMtSyHL0fEnxobfcxZIsTIJvlNo4L6PeGdrvpjXtGPb 2qhSs82QHHkGV56M/J47MW/6Q2iZlA9jvSRaBqtdJAK/LOx3irjkm8EoqOS+5fEyD8zV 7+hw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1780596550; x=1781201350; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=ZRBmb4WQIMwOp8EJqjAWjm9PjUUHk3D5HPtS2dDVrls=; b=kLehUNbb+tynZwjxPiIqFO8Uv5fIin1ojn/oJDyVeGPQTwJ4LCrUXcNKvwOxROTFPR iuPmhWP/NKZDsbzk41+MonoyfUwrowIMuI8r5YHwoQYb5qDQsJ7WM/tbFGR0mCv22rbW xim7Vg84jAcPRJsPZcVKTz1dL0mhWmVxLIpYQnQH7oereGEDlofVvtLZh7TtJsbTrO8x vPF3S4QhEMm566xjv8ygTO/A9iwBasbo0LFCsZCVsJ/q6u81lFaYfQIW4YzbqXOG/hR/ qEt3OKfdLRBEp986+fOrOkRtgKj8Mbo8zlgKruoL6uw7c2yr8h1Lzp0gXj+cLVSdf9hD UJ9g== X-Forwarded-Encrypted: i=1; AFNElJ9MvgGuTxR4rAekUOQpxEHF6x5tp/ZAmKnHRsXBrCsHPcu2OgYihhNB+lNz35Q+lqlK2b9sfY+PMWOtVTQ=@vger.kernel.org X-Gm-Message-State: AOJu0YwYeuHMItuMWVZ5oWWqv7qfEd547J06CWZjHcthgWGQ997LBfHp U5aedl3LkQ/Ih8cs5DuVvmDgLT+uViqdSrsEmxxAbpoucN6GHXxpUEgY X-Gm-Gg: Acq92OE32WqIkGugo7v1znoT3d6wChwnXsCZA3qU7KP7M38QvMYFWR7lbZVWkGgAiES SSDcN4oRsGUrnYbLQSO2SCfmI6Tor2NEN+77MCmr2N/y3x0zNjl16zdwEAkKJAhZmp9Ky18zzks lU+xQVWo7AL17DmPoymrT0lbeenkSDgpImoUhK8PnDBj9iZf6HvVODklN4L9Tp8JWArpEwFl8KQ I0rekbV4po6iUIKrei5ZQfMre9JpSMT2wbAuVhRucTt7HU3lDpJ/UKMHhm+7yh51CdvNzelKhBW oPU+h1eaB0KNL/swdeMqfyp2HF10EkArq8Q14oWvj2SNJTwaeVE3tjw8XYkgQVC59rFQaVW5Qmt FG7iU8E5201mwppbSgU6pcZ3AHGO1bLuYmAFhxXXzZBaQ9Dj2aWcHV6TWywwxsM5cseHCLvb43Z gOKp4MUWZC4h2lEkPF0L0MwWdGFT/OHxIJ3FFrB+hvpGZeWvTyL66jZqemQ493zANmtPUsS8zVP JC0X+vdJ64Lu9s7+G7uxHwjDVzWWI1JWRsbXb/xGA== X-Received: by 2002:a05:622a:a98e:20b0:517:8fb6:56ba with SMTP id d75a77b69052e-5178fb659a0mr25295821cf.24.1780596550612; Thu, 04 Jun 2026 11:09:10 -0700 (PDT) Received: from server0 (c-68-48-65-54.hsd1.mi.comcast.net. [68.48.65.54]) by smtp.gmail.com with ESMTPSA id d75a77b69052e-51775dbd2c9sm59020961cf.23.2026.06.04.11.09.09 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 04 Jun 2026 11:09:09 -0700 (PDT) From: Michael Bommarito To: Ilya Dryomov , Alex Markuze , Viacheslav Dubeyko Cc: ceph-devel@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 1/4] ceph: bound xattr value length in __build_xattrs() Date: Thu, 4 Jun 2026 14:08:57 -0400 Message-ID: <97a34ff3743172b1278f211d47a500a07eb25732.1780596023.git.michael.bommarito@gmail.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" __build_xattrs() decodes the MDS-supplied xattr blob one attribute at a time. For each attribute it reads a 32-bit name length, advances past the name bytes, reads a 32-bit value length, records the value pointer, and advances past the value bytes. The two length fields are read with ceph_decode_32_safe(), but the value bytes themselves are advanced over with a bare "p +=3D len" and no ceph_decode_need() check that "len" bytes remain in the blob. For every attribute except the last, the next iteration's ceph_decode_32_safe() on the following name length implicitly verifies that the previous value did not run past the blob end. The final attribute has no successor, so its decoded value length is never checked against the blob bounds. A malicious or compromised metadata server can set the last attribute's value length larger than the bytes actually present in the blob. The blob is a dedicated kvmalloc() allocation sized to the wire length (ceph_buffer_new() in ceph_fill_inode()). __set_xattr() records the oversized length in xattr->val_len verbatim, and a later getxattr(2) runs memcpy(value, xattr->val, xattr->val_len) into a user-supplied buffer, copying bytes past the end of the allocation back to user space. Impact: a malicious metadata server discloses adjacent kernel heap bytes to a local user via getxattr(2) on a CephFS file. Add the missing ceph_decode_need() so an out-of-bounds value length on the final attribute fails the decode and returns -EIO instead of being stored. Fixes: 355da1eb7a1f ("ceph: inode operations") Cc: stable@vger.kernel.org Signed-off-by: Michael Bommarito Assisted-by: Claude:claude-opus-4-8 Reviewed-by: Viacheslav Dubeyko --- fs/ceph/xattr.c | 1 + 1 file changed, 1 insertion(+) diff --git a/fs/ceph/xattr.c b/fs/ceph/xattr.c index e773be07f7674..d488bb8fc00ba 100644 --- a/fs/ceph/xattr.c +++ b/fs/ceph/xattr.c @@ -848,6 +848,7 @@ static int __build_xattrs(struct inode *inode) name =3D p; p +=3D len; ceph_decode_32_safe(&p, end, len, bad); + ceph_decode_need(&p, end, len, bad); val =3D p; p +=3D len; =20 --=20 2.53.0 From nobody Mon Jun 8 08:28:03 2026 Received: from mail-qt1-f172.google.com (mail-qt1-f172.google.com [209.85.160.172]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id F058939B482 for ; Thu, 4 Jun 2026 18:09:12 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.160.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780596554; cv=none; b=W1PM9E2swJbOiI7vWW05PILCwWX2Raf1hY3AB0cha0FQRIccj6yepARLsqFeqKP+Suuo5hmix4HM4Zyb2LAyAcch4Q+YPA5d1smB861Q8fIg0ZOLIVy3uvkeLa+mwH8D+DBWDr+e+tPNH5tQDZavBF7WiWOsgUu2q05/nrl1ck4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780596554; c=relaxed/simple; bh=PO3iejuBlnRzIOMTIRC7gUF+lvmQGa01DfODjyBXwno=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=M97tlzrpD6vYTsojBYYafNXwP2CRtBpqRDNe6wlevbk4G16C2eppEoukvORy6tLkBB1oPSyJE8bKBJRbzSSRPhnX0LrLCoam91/q3OizIe2i51Nkhm+fmcR5gUjau7W5eUoig5v55/5wR+xJgHWMWxbMHQMH8PrM9ja2LqhgY5k= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=a3mCZt/d; arc=none smtp.client-ip=209.85.160.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="a3mCZt/d" Received: by mail-qt1-f172.google.com with SMTP id d75a77b69052e-5174a1d78f8so9009951cf.2 for ; Thu, 04 Jun 2026 11:09:12 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1780596552; x=1781201352; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=qc3UhhffxGWia37/F9UtpFEHW30fe749qB/+Usg5z+c=; b=a3mCZt/dZCd+Vf9j43EAWOSb6Qjxt1sMcE6Vv6KeNx+kuIEx0tprIB1UiEUpIobOpg CgpefpuCvHxY8AHXAZJqXBJxFG74WtzTLypzfS8LZJ7SmoEnMJ1M8BlgfG/rvTnNzqlQ VmSU/O3+7YEvwpLdmOa+ZngYEmeZ827dy/wpRpHP5WdRr4Tan8KPYRkiQcD+WMtAhiBL o94cRNT3FxLwXZWZrocxsqYgxiDFbV1FenHP+apqSC6ZbeWesazgFvmZ+TWjuzXuv3zv V65lTLN8yjI6l3YKrnebw1Q4dq8wC4sHxDqbi7+NIWpOdYLQKPdiA60BWz58wogK/hzb FSUA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1780596552; x=1781201352; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=qc3UhhffxGWia37/F9UtpFEHW30fe749qB/+Usg5z+c=; b=iNECKbDziwk70jL6Bv/G4CVvUtTeV2hcvdcwGJ65wKc4CEY9DtBcgvL8ovqBJ7vjAZ Ntd2oks+RdWMaMuVbw/PkBoKz45AL4mF3++R0LlHAU/FFoWeR8A7LsRuy391TPGqSVvr ikLS5KrCqrIUdEdlYDnZTyq1ZSsLi3a6zn3RTNGVa7v26XGAEV9svEXqlufGQcrR4rEM 9gbxmYwwtwEOFbX8Bt7XgCOxYd/8tS6VlJ5u4G/y/4Pxxut/TNml3sr0WImFzByS4EeL b7RV7+O3d5n/9vPlKuPrc6/pi+a1fNIfutsVJQJZuCiwlu88WkZyR/NQbKiYb++XU3GX 59vQ== X-Forwarded-Encrypted: i=1; AFNElJ/Wu78pUYWF/kUIWUmRu8l9baJJQ+fGjN0w+L+Rthi4lYLXfp+utaBjWw6AaC5tnPlb9pIrlxnbIRwkrIE=@vger.kernel.org X-Gm-Message-State: AOJu0YwMpBuhHtrEXYux3vu5Nt0xwgfIZ0wMD8htdzW/hxY2/jOGAa+b J4o/niXZIMS4QJAyu4LmPPntRp/L3huJKolKRJ8SE01+4u8ujDXn8kj1 X-Gm-Gg: Acq92OHHIKtQch5YypMnxbHWiAQ2kRfkKGie8iDu0/mAttizES6/FlrDUakQfDodliJ Zmsbh8VgD17i/huMZ6oUVoxr7K/cxOqPCZA0/qg4/sWNTP/6kTw7oKR3oNvBjtud0+qMvbA7lRt r4n0OTphjd3e521ZRa3hD7GCeLwrU0Y5vSc9TszAPGerYg/RBqTTrGW8bI00yvExXtKzkfN3gUw Kw/0TsUjJFy+ip2r0TwsJBQonuQLeXJr5qcahwET4HWXabb1Z13LgnUbsyJI2Keo7nTYW/2dcKF udUpJdVyvFQJDyiP29UdESwgcPZMZSgyjaWsULTrgT0VickA1u7p/bLTm5b1U9PbNa/YFgKrrxw MwOBHFMplmRFNN40iou8/a83nq5jm0anQtDONA2qNO7JBD18aVnUFrG431+Jir3XYgNHvw7/3Vz M0GJUmb6qMvwCkVlk3m6ZWv5AbcLjHNeShsIrhY0KLGIdV0PxToYtIryr4KotMaBlq2unckqGtc UB59cU++ygMUqeaWJ3d17neurfLL+Y= X-Received: by 2002:ac8:6f13:0:b0:50f:c109:b78 with SMTP id d75a77b69052e-517787c0e39mr124706901cf.60.1780596551903; Thu, 04 Jun 2026 11:09:11 -0700 (PDT) Received: from server0 (c-68-48-65-54.hsd1.mi.comcast.net. [68.48.65.54]) by smtp.gmail.com with ESMTPSA id d75a77b69052e-51775dbd2c9sm59020961cf.23.2026.06.04.11.09.10 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 04 Jun 2026 11:09:11 -0700 (PDT) From: Michael Bommarito To: Ilya Dryomov , Alex Markuze , Viacheslav Dubeyko Cc: ceph-devel@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 2/4] ceph: bound MDSCapAuth path and fs_name decode in handle_session() Date: Thu, 4 Jun 2026 14:08:58 -0400 Message-ID: <54eb585e03930ade4d11d9a103eff5f737d65251.1780596023.git.michael.bommarito@gmail.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" handle_session() decodes the MDSCapAuth records carried by a CEPH_SESSION_OPEN message (msg_version >=3D 6). For each record the match.path and match.fs_name byte strings are read by first decoding a 32-bit length and then copying that many bytes with the bare ceph_decode_copy(). Unlike the surrounding fields, which all use the _safe decode variants, these two copies are not preceded by a ceph_decode_need() bounds check, and the enclosing MDSCapAuth and MDSCapMatch struct_len fields are skipped rather than enforced as an upper bound. A length larger than the bytes remaining in the message front makes ceph_decode_copy() read past the end of the front buffer. The message front is a dedicated allocation (ceph_msg_new2() -> kvmalloc), so the over-read runs off that object. A malicious or compromised MDS can trigger this with the first post-connect message on mount, with no client-side user interaction; under KASAN it is reported as a slab-out-of-bounds read in handle_session(). Impact: a malicious MDS can force the kernel client to read up to 4 GiB past the message front allocation during session setup, crashing the client (out-of-bounds read). Switch both copies to ceph_decode_copy_safe(), which performs the ceph_decode_need() bounds check before the copy and branches to the existing bad label, matching the rest of the decoder and the error path that frees the partially decoded cap_auths array. Fixes: 1d17de9534cb ("ceph: save cap_auths in MDS client when session is op= ened") Cc: stable@vger.kernel.org Signed-off-by: Michael Bommarito Assisted-by: Claude:claude-opus-4-8 Reviewed-by: Viacheslav Dubeyko --- fs/ceph/mds_client.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c index ed17e0023705e..4f36ac73305dc 100644 --- a/fs/ceph/mds_client.c +++ b/fs/ceph/mds_client.c @@ -4318,7 +4318,9 @@ static void handle_session(struct ceph_mds_session *s= ession, pr_err_client(cl, "No memory for path\n"); goto fail; } - ceph_decode_copy(&p, cap_auths[i].match.path, _len); + ceph_decode_copy_safe(&p, end, + cap_auths[i].match.path, + _len, bad); =20 /* Remove the tailing '/' */ while (_len && cap_auths[i].match.path[_len - 1] =3D=3D '/') { @@ -4335,7 +4337,9 @@ static void handle_session(struct ceph_mds_session *s= ession, pr_err_client(cl, "No memory for fs_name\n"); goto fail; } - ceph_decode_copy(&p, cap_auths[i].match.fs_name, _len); + ceph_decode_copy_safe(&p, end, + cap_auths[i].match.fs_name, + _len, bad); } =20 ceph_decode_8_safe(&p, end, cap_auths[i].match.root_squash, bad); --=20 2.53.0 From nobody Mon Jun 8 08:28:03 2026 Received: from mail-qt1-f179.google.com (mail-qt1-f179.google.com [209.85.160.179]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id EF2303C0A05 for ; Thu, 4 Jun 2026 18:09:14 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.160.179 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780596556; cv=none; b=LIFUxUF6SzS6OIqzY/vKF+v0OadOfhoE8c5KF1YxIGDCUJNDvvPKDrBx1D7MQ6Rj+tPzwsT/HsJqLZWA7eyfGjpGBkZX3mqiTYJE82Sx3CPNRd8SWJxl2CgAa1P9yHH1sZAp8b5XxQhNVDzix1DWGZP3pFH2e87NnMkUTA1xSYA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780596556; c=relaxed/simple; bh=iRGl+Zcv8CCCaVj7l7eFQI316DRL7nx4+17jWOdN+ZQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=JwWEk9ZMLvM8U0Y9a0OZICMAXmksWVnevhombMwpoNiNjplgOuy6Wwm2DX+wo7y4S043Z4dV/qx+6+M4zISsZ//38D5LjiG9NUlU5OqQxm0mkITb70Caha19+v9FTKn2ky8/Q5kT60FOyAnbPRXM6Tx1HM0q+e+1i3IpSJd3F1U= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=kiXwoAM8; arc=none smtp.client-ip=209.85.160.179 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="kiXwoAM8" Received: by mail-qt1-f179.google.com with SMTP id d75a77b69052e-51761d27612so10501181cf.3 for ; Thu, 04 Jun 2026 11:09:14 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1780596554; x=1781201354; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=MyP4o+dWT8qg11HXzsRqDPlFSQhGfJVHTkPwzcA0P6E=; b=kiXwoAM8Zf0OUn66TNmFK+ONm02GJHbG/GIgTMf14eIh6uH35dJOW9WA6q2UW8gPgy qK5PBwLhydAH8NBt7QRmZS+GE7zSCrWGHNGOdxtdwyXazCRrhSkwaHy0R3jOwuFbJ0ZW BqjFFaiJfy4z64pg0N/LR1kBGAuXGo1myq5qJc8kyAsMv1B4ELmgb9aZdFvwvo7pNh8u s6sWYHkgfQ3bgYqr8im6w1RCiyo5nEtRWYygRWjyeBzansWyVEkgRy7Z/b0gCiSQmzAq zg+Px0tXcI42sh9G5aNwUinzzT7qhpA7ldMMLkaEgwZ4UCP+ny4fvBujQdLS+qvf8FQC X85Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1780596554; x=1781201354; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=MyP4o+dWT8qg11HXzsRqDPlFSQhGfJVHTkPwzcA0P6E=; b=N+Bm42KF6Mf9Jl6wK5cTe3t+ukYAojEQsv9wGEzubvx+e4MBIXHrdqZcyz6RCoKvWL hn0fSJS0PtY7lrLrLcCfyjYsaAvpByMJoaQKtERU5qmGXCz6ukbguTqCIdTGAdONflDp lR7nIdnewsllfQmFrihxKfzfNwmvawhD4TXtcsyS+FUTftrlbCfxISWTQ+wORyeJc7dq eNUbC0OrIBTMYBnWuXul+WDjPqZWPpcAVdDqDcDan0p0BV0xJkh5uyUSr3bPNZQMR7Ie JoRgZ8Z8cl2m6TkvJsPw///DWW3xDrKmjy0bKo2KULls4jgv91dJf8GcvC0YSfe3E6+T AxKg== X-Forwarded-Encrypted: i=1; AFNElJ9JSVmFzz5hUy/XffWkojZr7ic+5A4y0k/FOhHDxURkxVgm5PpUM0W+5CaHfIaylhSVt/LsWDKHKn2FDC0=@vger.kernel.org X-Gm-Message-State: AOJu0YzIQTxc72t636x/h1F0OT5vQfy3dRe+Jc+LpDyUY0YLRI61luN6 rtoPB5IIVVjz81DK8w4db0ilaz3suiTmKyNPp5Z7h2+mUh8kfElS2xY5 X-Gm-Gg: Acq92OEDoEf4qlpdb508M0pSggB8XoUf6Ov5HsycdCD/x2ct1ncyzqupGkJIZFwRECj pFNZjN7bgBo5TV8dOlIdlRNDbfUCsPuvpkBV2dY6N2rFoAi37BtFr72pHnXEIIUDvLmLp6zXZop +BaX9Gcr6Et53SJZFbAwgWTv9v2UaunEoDDhIAr0qhZSzbvxaM7433kpr3Zu4/LzJnvAKmoQ4Ev PiS5QX+FjWauOW8+cUApMcgL3LtXQGdf5uFJ1qM1ujzM9wAJsUHr3uMj/d+udkE9jn8JdZCY2pr P1/m2gdLxAQVq60GtOgkK7yig4nLVwiwfIRCWqA+XFXGHVnc8nKorW5ENudfNvfTGNirUlyeZjt 7oVfKMTzAcrRkEyQvdaZ57II+BzzRAu/68oICRLEp/BoX6HpDakSLxZOPG5Gc1XptjxqfkH7uhn NajD0GshGKpMKeqVrmQSAzOt+/BWmp6cq+RMoDiWW9xbt3ViGoZIpOHQdsaTBEL7apLUOwlSIOr E6soaBGOhLPwHIAC3S1YqCiZtLLeiA= X-Received: by 2002:a05:622a:d17:b0:517:61d5:2f85 with SMTP id d75a77b69052e-517786c8788mr115781731cf.33.1780596553790; Thu, 04 Jun 2026 11:09:13 -0700 (PDT) Received: from server0 (c-68-48-65-54.hsd1.mi.comcast.net. [68.48.65.54]) by smtp.gmail.com with ESMTPSA id d75a77b69052e-51775dbd2c9sm59020961cf.23.2026.06.04.11.09.12 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 04 Jun 2026 11:09:12 -0700 (PDT) From: Michael Bommarito To: Ilya Dryomov , Alex Markuze , Viacheslav Dubeyko Cc: ceph-devel@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 3/4] ceph: bound num_export_targets array for mds info v2/v3 Date: Thu, 4 Jun 2026 14:08:59 -0400 Message-ID: <4ac3b57dcf0fba1dc5cc08bfb9a453be55cc465d.1780596023.git.michael.bommarito@gmail.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" ceph_mdsmap_decode() in fs/ceph/mdsmap.c reads num_export_targets from each per-mds info record and advances the decode cursor by num_export_targets * sizeof(u32) without first checking that many bytes remain. The only upper-bound check that catches a runaway cursor (*p > info_end) is gated on info_v >=3D 4, because info_end is left NULL for info_v 2 and 3. When the monitor sends an MDS map whose per-mds info version is 2 or 3 with an oversized num_export_targets, the cursor moves past the message front buffer and the later export-targets loop calls the unchecked ceph_decode_32() on out-of-bounds memory. A kernel client processes CEPH_MSG_MDS_MAP from its monitor session (net/ceph/mon_client.c dispatches it; fs/ceph/super.c routes it to ceph_mdsc_handle_mdsmap(), which sets end to the front buffer bound and calls ceph_mdsmap_decode()). A malicious or compromised monitor, or an on-path attacker on an unsigned/unencrypted messenger session, can therefore drive an out-of-bounds read in the client kernel; on x86_64 with KASAN it is reported as a slab-out-of-bounds read in ceph_mdsmap_decode(). The decoded values land in the internal info->export_targets[] array, so the consequence is a kernel out-of-bounds read, not an information leak to the attacker. Impact: a malicious or compromised Ceph monitor sending an MDS map with a per-mds info version of 2 or 3 and an oversized num_export_targets field triggers an out-of-bounds read in the CephFS client kernel. Add a ceph_decode_need() for num_export_targets * sizeof(u32) before advancing the cursor, so the bound is enforced for every info_v >=3D 2, not only info_v >=3D 4. This mirrors the count-then-need idiom already used for m_data_pg_pools later in the same function. Fixes: d463a43d69f4 ("ceph: CEPH_FEATURE_MDSENC support") Cc: stable@vger.kernel.org Assisted-by: Claude:claude-opus-4-8 Signed-off-by: Michael Bommarito --- fs/ceph/mdsmap.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/fs/ceph/mdsmap.c b/fs/ceph/mdsmap.c index d8e46eb7e5eb5..7cb65f9f4783c 100644 --- a/fs/ceph/mdsmap.c +++ b/fs/ceph/mdsmap.c @@ -224,6 +224,8 @@ struct ceph_mdsmap *ceph_mdsmap_decode(struct ceph_mds_= client *mdsc, void **p, *p +=3D namelen; if (info_v >=3D 2) { ceph_decode_32_safe(p, end, num_export_targets, bad); + ceph_decode_need(p, end, + num_export_targets * sizeof(u32), bad); pexport_targets =3D *p; *p +=3D num_export_targets * sizeof(u32); } else { --=20 2.53.0 From nobody Mon Jun 8 08:28:03 2026 Received: from mail-qt1-f172.google.com (mail-qt1-f172.google.com [209.85.160.172]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 1D6933A5E6C for ; Thu, 4 Jun 2026 18:09:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.160.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780596557; cv=none; b=mfZ6uvUY+D+rGhWYIOREN7g06bxXDKIPP8zbPecRujaPRS/FWHubet7kFouCJsYnqcOtJv1HURkqKjdr8yXPsVZ+YRDbDMRagqh7IZhgmlxPAKPr1ze7SuepervQu7yyqN60KxWuKURxvfzu0iw7I6u3E7T2/yC5zO++fxTLw+g= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780596557; c=relaxed/simple; bh=fX7fFsPfEFC3JMips9J8bHVCCgmHkm5jA9KcnfjY+8A=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Kls92d91qUWo7v6QCEFwlHEkaOoor7hy/Lbv25PnBL55xYxHSavCGOqX3pHgBC8Ody+jwkdB0No7agH8mFCAmqmSRzYsYZWgisyqy0vqlJoDfi1XQPP6oXBfMgJbYPy8zeGWsgH803gsviojzG7dUi0Yu8hXp5jlyHiApBQAmqE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=jwCstpsJ; arc=none smtp.client-ip=209.85.160.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="jwCstpsJ" Received: by mail-qt1-f172.google.com with SMTP id d75a77b69052e-51775f2473aso7641171cf.0 for ; Thu, 04 Jun 2026 11:09:16 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1780596555; x=1781201355; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=BX4HzXJ3JGZjJL5r8tJ9uzkaLb8khgmN8CTpb058st8=; b=jwCstpsJWJ2drukiVKXlyhm02GTMHoz/lPbmvi0p96clarOMmkDLIJE+pIgpGviwIo uPk0m4WHDzMa2i1nY+hQ2HSL3yvnmgiVRruhlTOxr7Fdk6IVDq8sDVOsHfKJNcEiGLcK KcYqc20zaGvwsJ5KiQe0iSgRYARAeDFzJreZjTmPPOpd0CDe9GpxSgqZek7E3qmoZxKs utKAjX86hvcSHUEIAY6mlEVm69djfFLqDPn+9jMGflvKUjr2p1yUnIjXbPH6bc/LsQQM TKA7hLjQmjV5o3Bu74Q2ASWIRtqh5THhNz4C/a14kQAXrH2ia7NU2nPo9G55TXWmEd2o +pJw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1780596555; x=1781201355; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=BX4HzXJ3JGZjJL5r8tJ9uzkaLb8khgmN8CTpb058st8=; b=OFxcuUoiNZCAqKKImoEd0ABA+tVD7XR4a9JuNXwe3awJpsdACMbPl77ie73Fh++lYQ p0RELjb8OyoNWjYMEnN4M3dDiDJ2+hJCT1DM++q8vHVdUZKBzu6TrGaBvT5JMOkXi+kD 9He/rE5qA3PRPxf5dA+FsusNobg2lr25jAYbgU3Wre2UYhqgiM/vtks72400enzn4S4I 6xgMPUOsnkXOq/IUKnIdNIdOErornbk5Wdg5pCi9JQQnNWH5ot7/3skDBY5GMYgzsZNt 24csKb+AV8foA/qOSa8t+wn+1MOYTd5095/JUSeE7RTslnjqE1pmCnkkGMXm6hG7lt/D oC2g== X-Forwarded-Encrypted: i=1; AFNElJ/TItabqkRcF2Ra1/Cml9Fswo5OXj9M1Cq7ImL2ByFUhvJKCeU7YbKEu/8Ra9w8p6AKlfCXB9lyZV8dRhg=@vger.kernel.org X-Gm-Message-State: AOJu0YxC0AoMYCBKmuFpC5dz8RxW3C4RvaeCbHuJty40FqSsfFpq2sV/ zBEtJ3se3LY0guxCHsWW0Wrmx6zxfsnEfdZXUuXnnljgnUlZf/5CQ9X0 X-Gm-Gg: Acq92OHuXts9A9+tJSB5UhV0nRZ+Dqh2JLCHiC+YJN38/4dEJPaVpKIjdBIvphleGJj Y6gpoMIpyynVqbMK75xAY+zsdfDl4wbY0DTmjElxcSctCW5JiekSY4t/wZDuZZLN9af0FQan8M/ 1aWXKyMeUUWtwPUh9TaIabOY1O+sLqy4UDbtSyQjAvzGMEzb1/ruWS7jhK+ORa/MJ5Zar/paMvV YuYpcNW2X3xZwftDHNvcbvHyXHYagp7EQyJBqr0KZDdAmre88HH1EkpwLJmbEbV0O2/Rx75ybmd GCK36pfR6EsCiLoqeeFbKl04PWxLCCU2Tx6VgPjodlRNZRMiH2h81qy+SV3du9efvCSiD2EUDs2 Ovj2UquCFJXF9pIyjGRY98IFwWUyzmizyHqM8OvW4eIynurUTVVFqKH+YT7pDw1Zdd1QYJdXioJ AYQnaC3+mS7K09k17/GD3o69Kaz5mBiEbbJpkRgYU+YM/LTNG/fEdvENWIXL2bcNWa5QXfJ7T+e ExF07BmZM/de07pvyAhsz4GGhSBwRJrB/X4awYrBA== X-Received: by 2002:ac8:5881:0:b0:517:82bd:46ff with SMTP id d75a77b69052e-51782bd4a4fmr96126461cf.26.1780596555207; Thu, 04 Jun 2026 11:09:15 -0700 (PDT) Received: from server0 (c-68-48-65-54.hsd1.mi.comcast.net. [68.48.65.54]) by smtp.gmail.com with ESMTPSA id d75a77b69052e-51775dbd2c9sm59020961cf.23.2026.06.04.11.09.13 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 04 Jun 2026 11:09:14 -0700 (PDT) From: Michael Bommarito To: Ilya Dryomov , Alex Markuze , Viacheslav Dubeyko Cc: ceph-devel@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 4/4] ceph: cap delegated inode count in ceph_parse_deleg_inos() Date: Thu, 4 Jun 2026 14:09:00 -0400 Message-ID: <8f25e9ac54cb3c408d061993a5a797186aa50506.1780596023.git.michael.bommarito@gmail.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" ceph_parse_deleg_inos() decodes interval sets of delegated inode numbers from an MDS create-with-delegation reply. For each set it reads a 64-bit start and a 64-bit len with ceph_decode_64_safe(), which only validates that the eight bytes are present in the message, not the value, and then loops: while (len--) { xa_insert(&s->s_delegated_inos, start++, DELEGATED_INO_AVAILABLE, GFP_KERNEL); ... } len is fully attacker controlled. A malicious or compromised MDS can send a create reply whose interval set declares len near 2^63, driving an effectively unbounded loop that performs a GFP_KERNEL xarray insert on each iteration. This spins a kernel thread in the reply dispatch path and exhausts memory; on a client that has negotiated CEPHFS_FEATURE_DELEG_INO (enabled by default) a single reply is enough to wedge the mount. A legitimate MDS delegates only a small range per set (the userspace MDS prealloc window, mds_client_prealloc_inos, defaults to 1000). Reject any set whose len exceeds CEPH_MAX_DELEG_INOS (1M, far above any legitimate value) by treating the reply as malformed and returning -EIO, consistent with the existing decode error handling. Normal delegations are well under the cap and are unaffected. Fixes: d4846487870897 ("ceph: decode interval_sets for delegated inos") Cc: stable@vger.kernel.org Signed-off-by: Michael Bommarito Assisted-by: Claude:claude-opus-4-8 --- fs/ceph/mds_client.c | 14 ++++++++++++++ fs/ceph/super.h | 9 +++++++++ 2 files changed, 23 insertions(+) diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c index 4f36ac73305dc..0a084c4f3aae2 100644 --- a/fs/ceph/mds_client.c +++ b/fs/ceph/mds_client.c @@ -633,6 +633,20 @@ static int ceph_parse_deleg_inos(void **p, void *end, start, len); continue; } + + /* + * A legitimate MDS delegates a small range per set. Treat a + * count larger than any plausible delegation window as a + * malformed reply rather than spinning while(len--) and + * inserting unbounded xarray entries. + */ + if (len > CEPH_MAX_DELEG_INOS) { + pr_warn_ratelimited_client(cl, + "rejecting oversized inode range delegation (start=3D0x%llx len=3D0x%l= lx)\n", + start, len); + return -EIO; + } + while (len--) { int err =3D xa_insert(&s->s_delegated_inos, start++, DELEGATED_INO_AVAILABLE, diff --git a/fs/ceph/super.h b/fs/ceph/super.h index afc89ce91804e..43a9b075f344c 100644 --- a/fs/ceph/super.h +++ b/fs/ceph/super.h @@ -634,6 +634,15 @@ static inline int ceph_ino_compare(struct inode *inode= , void *data) #define CEPH_MDS_INO_LOG_OFFSET (2 * CEPH_MAX_MDS) #define CEPH_INO_SYSTEM_BASE ((6*CEPH_MAX_MDS) + (CEPH_MAX_MDS * CEPH_NUM= _STRAY)) =20 +/* + * Upper bound on the number of inodes the MDS may delegate to a client in= a + * single interval set. The userspace MDS hands out at most a few thousand + * (mds_client_prealloc_inos, default 1000); 1M is far above any legitimate + * value and guards ceph_parse_deleg_inos() against an unbounded loop driv= en + * by an attacker controlled 64-bit length. + */ +#define CEPH_MAX_DELEG_INOS (1024 * 1024) + static inline bool ceph_vino_is_reserved(const struct ceph_vino vino) { if (vino.ino >=3D CEPH_INO_SYSTEM_BASE || --=20 2.53.0