Skip to content

Commit d91f305

Browse files
Waiman-LongIngo Molnar
authored andcommitted
locking/lockdep: Fix buffer overrun problem in stack_trace[]
If the lockdep code is really running out of the stack_trace entries, it is likely that buffer overrun can happen and the data immediately after stack_trace[] will be corrupted. If there is less than LOCK_TRACE_SIZE_IN_LONGS entries left before the call to save_trace(), the max_entries computation will leave it with a very large positive number because of its unsigned nature. The subsequent call to stack_trace_save() will then corrupt the data after stack_trace[]. Fix that by changing max_entries to a signed integer and check for negative value before calling stack_trace_save(). Signed-off-by: Waiman Long <[email protected]> Signed-off-by: Peter Zijlstra (Intel) <[email protected]> Reviewed-by: Bart Van Assche <[email protected]> Cc: Linus Torvalds <[email protected]> Cc: Peter Zijlstra <[email protected]> Cc: Thomas Gleixner <[email protected]> Fixes: 12593b7 ("locking/lockdep: Reduce space occupied by stack traces") Link: https://lkml.kernel.org/r/[email protected] Signed-off-by: Ingo Molnar <[email protected]>
1 parent 46cf053 commit d91f305

File tree

1 file changed

+3
-4
lines changed

1 file changed

+3
-4
lines changed

kernel/locking/lockdep.c

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -482,18 +482,16 @@ static struct lock_trace *save_trace(void)
482482
struct lock_trace *trace, *t2;
483483
struct hlist_head *hash_head;
484484
u32 hash;
485-
unsigned int max_entries;
485+
int max_entries;
486486

487487
BUILD_BUG_ON_NOT_POWER_OF_2(STACK_TRACE_HASH_SIZE);
488488
BUILD_BUG_ON(LOCK_TRACE_SIZE_IN_LONGS >= MAX_STACK_TRACE_ENTRIES);
489489

490490
trace = (struct lock_trace *)(stack_trace + nr_stack_trace_entries);
491491
max_entries = MAX_STACK_TRACE_ENTRIES - nr_stack_trace_entries -
492492
LOCK_TRACE_SIZE_IN_LONGS;
493-
trace->nr_entries = stack_trace_save(trace->entries, max_entries, 3);
494493

495-
if (nr_stack_trace_entries >= MAX_STACK_TRACE_ENTRIES -
496-
LOCK_TRACE_SIZE_IN_LONGS - 1) {
494+
if (max_entries <= 0) {
497495
if (!debug_locks_off_graph_unlock())
498496
return NULL;
499497

@@ -502,6 +500,7 @@ static struct lock_trace *save_trace(void)
502500

503501
return NULL;
504502
}
503+
trace->nr_entries = stack_trace_save(trace->entries, max_entries, 3);
505504

506505
hash = jhash(trace->entries, trace->nr_entries *
507506
sizeof(trace->entries[0]), 0);

0 commit comments

Comments
 (0)