diff options
author | Lennert Buytenhek <buytenh@wantstofly.org> | 2005-11-07 16:12:07 -0500 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2005-11-07 16:12:07 -0500 |
commit | 06c03cac9487555478c7d80065ebf7818bf6fd06 (patch) | |
tree | 1a03ff9ae347f40c11d0e3eee790a1b88ff29cc1 | |
parent | 862184fe013146a0d9654a5598c5a2691747541c (diff) |
[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>
-rw-r--r-- | arch/arm/nwfpe/fpopcode.c | 16 | ||||
-rw-r--r-- | arch/arm/nwfpe/softfloat-specialize | 1 | ||||
-rw-r--r-- | arch/arm/nwfpe/softfloat.c | 6 | ||||
-rw-r--r-- | arch/arm/nwfpe/softfloat.h | 1 |
4 files changed, 16 insertions, 8 deletions
diff --git a/arch/arm/nwfpe/fpopcode.c b/arch/arm/nwfpe/fpopcode.c index 4c9f5703148c..67ff2ab08ea0 100644 --- a/arch/arm/nwfpe/fpopcode.c +++ b/arch/arm/nwfpe/fpopcode.c | |||
@@ -29,14 +29,14 @@ | |||
29 | 29 | ||
30 | #ifdef CONFIG_FPE_NWFPE_XP | 30 | #ifdef CONFIG_FPE_NWFPE_XP |
31 | const floatx80 floatx80Constant[] = { | 31 | const floatx80 floatx80Constant[] = { |
32 | {0x0000, 0x0000000000000000ULL}, /* extended 0.0 */ | 32 | { .high = 0x0000, .low = 0x0000000000000000ULL},/* extended 0.0 */ |
33 | {0x3fff, 0x8000000000000000ULL}, /* extended 1.0 */ | 33 | { .high = 0x3fff, .low = 0x8000000000000000ULL},/* extended 1.0 */ |
34 | {0x4000, 0x8000000000000000ULL}, /* extended 2.0 */ | 34 | { .high = 0x4000, .low = 0x8000000000000000ULL},/* extended 2.0 */ |
35 | {0x4000, 0xc000000000000000ULL}, /* extended 3.0 */ | 35 | { .high = 0x4000, .low = 0xc000000000000000ULL},/* extended 3.0 */ |
36 | {0x4001, 0x8000000000000000ULL}, /* extended 4.0 */ | 36 | { .high = 0x4001, .low = 0x8000000000000000ULL},/* extended 4.0 */ |
37 | {0x4001, 0xa000000000000000ULL}, /* extended 5.0 */ | 37 | { .high = 0x4001, .low = 0xa000000000000000ULL},/* extended 5.0 */ |
38 | {0x3ffe, 0x8000000000000000ULL}, /* extended 0.5 */ | 38 | { .high = 0x3ffe, .low = 0x8000000000000000ULL},/* extended 0.5 */ |
39 | {0x4002, 0xa000000000000000ULL} /* extended 10.0 */ | 39 | { .high = 0x4002, .low = 0xa000000000000000ULL},/* extended 10.0 */ |
40 | }; | 40 | }; |
41 | #endif | 41 | #endif |
42 | 42 | ||
diff --git a/arch/arm/nwfpe/softfloat-specialize b/arch/arm/nwfpe/softfloat-specialize index acf409144763..d4a4c8e06635 100644 --- a/arch/arm/nwfpe/softfloat-specialize +++ b/arch/arm/nwfpe/softfloat-specialize | |||
@@ -332,6 +332,7 @@ static floatx80 commonNaNToFloatx80( commonNaNT a ) | |||
332 | 332 | ||
333 | z.low = LIT64( 0xC000000000000000 ) | ( a.high>>1 ); | 333 | z.low = LIT64( 0xC000000000000000 ) | ( a.high>>1 ); |
334 | z.high = ( ( (bits16) a.sign )<<15 ) | 0x7FFF; | 334 | z.high = ( ( (bits16) a.sign )<<15 ) | 0x7FFF; |
335 | z.__padding = 0; | ||
335 | return z; | 336 | return z; |
336 | 337 | ||
337 | } | 338 | } |
diff --git a/arch/arm/nwfpe/softfloat.c b/arch/arm/nwfpe/softfloat.c index f9f049132a17..0f9656e482ba 100644 --- a/arch/arm/nwfpe/softfloat.c +++ b/arch/arm/nwfpe/softfloat.c | |||
@@ -531,6 +531,7 @@ INLINE floatx80 packFloatx80( flag zSign, int32 zExp, bits64 zSig ) | |||
531 | 531 | ||
532 | z.low = zSig; | 532 | z.low = zSig; |
533 | z.high = ( ( (bits16) zSign )<<15 ) + zExp; | 533 | z.high = ( ( (bits16) zSign )<<15 ) + zExp; |
534 | z.__padding = 0; | ||
534 | return z; | 535 | return z; |
535 | 536 | ||
536 | } | 537 | } |
@@ -2831,6 +2832,7 @@ static floatx80 subFloatx80Sigs( struct roundingData *roundData, floatx80 a, flo | |||
2831 | roundData->exception |= float_flag_invalid; | 2832 | roundData->exception |= float_flag_invalid; |
2832 | z.low = floatx80_default_nan_low; | 2833 | z.low = floatx80_default_nan_low; |
2833 | z.high = floatx80_default_nan_high; | 2834 | z.high = floatx80_default_nan_high; |
2835 | z.__padding = 0; | ||
2834 | return z; | 2836 | return z; |
2835 | } | 2837 | } |
2836 | if ( aExp == 0 ) { | 2838 | if ( aExp == 0 ) { |
@@ -2950,6 +2952,7 @@ floatx80 floatx80_mul( struct roundingData *roundData, floatx80 a, floatx80 b ) | |||
2950 | roundData->exception |= float_flag_invalid; | 2952 | roundData->exception |= float_flag_invalid; |
2951 | z.low = floatx80_default_nan_low; | 2953 | z.low = floatx80_default_nan_low; |
2952 | z.high = floatx80_default_nan_high; | 2954 | z.high = floatx80_default_nan_high; |
2955 | z.__padding = 0; | ||
2953 | return z; | 2956 | return z; |
2954 | } | 2957 | } |
2955 | return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) ); | 2958 | return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) ); |
@@ -3015,6 +3018,7 @@ floatx80 floatx80_div( struct roundingData *roundData, floatx80 a, floatx80 b ) | |||
3015 | roundData->exception |= float_flag_invalid; | 3018 | roundData->exception |= float_flag_invalid; |
3016 | z.low = floatx80_default_nan_low; | 3019 | z.low = floatx80_default_nan_low; |
3017 | z.high = floatx80_default_nan_high; | 3020 | z.high = floatx80_default_nan_high; |
3021 | z.__padding = 0; | ||
3018 | return z; | 3022 | return z; |
3019 | } | 3023 | } |
3020 | roundData->exception |= float_flag_divbyzero; | 3024 | roundData->exception |= float_flag_divbyzero; |
@@ -3093,6 +3097,7 @@ floatx80 floatx80_rem( struct roundingData *roundData, floatx80 a, floatx80 b ) | |||
3093 | roundData->exception |= float_flag_invalid; | 3097 | roundData->exception |= float_flag_invalid; |
3094 | z.low = floatx80_default_nan_low; | 3098 | z.low = floatx80_default_nan_low; |
3095 | z.high = floatx80_default_nan_high; | 3099 | z.high = floatx80_default_nan_high; |
3100 | z.__padding = 0; | ||
3096 | return z; | 3101 | return z; |
3097 | } | 3102 | } |
3098 | normalizeFloatx80Subnormal( bSig, &bExp, &bSig ); | 3103 | normalizeFloatx80Subnormal( bSig, &bExp, &bSig ); |
@@ -3184,6 +3189,7 @@ floatx80 floatx80_sqrt( struct roundingData *roundData, floatx80 a ) | |||
3184 | roundData->exception |= float_flag_invalid; | 3189 | roundData->exception |= float_flag_invalid; |
3185 | z.low = floatx80_default_nan_low; | 3190 | z.low = floatx80_default_nan_low; |
3186 | z.high = floatx80_default_nan_high; | 3191 | z.high = floatx80_default_nan_high; |
3192 | z.__padding = 0; | ||
3187 | return z; | 3193 | return z; |
3188 | } | 3194 | } |
3189 | if ( aExp == 0 ) { | 3195 | if ( aExp == 0 ) { |
diff --git a/arch/arm/nwfpe/softfloat.h b/arch/arm/nwfpe/softfloat.h index 14151700b6b2..1301d97e037f 100644 --- a/arch/arm/nwfpe/softfloat.h +++ b/arch/arm/nwfpe/softfloat.h | |||
@@ -55,6 +55,7 @@ typedef unsigned long int float32; | |||
55 | typedef unsigned long long float64; | 55 | typedef unsigned long long float64; |
56 | typedef struct { | 56 | typedef struct { |
57 | unsigned short high; | 57 | unsigned short high; |
58 | unsigned short __padding; | ||
58 | unsigned long long low; | 59 | unsigned long long low; |
59 | } floatx80; | 60 | } floatx80; |
60 | 61 | ||