diff options
author | Jiri Slaby <jslaby@suse.cz> | 2011-02-28 04:34:05 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2011-02-28 22:24:54 -0500 |
commit | f7d7aedfcd4e20e7dfc7356d30cc22dc0b0f493e (patch) | |
tree | 69b2b977e5900de9e5a5a2b934ecadc7b0ccbf33 /drivers/usb/serial/keyspan_pda.c | |
parent | 7adc14b14b43b6ca9f2f00ac7a4780577dbe883b (diff) |
USB: serial/keyspan_pda, fix potential tty NULL dereferences
Make sure that we check the return value of tty_port_tty_get.
Sometimes it may return NULL and we later dereference that.
There are several places to check. For easier handling,
tty_port_tty_get is moved directly to the palce where needed in
keyspan_pda_rx_interrupt.
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Cc: Alan Cox <alan@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/serial/keyspan_pda.c')
-rw-r--r-- | drivers/usb/serial/keyspan_pda.c | 15 |
1 files changed, 8 insertions, 7 deletions
diff --git a/drivers/usb/serial/keyspan_pda.c b/drivers/usb/serial/keyspan_pda.c index 554a8693a463..7b690f3282a2 100644 --- a/drivers/usb/serial/keyspan_pda.c +++ b/drivers/usb/serial/keyspan_pda.c | |||
@@ -173,7 +173,8 @@ static void keyspan_pda_wakeup_write(struct work_struct *work) | |||
173 | container_of(work, struct keyspan_pda_private, wakeup_work); | 173 | container_of(work, struct keyspan_pda_private, wakeup_work); |
174 | struct usb_serial_port *port = priv->port; | 174 | struct usb_serial_port *port = priv->port; |
175 | struct tty_struct *tty = tty_port_tty_get(&port->port); | 175 | struct tty_struct *tty = tty_port_tty_get(&port->port); |
176 | tty_wakeup(tty); | 176 | if (tty) |
177 | tty_wakeup(tty); | ||
177 | tty_kref_put(tty); | 178 | tty_kref_put(tty); |
178 | } | 179 | } |
179 | 180 | ||
@@ -206,7 +207,7 @@ static void keyspan_pda_request_unthrottle(struct work_struct *work) | |||
206 | static void keyspan_pda_rx_interrupt(struct urb *urb) | 207 | static void keyspan_pda_rx_interrupt(struct urb *urb) |
207 | { | 208 | { |
208 | struct usb_serial_port *port = urb->context; | 209 | struct usb_serial_port *port = urb->context; |
209 | struct tty_struct *tty = tty_port_tty_get(&port->port); | 210 | struct tty_struct *tty; |
210 | unsigned char *data = urb->transfer_buffer; | 211 | unsigned char *data = urb->transfer_buffer; |
211 | int retval; | 212 | int retval; |
212 | int status = urb->status; | 213 | int status = urb->status; |
@@ -223,7 +224,7 @@ static void keyspan_pda_rx_interrupt(struct urb *urb) | |||
223 | /* this urb is terminated, clean up */ | 224 | /* this urb is terminated, clean up */ |
224 | dbg("%s - urb shutting down with status: %d", | 225 | dbg("%s - urb shutting down with status: %d", |
225 | __func__, status); | 226 | __func__, status); |
226 | goto out; | 227 | return; |
227 | default: | 228 | default: |
228 | dbg("%s - nonzero urb status received: %d", | 229 | dbg("%s - nonzero urb status received: %d", |
229 | __func__, status); | 230 | __func__, status); |
@@ -233,12 +234,14 @@ static void keyspan_pda_rx_interrupt(struct urb *urb) | |||
233 | /* see if the message is data or a status interrupt */ | 234 | /* see if the message is data or a status interrupt */ |
234 | switch (data[0]) { | 235 | switch (data[0]) { |
235 | case 0: | 236 | case 0: |
236 | /* rest of message is rx data */ | 237 | tty = tty_port_tty_get(&port->port); |
237 | if (urb->actual_length) { | 238 | /* rest of message is rx data */ |
239 | if (tty && urb->actual_length) { | ||
238 | tty_insert_flip_string(tty, data + 1, | 240 | tty_insert_flip_string(tty, data + 1, |
239 | urb->actual_length - 1); | 241 | urb->actual_length - 1); |
240 | tty_flip_buffer_push(tty); | 242 | tty_flip_buffer_push(tty); |
241 | } | 243 | } |
244 | tty_kref_put(tty); | ||
242 | break; | 245 | break; |
243 | case 1: | 246 | case 1: |
244 | /* status interrupt */ | 247 | /* status interrupt */ |
@@ -265,8 +268,6 @@ exit: | |||
265 | dev_err(&port->dev, | 268 | dev_err(&port->dev, |
266 | "%s - usb_submit_urb failed with result %d", | 269 | "%s - usb_submit_urb failed with result %d", |
267 | __func__, retval); | 270 | __func__, retval); |
268 | out: | ||
269 | tty_kref_put(tty); | ||
270 | } | 271 | } |
271 | 272 | ||
272 | 273 | ||