Skip to content

Commit 9dfa7bb

Browse files
Michael Schmitztytso
authored andcommitted
fix race in drivers/char/random.c:get_reg()
get_reg() can be reentered on architectures with prioritized interrupts (m68k in this case), causing f->reg_index to be incremented after the range check. Out of bounds memory access past the pt_regs struct results. This will go mostly undetected unless access is beyond end of memory. Prevent the race by disabling interrupts in get_reg(). Tested on m68k (Atari Falcon, and ARAnyM emulator). Kudos to Geert Uytterhoeven for helping to trace this race. Signed-off-by: Michael Schmitz <schmitzmic@gmail.com> Signed-off-by: Theodore Ts'o <tytso@mit.edu>
1 parent 0833289 commit 9dfa7bb

File tree

1 file changed

+5
-1
lines changed

1 file changed

+5
-1
lines changed

drivers/char/random.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1097,12 +1097,16 @@ static void add_interrupt_bench(cycles_t start)
10971097
static __u32 get_reg(struct fast_pool *f, struct pt_regs *regs)
10981098
{
10991099
__u32 *ptr = (__u32 *) regs;
1100+
unsigned long flags;
11001101

11011102
if (regs == NULL)
11021103
return 0;
1104+
local_irq_save(flags);
11031105
if (f->reg_idx >= sizeof(struct pt_regs) / sizeof(__u32))
11041106
f->reg_idx = 0;
1105-
return *(ptr + f->reg_idx++);
1107+
ptr += f->reg_idx++;
1108+
local_irq_restore(flags);
1109+
return *ptr;
11061110
}
11071111

11081112
void add_interrupt_randomness(int irq, int irq_flags)

0 commit comments

Comments
 (0)