All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v4 1/2] libceph: reject zero bucket types in crush_decode
@ 2026-06-04  3:18 Ren Wei
  2026-06-04  3:18 ` [PATCH v4 2/2] libceph: crush: use CRUSH_ITEM_TYPE_DEVICE for leaf device checks Ren Wei
  2026-06-04 19:39 ` [PATCH v4 1/2] libceph: reject zero bucket types in crush_decode Viacheslav Dubeyko
  0 siblings, 2 replies; 4+ messages in thread
From: Ren Wei @ 2026-06-04  3:18 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 as a standalone named constant 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 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 | 4 +++-
 net/ceph/osdmap.c           | 2 ++
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/include/linux/crush/crush.h b/include/linux/crush/crush.h
index 30dba392b7302de3e14861f8b769242cd8cbac9e..76bd1fa036538df86d548b1c668163035c30ade6 100644
--- a/include/linux/crush/crush.h
+++ b/include/linux/crush/crush.h
@@ -110,6 +110,8 @@ struct crush_rule {
  *  straw           O(n)       better       better
  *  straw2          O(n)       optimal      optimal
  */
+#define CRUSH_ITEM_TYPE_DEVICE 0
+
 enum {
 	CRUSH_BUCKET_UNIFORM = 1,
 	CRUSH_BUCKET_LIST = 2,
@@ -130,7 +132,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 v4 2/2] libceph: crush: use CRUSH_ITEM_TYPE_DEVICE for leaf device checks
  2026-06-04  3:18 [PATCH v4 1/2] libceph: reject zero bucket types in crush_decode Ren Wei
@ 2026-06-04  3:18 ` Ren Wei
  2026-06-04 19:43   ` Viacheslav Dubeyko
  2026-06-04 19:39 ` [PATCH v4 1/2] libceph: reject zero bucket types in crush_decode Viacheslav Dubeyko
  1 sibling, 1 reply; 4+ messages in thread
From: Ren Wei @ 2026-06-04  3:18 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 type 0 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.

Signed-off-by: Douya Le <ldy3087146292@gmail.com>
Signed-off-by: Ren Wei <n05ec@lzu.edu.cn>

---
 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 v4 1/2] libceph: reject zero bucket types in crush_decode
  2026-06-04  3:18 [PATCH v4 1/2] libceph: reject zero bucket types in crush_decode Ren Wei
  2026-06-04  3:18 ` [PATCH v4 2/2] libceph: crush: use CRUSH_ITEM_TYPE_DEVICE for leaf device checks Ren Wei
@ 2026-06-04 19:39 ` Viacheslav Dubeyko
  1 sibling, 0 replies; 4+ messages in thread
From: Viacheslav Dubeyko @ 2026-06-04 19:39 UTC (permalink / raw)
  To: Ren Wei, Viacheslav Dubeyko, ceph-devel
  Cc: idryomov, amarkuze, sage, Slava.Dubeyko, yuantan098, zcliangcn,
	bird, ldy3087146292

On Thu, 2026-06-04 at 11:18 +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 as a standalone named constant
> 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 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 | 4 +++-
>  net/ceph/osdmap.c           | 2 ++
>  2 files changed, 5 insertions(+), 1 deletion(-)
> 
> diff --git a/include/linux/crush/crush.h
> b/include/linux/crush/crush.h
> index
> 30dba392b7302de3e14861f8b769242cd8cbac9e..76bd1fa036538df86d548b1c668
> 163035c30ade6 100644
> --- a/include/linux/crush/crush.h
> +++ b/include/linux/crush/crush.h
> @@ -110,6 +110,8 @@ struct crush_rule {
>   *  straw           O(n)       better       better
>   *  straw2          O(n)       optimal      optimal
>   */
> +#define CRUSH_ITEM_TYPE_DEVICE 0

If I understood correctly, the b->type field encodes the CRUSH topology
type (host, rack, row, datacenter, etc.). So, I think to have enum will
be much better here.

Thanks,
Slava.

> +
>  enum {
>  	CRUSH_BUCKET_UNIFORM = 1,
>  	CRUSH_BUCKET_LIST = 2,
> @@ -130,7 +132,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;

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH v4 2/2] libceph: crush: use CRUSH_ITEM_TYPE_DEVICE for leaf device checks
  2026-06-04  3:18 ` [PATCH v4 2/2] libceph: crush: use CRUSH_ITEM_TYPE_DEVICE for leaf device checks Ren Wei
@ 2026-06-04 19:43   ` Viacheslav Dubeyko
  0 siblings, 0 replies; 4+ messages in thread
From: Viacheslav Dubeyko @ 2026-06-04 19:43 UTC (permalink / raw)
  To: Ren Wei, Viacheslav Dubeyko, ceph-devel
  Cc: idryomov, amarkuze, sage, Slava.Dubeyko, yuantan098, zcliangcn,
	bird, ldy3087146292

On Thu, 2026-06-04 at 11:18 +0800, Ren Wei wrote:
> From: Douya Le <ldy3087146292@gmail.com>
> 
> The CRUSH mapper uses type 0 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.

Usually, patchset requires a cover letter. The patch itself looks good.

Reviewed-by: Viacheslav Dubeyko <Slava.Dubeyko@ibm.com>

Thanks,
Slava.

> 
> Signed-off-by: Douya Le <ldy3087146292@gmail.com>
> Signed-off-by: Ren Wei <n05ec@lzu.edu.cn>
> 
> ---
>  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..00e139efd54eae36f75ed7cebd7
> 9ac9b0dc27262 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,
>  								weig
> ht_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;
>  

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2026-06-04 19:43 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-06-04  3:18 [PATCH v4 1/2] libceph: reject zero bucket types in crush_decode Ren Wei
2026-06-04  3:18 ` [PATCH v4 2/2] libceph: crush: use CRUSH_ITEM_TYPE_DEVICE for leaf device checks Ren Wei
2026-06-04 19:43   ` Viacheslav Dubeyko
2026-06-04 19:39 ` [PATCH v4 1/2] libceph: reject zero bucket types in crush_decode Viacheslav Dubeyko

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.