* [PATCH v5 0/2] libceph: reject zero bucket types and clean up type 0 uses
@ 2026-06-05 8:43 Ren Wei
2026-06-05 8:43 ` [PATCH v5 1/2] libceph: reject zero bucket types in crush_decode Ren Wei
2026-06-05 8:43 ` [PATCH v5 2/2] libceph: crush: use CRUSH_ITEM_TYPE_DEVICE for leaf device checks Ren Wei
0 siblings, 2 replies; 4+ messages in thread
From: Ren Wei @ 2026-06-05 8:43 UTC (permalink / raw)
To: Viacheslav Dubeyko, ceph-devel
Cc: idryomov, amarkuze, slava, sage, Slava.Dubeyko, yuantan098,
zcliangcn, bird, ldy3087146292, n05ec
From: Douya Le <ldy3087146292@gmail.com>
This series fixes a CRUSH map decode issue in libceph and keeps the
follow-up type-0-to-constant cleanup in a separate patch.
Patch 1/2 rejects bucket type 0 during CRUSH map decode and defines the
reserved device type in a separate enum.
Patch 2/2 uses that type constant consistently in the CRUSH mapper
paths that identify leaf devices.
Douya Le (2):
libceph: reject zero bucket types in crush_decode
libceph: crush: use CRUSH_ITEM_TYPE_DEVICE for leaf device checks
include/linux/crush/crush.h | 6 +++++-
net/ceph/crush/mapper.c | 8 ++++----
net/ceph/osdmap.c | 2 ++
3 files changed, 11 insertions(+), 5 deletions(-)
--
2.47.3
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH v5 1/2] libceph: reject zero bucket types in crush_decode
2026-06-05 8:43 [PATCH v5 0/2] libceph: reject zero bucket types and clean up type 0 uses Ren Wei
@ 2026-06-05 8:43 ` Ren Wei
2026-06-05 19:03 ` Viacheslav Dubeyko
2026-06-05 8:43 ` [PATCH v5 2/2] libceph: crush: use CRUSH_ITEM_TYPE_DEVICE for leaf device checks Ren Wei
1 sibling, 1 reply; 4+ messages in thread
From: Ren Wei @ 2026-06-05 8:43 UTC (permalink / raw)
To: Viacheslav Dubeyko, ceph-devel
Cc: idryomov, amarkuze, slava, sage, Slava.Dubeyko, yuantan098,
zcliangcn, bird, ldy3087146292, n05ec
From: Douya Le <ldy3087146292@gmail.com>
CRUSH bucket type 0 is reserved for devices. The mapper relies on
that invariant and uses type 0 to identify leaf devices.
If crush_decode() accepts a bucket with type 0, a malformed CRUSH map
can make the mapper treat a negative bucket ID as a device and pass it
to is_out(), causing an out-of-bounds access when indexing the OSD
weight array with a negative value.
Reject zero bucket types while decoding the CRUSH map so the invalid
state never reaches the mapper.
Define the reserved device type in a separate enum instead of mixing it
into the bucket algorithm enum.
Fixes: f24e9980eb86 ("ceph: OSD client")
Cc: stable@vger.kernel.org
Reported-by: Yuan Tan <yuantan098@gmail.com>
Reported-by: Zhengchuan Liang <zcliangcn@gmail.com>
Reported-by: Xin Liu <bird@lzu.edu.cn>
Assisted-by: Codex:GPT-5.4
Signed-off-by: Douya Le <ldy3087146292@gmail.com>
Signed-off-by: Ren Wei <n05ec@lzu.edu.cn>
---
Changes in v5:
- add a cover letter for the two-patch series
- define CRUSH_ITEM_TYPE_DEVICE in a separate enum as suggested
- v4 Link: https://lore.kernel.org/all/8fbe4d61ba313a26.1780473720.git.ldy3087146292@gmail.com/
Changes in v4:
- define CRUSH_ITEM_TYPE_DEVICE as a standalone constant instead of
putting it in the bucket algorithm enum
- move the remaining type-0-to-constant cleanups into a separate patch
- v3 Link: https://lore.kernel.org/all/d21e2f97dfe6f250.1780369814.git.ldy3087146292@gmail.com/
Changes in v3:
- use CRUSH_BUCKET_DEVICE instead of CRUSH_ITEM_TYPE_DEVICE
- v2 Link: https://lore.kernel.org/all/3200151429f33554f06ced8a.1780197742.git.ldy3087146292@gmail.com/
Changes in v2:
- use CRUSH_ITEM_TYPE_DEVICE instead of hardcoded 0
- v1 Link: https://lore.kernel.org/all/4ad15b49fbbae00d86dfe12348bf94d45aa60ac2.1779949116.git.ldy3087146292@gmail.com/
---
include/linux/crush/crush.h | 6 +++++-
net/ceph/osdmap.c | 2 ++
2 files changed, 7 insertions(+), 1 deletion(-)
diff --git a/include/linux/crush/crush.h b/include/linux/crush/crush.h
index 30dba392b7302de3e14861f8b769242cd8cbac9e..770b172903f3ab268226296043a909861582bcb1 100644
--- a/include/linux/crush/crush.h
+++ b/include/linux/crush/crush.h
@@ -110,6 +110,10 @@ struct crush_rule {
* straw O(n) better better
* straw2 O(n) optimal optimal
*/
+enum {
+ CRUSH_ITEM_TYPE_DEVICE = 0,
+};
+
enum {
CRUSH_BUCKET_UNIFORM = 1,
CRUSH_BUCKET_LIST = 2,
@@ -130,7 +134,7 @@ extern const char *crush_bucket_alg_name(int alg);
struct crush_bucket {
__s32 id; /* this'll be negative */
- __u16 type; /* non-zero; type=0 is reserved for devices */
+ __u16 type; /* non-zero; CRUSH_ITEM_TYPE_DEVICE is reserved */
__u8 alg; /* one of CRUSH_BUCKET_* */
__u8 hash; /* which hash function to use, CRUSH_HASH_* */
__u32 weight; /* 16-bit fixed point */
diff --git a/net/ceph/osdmap.c b/net/ceph/osdmap.c
index 8b5b0587a0cfa2c437b76c8c87251199efe20291..21cdd33f2945e0c1f45277ac05fda373bf217586 100644
--- a/net/ceph/osdmap.c
+++ b/net/ceph/osdmap.c
@@ -518,6 +518,8 @@ static struct crush_map *crush_decode(void *pbyval, void *end)
ceph_decode_need(p, end, 4*sizeof(u32), bad);
b->id = ceph_decode_32(p);
b->type = ceph_decode_16(p);
+ if (b->type == CRUSH_ITEM_TYPE_DEVICE)
+ goto bad;
b->alg = ceph_decode_8(p);
if (b->alg != alg) {
b->alg = 0;
--
2.47.3
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH v5 2/2] libceph: crush: use CRUSH_ITEM_TYPE_DEVICE for leaf device checks
2026-06-05 8:43 [PATCH v5 0/2] libceph: reject zero bucket types and clean up type 0 uses Ren Wei
2026-06-05 8:43 ` [PATCH v5 1/2] libceph: reject zero bucket types in crush_decode Ren Wei
@ 2026-06-05 8:43 ` Ren Wei
1 sibling, 0 replies; 4+ messages in thread
From: Ren Wei @ 2026-06-05 8:43 UTC (permalink / raw)
To: Viacheslav Dubeyko, ceph-devel
Cc: idryomov, amarkuze, slava, sage, Slava.Dubeyko, yuantan098,
zcliangcn, bird, ldy3087146292, n05ec
From: Douya Le <ldy3087146292@gmail.com>
The CRUSH mapper uses CRUSH_ITEM_TYPE_DEVICE to identify leaf devices in
several paths.
Replace those hardcoded checks with CRUSH_ITEM_TYPE_DEVICE so the code
uses the named device-type constant consistently.
Reviewed-by: Viacheslav Dubeyko <Slava.Dubeyko@ibm.com>
Signed-off-by: Douya Le <ldy3087146292@gmail.com>
Signed-off-by: Ren Wei <n05ec@lzu.edu.cn>
---
Changes in v5:
- add Reviewed-by from Viacheslav Dubeyko
- add a cover letter for the two-patch series
- v4 Link: https://lore.kernel.org/all/062971a5852907a5.1780473721.git.ldy3087146292@gmail.com/
---
net/ceph/crush/mapper.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/net/ceph/crush/mapper.c b/net/ceph/crush/mapper.c
index 17b041779fb9da2deb8cdbf58439392d7fa2e8ef..00e139efd54eae36f75ed7cebd79ac9b0dc27262 100644
--- a/net/ceph/crush/mapper.c
+++ b/net/ceph/crush/mapper.c
@@ -530,7 +530,7 @@ static int crush_choose_firstn(const struct crush_map *map,
if (item < 0)
itemtype = map->buckets[-1-item]->type;
else
- itemtype = 0;
+ itemtype = CRUSH_ITEM_TYPE_DEVICE;
dprintk(" item %d type %d\n", item, itemtype);
/* keep going? */
@@ -588,7 +588,7 @@ static int crush_choose_firstn(const struct crush_map *map,
if (!reject && !collide) {
/* out? */
- if (itemtype == 0)
+ if (itemtype == CRUSH_ITEM_TYPE_DEVICE)
reject = is_out(map, weight,
weight_max,
item, x);
@@ -743,7 +743,7 @@ static void crush_choose_indep(const struct crush_map *map,
if (item < 0)
itemtype = map->buckets[-1-item]->type;
else
- itemtype = 0;
+ itemtype = CRUSH_ITEM_TYPE_DEVICE;
dprintk(" item %d type %d\n", item, itemtype);
/* keep going? */
@@ -796,7 +796,7 @@ static void crush_choose_indep(const struct crush_map *map,
}
/* out? */
- if (itemtype == 0 &&
+ if (itemtype == CRUSH_ITEM_TYPE_DEVICE &&
is_out(map, weight, weight_max, item, x))
break;
--
2.47.3
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH v5 1/2] libceph: reject zero bucket types in crush_decode
2026-06-05 8:43 ` [PATCH v5 1/2] libceph: reject zero bucket types in crush_decode Ren Wei
@ 2026-06-05 19:03 ` Viacheslav Dubeyko
0 siblings, 0 replies; 4+ messages in thread
From: Viacheslav Dubeyko @ 2026-06-05 19:03 UTC (permalink / raw)
To: Ren Wei, Viacheslav Dubeyko, ceph-devel
Cc: idryomov, amarkuze, sage, Slava.Dubeyko, yuantan098, zcliangcn,
bird, ldy3087146292
On Fri, 2026-06-05 at 16:43 +0800, Ren Wei wrote:
> From: Douya Le <ldy3087146292@gmail.com>
>
> CRUSH bucket type 0 is reserved for devices. The mapper relies on
> that invariant and uses type 0 to identify leaf devices.
>
> If crush_decode() accepts a bucket with type 0, a malformed CRUSH map
> can make the mapper treat a negative bucket ID as a device and pass
> it
> to is_out(), causing an out-of-bounds access when indexing the OSD
> weight array with a negative value.
>
> Reject zero bucket types while decoding the CRUSH map so the invalid
> state never reaches the mapper.
>
> Define the reserved device type in a separate enum instead of mixing
> it
> into the bucket algorithm enum.
>
> Fixes: f24e9980eb86 ("ceph: OSD client")
> Cc: stable@vger.kernel.org
> Reported-by: Yuan Tan <yuantan098@gmail.com>
> Reported-by: Zhengchuan Liang <zcliangcn@gmail.com>
> Reported-by: Xin Liu <bird@lzu.edu.cn>
> Assisted-by: Codex:GPT-5.4
> Signed-off-by: Douya Le <ldy3087146292@gmail.com>
> Signed-off-by: Ren Wei <n05ec@lzu.edu.cn>
>
> ---
> Changes in v5:
> - add a cover letter for the two-patch series
> - define CRUSH_ITEM_TYPE_DEVICE in a separate enum as suggested
> - v4 Link:
> https://lore.kernel.org/all/8fbe4d61ba313a26.1780473720.git.ldy3087146292@gmail.com/
>
> Changes in v4:
> - define CRUSH_ITEM_TYPE_DEVICE as a standalone constant instead of
> putting it in the bucket algorithm enum
> - move the remaining type-0-to-constant cleanups into a separate
> patch
> - v3 Link:
> https://lore.kernel.org/all/d21e2f97dfe6f250.1780369814.git.ldy3087146292@gmail.com/
>
> Changes in v3:
> - use CRUSH_BUCKET_DEVICE instead of CRUSH_ITEM_TYPE_DEVICE
> - v2 Link:
> https://lore.kernel.org/all/3200151429f33554f06ced8a.1780197742.git.ldy3087146292@gmail.com/
>
> Changes in v2:
> - use CRUSH_ITEM_TYPE_DEVICE instead of hardcoded 0
> - v1 Link:
> https://lore.kernel.org/all/4ad15b49fbbae00d86dfe12348bf94d45aa60ac2.1779949116.git.ldy3087146292@gmail.com/
>
> ---
> include/linux/crush/crush.h | 6 +++++-
> net/ceph/osdmap.c | 2 ++
> 2 files changed, 7 insertions(+), 1 deletion(-)
>
> diff --git a/include/linux/crush/crush.h
> b/include/linux/crush/crush.h
> index
> 30dba392b7302de3e14861f8b769242cd8cbac9e..770b172903f3ab268226296043a
> 909861582bcb1 100644
> --- a/include/linux/crush/crush.h
> +++ b/include/linux/crush/crush.h
> @@ -110,6 +110,10 @@ struct crush_rule {
> * straw O(n) better better
> * straw2 O(n) optimal optimal
> */
> +enum {
> + CRUSH_ITEM_TYPE_DEVICE = 0,
> +};
> +
> enum {
> CRUSH_BUCKET_UNIFORM = 1,
> CRUSH_BUCKET_LIST = 2,
> @@ -130,7 +134,7 @@ extern const char *crush_bucket_alg_name(int
> alg);
>
> struct crush_bucket {
> __s32 id; /* this'll be negative */
> - __u16 type; /* non-zero; type=0 is reserved for devices
> */
> + __u16 type; /* non-zero; CRUSH_ITEM_TYPE_DEVICE is
> reserved */
> __u8 alg; /* one of CRUSH_BUCKET_* */
> __u8 hash; /* which hash function to use, CRUSH_HASH_*
> */
> __u32 weight; /* 16-bit fixed point */
> diff --git a/net/ceph/osdmap.c b/net/ceph/osdmap.c
> index
> 8b5b0587a0cfa2c437b76c8c87251199efe20291..21cdd33f2945e0c1f45277ac05f
> da373bf217586 100644
> --- a/net/ceph/osdmap.c
> +++ b/net/ceph/osdmap.c
> @@ -518,6 +518,8 @@ static struct crush_map *crush_decode(void
> *pbyval, void *end)
> ceph_decode_need(p, end, 4*sizeof(u32), bad);
> b->id = ceph_decode_32(p);
> b->type = ceph_decode_16(p);
> + if (b->type == CRUSH_ITEM_TYPE_DEVICE)
> + goto bad;
> b->alg = ceph_decode_8(p);
> if (b->alg != alg) {
> b->alg = 0;
Looks good.
Reviewed-by: Viacheslav Dubeyko <Slava.Dubeyko@ibm.com>
Thanks,
Slava.
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2026-06-05 19:03 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-06-05 8:43 [PATCH v5 0/2] libceph: reject zero bucket types and clean up type 0 uses Ren Wei
2026-06-05 8:43 ` [PATCH v5 1/2] libceph: reject zero bucket types in crush_decode Ren Wei
2026-06-05 19:03 ` Viacheslav Dubeyko
2026-06-05 8:43 ` [PATCH v5 2/2] libceph: crush: use CRUSH_ITEM_TYPE_DEVICE for leaf device checks Ren Wei
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox