From: salina@us.ibm.com
Subject: No lp_release_parport while write is going on
References: bnc#62947 - LTC11483
Patch-mainline: not yet

This patch was done by IBM a while back, but apparently never made it
into mainline. It fixes a problem in the lp driver that can cause oopses.

Scenario:
 process A:	calls lp_write, which in turn calls parport_ieee1284_write_compat,
 		and that invokes parport_wait_peripheral
 process B:	meanwhile does an ioctl(LPGETSTATUS), which call lp_release_parport
 		when done. This function will set physport->cad = NULL.
 process A:	parport_wait_peripheral tries to dereference physport->cad and
 		dies

The patch below simply protects that code with the port_mutex in order to
protect against simultaneous calls to lp_read/lp_write.

Similar protection is probably required for ioctl(LPRESET).

Signed-off-by: okir@suse.de

---
 drivers/char/lp.c |    3 +++
 1 file changed, 3 insertions(+)

--- a/drivers/char/lp.c
+++ b/drivers/char/lp.c
@@ -622,9 +622,12 @@ static int lp_do_ioctl(unsigned int mino
 				return -EFAULT;
 			break;
 		case LPGETSTATUS:
+			if (mutex_lock_interruptible(&lp_table[minor].port_mutex))
+				return -EINTR;
 			lp_claim_parport_or_block (&lp_table[minor]);
 			status = r_str(minor);
 			lp_release_parport (&lp_table[minor]);
+			mutex_unlock(&lp_table[minor].port_mutex);
 
 			if (copy_to_user(argp, &status, sizeof(int)))
 				return -EFAULT;
