mirror of
https://github.com/torvalds/linux.git
synced 2024-11-26 22:21:42 +00:00
[ARM] 3117/1: nwfpe kernel memory info leak
Patch from Lennert Buytenhek The routine that nwfpe uses for converting floats/doubles to extended precision fails to zero two bytes of kernel stack. This is not immediately obvious, as the floatx80 structure has 16 bits of implicit padding (by design.) These two bytes are copied to userspace when an stfe is emulated, causing a possible info leak. Make the padding explicit and zero it out in the relevant places. Signed-off-by: Lennert Buytenhek <buytenh@wantstofly.org> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
This commit is contained in:
parent
862184fe01
commit
06c03cac94
@ -29,14 +29,14 @@
|
||||
|
||||
#ifdef CONFIG_FPE_NWFPE_XP
|
||||
const floatx80 floatx80Constant[] = {
|
||||
{0x0000, 0x0000000000000000ULL}, /* extended 0.0 */
|
||||
{0x3fff, 0x8000000000000000ULL}, /* extended 1.0 */
|
||||
{0x4000, 0x8000000000000000ULL}, /* extended 2.0 */
|
||||
{0x4000, 0xc000000000000000ULL}, /* extended 3.0 */
|
||||
{0x4001, 0x8000000000000000ULL}, /* extended 4.0 */
|
||||
{0x4001, 0xa000000000000000ULL}, /* extended 5.0 */
|
||||
{0x3ffe, 0x8000000000000000ULL}, /* extended 0.5 */
|
||||
{0x4002, 0xa000000000000000ULL} /* extended 10.0 */
|
||||
{ .high = 0x0000, .low = 0x0000000000000000ULL},/* extended 0.0 */
|
||||
{ .high = 0x3fff, .low = 0x8000000000000000ULL},/* extended 1.0 */
|
||||
{ .high = 0x4000, .low = 0x8000000000000000ULL},/* extended 2.0 */
|
||||
{ .high = 0x4000, .low = 0xc000000000000000ULL},/* extended 3.0 */
|
||||
{ .high = 0x4001, .low = 0x8000000000000000ULL},/* extended 4.0 */
|
||||
{ .high = 0x4001, .low = 0xa000000000000000ULL},/* extended 5.0 */
|
||||
{ .high = 0x3ffe, .low = 0x8000000000000000ULL},/* extended 0.5 */
|
||||
{ .high = 0x4002, .low = 0xa000000000000000ULL},/* extended 10.0 */
|
||||
};
|
||||
#endif
|
||||
|
||||
|
@ -332,6 +332,7 @@ static floatx80 commonNaNToFloatx80( commonNaNT a )
|
||||
|
||||
z.low = LIT64( 0xC000000000000000 ) | ( a.high>>1 );
|
||||
z.high = ( ( (bits16) a.sign )<<15 ) | 0x7FFF;
|
||||
z.__padding = 0;
|
||||
return z;
|
||||
|
||||
}
|
||||
|
@ -531,6 +531,7 @@ INLINE floatx80 packFloatx80( flag zSign, int32 zExp, bits64 zSig )
|
||||
|
||||
z.low = zSig;
|
||||
z.high = ( ( (bits16) zSign )<<15 ) + zExp;
|
||||
z.__padding = 0;
|
||||
return z;
|
||||
|
||||
}
|
||||
@ -2831,6 +2832,7 @@ static floatx80 subFloatx80Sigs( struct roundingData *roundData, floatx80 a, flo
|
||||
roundData->exception |= float_flag_invalid;
|
||||
z.low = floatx80_default_nan_low;
|
||||
z.high = floatx80_default_nan_high;
|
||||
z.__padding = 0;
|
||||
return z;
|
||||
}
|
||||
if ( aExp == 0 ) {
|
||||
@ -2950,6 +2952,7 @@ floatx80 floatx80_mul( struct roundingData *roundData, floatx80 a, floatx80 b )
|
||||
roundData->exception |= float_flag_invalid;
|
||||
z.low = floatx80_default_nan_low;
|
||||
z.high = floatx80_default_nan_high;
|
||||
z.__padding = 0;
|
||||
return z;
|
||||
}
|
||||
return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
|
||||
@ -3015,6 +3018,7 @@ floatx80 floatx80_div( struct roundingData *roundData, floatx80 a, floatx80 b )
|
||||
roundData->exception |= float_flag_invalid;
|
||||
z.low = floatx80_default_nan_low;
|
||||
z.high = floatx80_default_nan_high;
|
||||
z.__padding = 0;
|
||||
return z;
|
||||
}
|
||||
roundData->exception |= float_flag_divbyzero;
|
||||
@ -3093,6 +3097,7 @@ floatx80 floatx80_rem( struct roundingData *roundData, floatx80 a, floatx80 b )
|
||||
roundData->exception |= float_flag_invalid;
|
||||
z.low = floatx80_default_nan_low;
|
||||
z.high = floatx80_default_nan_high;
|
||||
z.__padding = 0;
|
||||
return z;
|
||||
}
|
||||
normalizeFloatx80Subnormal( bSig, &bExp, &bSig );
|
||||
@ -3184,6 +3189,7 @@ floatx80 floatx80_sqrt( struct roundingData *roundData, floatx80 a )
|
||||
roundData->exception |= float_flag_invalid;
|
||||
z.low = floatx80_default_nan_low;
|
||||
z.high = floatx80_default_nan_high;
|
||||
z.__padding = 0;
|
||||
return z;
|
||||
}
|
||||
if ( aExp == 0 ) {
|
||||
|
@ -55,6 +55,7 @@ typedef unsigned long int float32;
|
||||
typedef unsigned long long float64;
|
||||
typedef struct {
|
||||
unsigned short high;
|
||||
unsigned short __padding;
|
||||
unsigned long long low;
|
||||
} floatx80;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user