From: Kenneth Sumrall In lp_write(), copy_from_user() is called to copy data into a statically allocated kernel buffer before down_interruptible() is called. If a second thread of execution comes in between the copy_from_user() and the down_interruptible() calls, silent data corruption could result. Signed-off-by: Andrew Morton --- 25-akpm/drivers/char/lp.c | 10 ++++++---- 1 files changed, 6 insertions(+), 4 deletions(-) diff -puN drivers/char/lp.c~drivers-char-lpc-race-fix drivers/char/lp.c --- 25/drivers/char/lp.c~drivers-char-lpc-race-fix 2005-02-08 20:51:24.000000000 -0800 +++ 25-akpm/drivers/char/lp.c 2005-02-08 20:52:03.000000000 -0800 @@ -314,12 +314,14 @@ static ssize_t lp_write(struct file * fi if (copy_size > LP_BUFFER_SIZE) copy_size = LP_BUFFER_SIZE; - if (copy_from_user (kbuf, buf, copy_size)) - return -EFAULT; - if (down_interruptible (&lp_table[minor].port_mutex)) return -EINTR; + if (copy_from_user (kbuf, buf, copy_size)) { + retv = -EFAULT; + goto out_unlock; + } + /* Claim Parport or sleep until it becomes available */ lp_claim_parport_or_block (&lp_table[minor]); @@ -398,7 +400,7 @@ static ssize_t lp_write(struct file * fi lp_table[minor].current_mode = IEEE1284_MODE_COMPAT; lp_release_parport (&lp_table[minor]); } - +out_unlock: up (&lp_table[minor].port_mutex); return retv; _