[JFFS2] fix race condition in jffs2_lzo_compress()

deflate_mutex protects the globals lzo_mem and lzo_compress_buf. However,
jffs2_lzo_compress() unlocks deflate_mutex _before_ it has copied out the
compressed data from lzo_compress_buf. Correct this by moving the mutex
unlock after the copy.

In addition, document what deflate_mutex actually protects.

Cc: stable@kernel.org
Signed-off-by: Geert Uytterhoeven <Geert.Uytterhoeven@sonycom.com>
Acked-by: Richard Purdie <rpurdie@openedhand.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>

authored by Geert Uytterhoeven and committed by David Woodhouse dc8a0843 467622ef

+9 -6
+9 -6
fs/jffs2/compr_lzo.c
··· 19 20 static void *lzo_mem; 21 static void *lzo_compress_buf; 22 - static DEFINE_MUTEX(deflate_mutex); 23 24 static void free_workspace(void) 25 { ··· 49 50 mutex_lock(&deflate_mutex); 51 ret = lzo1x_1_compress(data_in, *sourcelen, lzo_compress_buf, &compress_size, lzo_mem); 52 - mutex_unlock(&deflate_mutex); 53 - 54 if (ret != LZO_E_OK) 55 - return -1; 56 57 if (compress_size > *dstlen) 58 - return -1; 59 60 memcpy(cpage_out, lzo_compress_buf, compress_size); 61 - *dstlen = compress_size; 62 63 return 0; 64 } 65 66 static int jffs2_lzo_decompress(unsigned char *data_in, unsigned char *cpage_out,
··· 19 20 static void *lzo_mem; 21 static void *lzo_compress_buf; 22 + static DEFINE_MUTEX(deflate_mutex); /* for lzo_mem and lzo_compress_buf */ 23 24 static void free_workspace(void) 25 { ··· 49 50 mutex_lock(&deflate_mutex); 51 ret = lzo1x_1_compress(data_in, *sourcelen, lzo_compress_buf, &compress_size, lzo_mem); 52 if (ret != LZO_E_OK) 53 + goto fail; 54 55 if (compress_size > *dstlen) 56 + goto fail; 57 58 memcpy(cpage_out, lzo_compress_buf, compress_size); 59 + mutex_unlock(&deflate_mutex); 60 61 + *dstlen = compress_size; 62 return 0; 63 + 64 + fail: 65 + mutex_unlock(&deflate_mutex); 66 + return -1; 67 } 68 69 static int jffs2_lzo_decompress(unsigned char *data_in, unsigned char *cpage_out,