linux
Memory access beyond buffer limits
In the second iteration of the while loop, when i==8, the memory being accessed buf+64/sizeof(__u64) is out of the bounds of the buf array.
Bug fixed by commit c708c57e247
| Type | OutOfBoundsRead |
| Config | "S390 && S390_PRNG" (2nd degree) |
| C-features | PointerArithmetic |
| Fix-in | code |
| Location | arch/s390/crypto |
typedef unsigned long __u64;
#ifdef CONFIG_S390_PRNG
static unsigned char parm_block[32] = {
0x0F,0x2B,0x8E,0x63,0x8C,0x8E,0xD2,0x52,0x64,0xB7,0xA0,0x7B,0x75,0x28,0xB8,0xF4,
0x75,0x5F,0xD2,0xA6,0x8D,0x97,0x11,0xFF,0x49,0xD8,0x23,0xF3,0x7E,0x21,0xEC,0xA0,
};
void prng_seed(int nbytes)
{
char buf[16] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
int i = 0;
if (nbytes > 16)
return;
while (nbytes >= 8) {
*((__u64 *)parm_block) ^= *((__u64 *)buf+i*8); // ERROR
i += 8;
nbytes -= 8;
}
}
#endif
int main(int argc, char *argv[])
{
#ifdef CONFIG_S390_PRNG
prng_seed(16);
#endif
return 0;
}
diff --git a/simple/c708c57.c b/simple/c708c57.c
--- a/simple/c708c57.c
+++ b/simple/c708c57.c
@@ -16,7 +16,7 @@
return;
while (nbytes >= 8) {
- *((__u64 *)parm_block) ^= *((__u64 *)buf+i*8); // ERROR
+ *((__u64 *)parm_block) ^= *((__u64 *)buf+i); // ERROR
i += 8;
nbytes -= 8;
}
typedef unsigned long __u64;
#ifdef CONFIG_S390_PRNG
static unsigned char parm_block[32] = {
0x0F,0x2B,0x8E,0x63,0x8C,0x8E,0xD2,0x52,0x64,0xB7,0xA0,0x7B,0x75,0x28,0xB8,0xF4,
0x75,0x5F,0xD2,0xA6,0x8D,0x97,0x11,0xFF,0x49,0xD8,0x23,0xF3,0x7E,0x21,0xEC,0xA0,
};
#endif
int main(int argc, char *argv[])
{
#ifdef CONFIG_S390_PRNG
// prng_seed(16);
char buf[16] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
int i = 0;
if (nbytes > 16)
return;
while (nbytes >= 8) {
*((__u64 *)parm_block) ^= *((__u64 *)buf+i*8); // ERROR
i += 8;
nbytes -= 8;
}
#endif
return 0;
}
. call arch/s390/crypto/prng.c:164:prng_init() . 187: prng_seed(16); .. call arch/s390/crypto/prng.c:69:prng_seed() .. ERROR 79: *((__u64 *)parm_block) ^= *((__u64 *)buf+i*8);