From e4dbe0ced7c80f96df7c04a73ffaa7b8a44d9518 Mon Sep 17 00:00:00 2001
From: Oscar Salvador <osalvador@suse.de>
Date: Wed, 14 Feb 2024 09:48:28 +0100
Subject: [PATCH v10 1/7] lib/stackdepot: Fix first entry having a 0-handle
References: jsc-PED#7423
Patch-mainline: v6.8-rc5
Git-commit: 3ee34eabac2abb6b1b6fcdebffe18870719ad000
The very first entry of stack_record gets a handle of 0, but this is wrong
because stackdepot treats a 0-handle as a non-valid one.
E.g: See the check in stack_depot_fetch()
Fix this by adding and offset of 1.
This bug has been lurking since the very beginning of stackdepot,
but no one really cared as it seems.
Because of that I am not adding a Fixes tag.
Co-developed-by: Marco Elver <elver@google.com>
Signed-off-by: Marco Elver <elver@google.com>
Signed-off-by: Oscar Salvador <osalvador@suse.de>
Acked-by: Vlastimil Babka <vbabka@suse.cz>
---
lib/stackdepot.c | 15 ++++++++-------
1 file changed, 8 insertions(+), 7 deletions(-)
--- a/lib/stackdepot.c
+++ b/lib/stackdepot.c
@@ -47,14 +47,14 @@
STACK_ALLOC_NULL_PROTECTION_BITS - STACK_ALLOC_OFFSET_BITS)
#define STACK_ALLOC_SLABS_CAP 8192
#define STACK_ALLOC_MAX_SLABS \
- (((1LL << (STACK_ALLOC_INDEX_BITS)) < STACK_ALLOC_SLABS_CAP) ? \
- (1LL << (STACK_ALLOC_INDEX_BITS)) : STACK_ALLOC_SLABS_CAP)
+ (((1LL << (STACK_ALLOC_INDEX_BITS)) - 1 < STACK_ALLOC_SLABS_CAP) ? \
+ (1LL << (STACK_ALLOC_INDEX_BITS)) - 1 : STACK_ALLOC_SLABS_CAP)
/* The compact structure to store the reference to stacks. */
union handle_parts {
depot_stack_handle_t handle;
struct {
- u32 slabindex : STACK_ALLOC_INDEX_BITS;
+ u32 slabindex : STACK_ALLOC_INDEX_BITS; /* slabindex is offset by 1 */
u32 offset : STACK_ALLOC_OFFSET_BITS;
u32 valid : STACK_ALLOC_NULL_PROTECTION_BITS;
};
@@ -136,7 +136,7 @@ static struct stack_record *depot_alloc_
stack->hash = hash;
stack->size = size;
- stack->handle.slabindex = depot_index;
+ stack->handle.slabindex = depot_index + 1;
stack->handle.offset = depot_offset >> STACK_ALLOC_ALIGN;
stack->handle.valid = 1;
refcount_set(&stack->count, REFCOUNT_SATURATED);
@@ -287,15 +287,16 @@ static struct stack_record *depot_fetch_
{
union handle_parts parts = { .handle = handle };
void *slab;
+ u32 slab_index_real = parts.slabindex - 1;
size_t offset = parts.offset << STACK_ALLOC_ALIGN;
struct stack_record *stack;
- if (parts.slabindex > depot_index) {
+ if (slab_index_real > depot_index) {
WARN(1, "slab index %d out of bounds (%d) for stack id %08x\n",
- parts.slabindex, depot_index, handle);
+ slab_index_real, depot_index, handle);
return NULL;
}
- slab = stack_slabs[parts.slabindex];
+ slab = stack_slabs[slab_index_real];
if (!slab)
return NULL;