]>
Commit | Line | Data |
---|---|---|
2cb7cef9 BS |
1 | From: salina@us.ibm.com |
2 | Subject: No lp_release_parport while write is going on | |
3 | References: 62947 - LTC11483 | |
4 | ||
5 | This patch was done by IBM a while back, but apparently never made it | |
6 | into mainline. It fixes a problem in the lp driver that can cause oopses. | |
7 | ||
8 | Scenario: | |
9 | process A: calls lp_write, which in turn calls parport_ieee1284_write_compat, | |
10 | and that invokes parport_wait_peripheral | |
11 | process B: meanwhile does an ioctl(LPGETSTATUS), which call lp_release_parport | |
12 | when done. This function will set physport->cad = NULL. | |
13 | process A: parport_wait_peripheral tries to dereference physport->cad and | |
14 | dies | |
15 | ||
16 | The patch below simply protects that code with the port_mutex in order to | |
17 | protect against simultaneous calls to lp_read/lp_write. | |
18 | ||
19 | Similar protection is probably required for ioctl(LPRESET). | |
20 | ||
21 | Signed-off-by: okir@suse.de | |
22 | ||
23 | --- | |
24 | drivers/char/lp.c | 3 +++ | |
25 | 1 file changed, 3 insertions(+) | |
26 | ||
27 | --- a/drivers/char/lp.c | |
28 | +++ b/drivers/char/lp.c | |
29 | @@ -626,9 +626,12 @@ static int lp_ioctl(struct inode *inode, | |
30 | return -EFAULT; | |
31 | break; | |
32 | case LPGETSTATUS: | |
33 | + if (mutex_lock_interruptible(&lp_table[minor].port_mutex)) | |
34 | + return -EINTR; | |
35 | lp_claim_parport_or_block (&lp_table[minor]); | |
36 | status = r_str(minor); | |
37 | lp_release_parport (&lp_table[minor]); | |
38 | + mutex_unlock(&lp_table[minor].port_mutex); | |
39 | ||
40 | if (copy_to_user(argp, &status, sizeof(int))) | |
41 | return -EFAULT; |