Commit 54f1a7a7 authored by ken@mvista.com's avatar ken@mvista.com Committed by Linus Torvalds

[PATCH] drivers/char/lp.c race fix

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: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 4c6672c1
...@@ -314,12 +314,14 @@ static ssize_t lp_write(struct file * file, const char __user * buf, ...@@ -314,12 +314,14 @@ static ssize_t lp_write(struct file * file, const char __user * buf,
if (copy_size > LP_BUFFER_SIZE) if (copy_size > LP_BUFFER_SIZE)
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)) if (down_interruptible (&lp_table[minor].port_mutex))
return -EINTR; return -EINTR;
if (copy_from_user (kbuf, buf, copy_size)) {
retv = -EFAULT;
goto out_unlock;
}
/* Claim Parport or sleep until it becomes available /* Claim Parport or sleep until it becomes available
*/ */
lp_claim_parport_or_block (&lp_table[minor]); lp_claim_parport_or_block (&lp_table[minor]);
...@@ -398,7 +400,7 @@ static ssize_t lp_write(struct file * file, const char __user * buf, ...@@ -398,7 +400,7 @@ static ssize_t lp_write(struct file * file, const char __user * buf,
lp_table[minor].current_mode = IEEE1284_MODE_COMPAT; lp_table[minor].current_mode = IEEE1284_MODE_COMPAT;
lp_release_parport (&lp_table[minor]); lp_release_parport (&lp_table[minor]);
} }
out_unlock:
up (&lp_table[minor].port_mutex); up (&lp_table[minor].port_mutex);
return retv; return retv;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment