[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>
diff --git a/arch/arm/nwfpe/fpopcode.c b/arch/arm/nwfpe/fpopcode.c
index 4c9f570..67ff2ab 100644
--- a/arch/arm/nwfpe/fpopcode.c
+++ b/arch/arm/nwfpe/fpopcode.c
@@ -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
 
diff --git a/arch/arm/nwfpe/softfloat-specialize b/arch/arm/nwfpe/softfloat-specialize
index acf4091..d4a4c8e 100644
--- a/arch/arm/nwfpe/softfloat-specialize
+++ b/arch/arm/nwfpe/softfloat-specialize
@@ -332,6 +332,7 @@
 
     z.low = LIT64( 0xC000000000000000 ) | ( a.high>>1 );
     z.high = ( ( (bits16) a.sign )<<15 ) | 0x7FFF;
+    z.__padding = 0;
     return z;
 
 }
diff --git a/arch/arm/nwfpe/softfloat.c b/arch/arm/nwfpe/softfloat.c
index f9f0491..0f9656e 100644
--- a/arch/arm/nwfpe/softfloat.c
+++ b/arch/arm/nwfpe/softfloat.c
@@ -531,6 +531,7 @@
 
     z.low = zSig;
     z.high = ( ( (bits16) zSign )<<15 ) + zExp;
+    z.__padding = 0;
     return z;
 
 }
@@ -2831,6 +2832,7 @@
         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 @@
             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 @@
                 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 @@
             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 @@
         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 ) {
diff --git a/arch/arm/nwfpe/softfloat.h b/arch/arm/nwfpe/softfloat.h
index 1415170..1301d97 100644
--- a/arch/arm/nwfpe/softfloat.h
+++ b/arch/arm/nwfpe/softfloat.h
@@ -55,6 +55,7 @@
 typedef unsigned long long float64;
 typedef struct {
     unsigned short high;
+    unsigned short __padding;
     unsigned long long low;
 } floatx80;