Skip to content

Commit abf492e

Browse files
jhovoldgregkh
authored andcommitted
USB: kl5kusb105: fix DMA buffers on stack
Cc: Oliver Neukum <[email protected]> Signed-off-by: Johan Hovold <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent ca65d25 commit abf492e

File tree

1 file changed

+45
-18
lines changed

1 file changed

+45
-18
lines changed

drivers/usb/serial/kl5kusb105.c

Lines changed: 45 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -212,10 +212,19 @@ static int klsi_105_get_line_state(struct usb_serial_port *port,
212212
unsigned long *line_state_p)
213213
{
214214
int rc;
215-
__u8 status_buf[KLSI_STATUSBUF_LEN] = { -1, -1};
215+
u8 *status_buf;
216216
__u16 status;
217217

218218
dev_info(&port->serial->dev->dev, "sending SIO Poll request\n");
219+
220+
status_buf = kmalloc(KLSI_STATUSBUF_LEN, GFP_KERNEL);
221+
if (!status_buf) {
222+
dev_err(&port->dev, "%s - out of memory for status buffer.\n",
223+
__func__);
224+
return -ENOMEM;
225+
}
226+
status_buf[0] = 0xff;
227+
status_buf[1] = 0xff;
219228
rc = usb_control_msg(port->serial->dev,
220229
usb_rcvctrlpipe(port->serial->dev, 0),
221230
KL5KUSB105A_SIO_POLL,
@@ -236,6 +245,8 @@ static int klsi_105_get_line_state(struct usb_serial_port *port,
236245

237246
*line_state_p = klsi_105_status2linestate(status);
238247
}
248+
249+
kfree(status_buf);
239250
return rc;
240251
}
241252

@@ -364,7 +375,7 @@ static int klsi_105_open(struct tty_struct *tty, struct usb_serial_port *port)
364375
int rc;
365376
int i;
366377
unsigned long line_state;
367-
struct klsi_105_port_settings cfg;
378+
struct klsi_105_port_settings *cfg;
368379
unsigned long flags;
369380

370381
dbg("%s port %d", __func__, port->number);
@@ -376,12 +387,18 @@ static int klsi_105_open(struct tty_struct *tty, struct usb_serial_port *port)
376387
* Then read the modem line control and store values in
377388
* priv->line_state.
378389
*/
379-
cfg.pktlen = 5;
380-
cfg.baudrate = kl5kusb105a_sio_b9600;
381-
cfg.databits = kl5kusb105a_dtb_8;
382-
cfg.unknown1 = 0;
383-
cfg.unknown2 = 1;
384-
klsi_105_chg_port_settings(port, &cfg);
390+
cfg = kmalloc(sizeof(*cfg), GFP_KERNEL);
391+
if (!cfg) {
392+
dev_err(&port->dev, "%s - out of memory for config buffer.\n",
393+
__func__);
394+
return -ENOMEM;
395+
}
396+
cfg->pktlen = 5;
397+
cfg->baudrate = kl5kusb105a_sio_b9600;
398+
cfg->databits = kl5kusb105a_dtb_8;
399+
cfg->unknown1 = 0;
400+
cfg->unknown2 = 1;
401+
klsi_105_chg_port_settings(port, cfg);
385402

386403
/* set up termios structure */
387404
spin_lock_irqsave(&priv->lock, flags);
@@ -391,11 +408,11 @@ static int klsi_105_open(struct tty_struct *tty, struct usb_serial_port *port)
391408
priv->termios.c_lflag = tty->termios->c_lflag;
392409
for (i = 0; i < NCCS; i++)
393410
priv->termios.c_cc[i] = tty->termios->c_cc[i];
394-
priv->cfg.pktlen = cfg.pktlen;
395-
priv->cfg.baudrate = cfg.baudrate;
396-
priv->cfg.databits = cfg.databits;
397-
priv->cfg.unknown1 = cfg.unknown1;
398-
priv->cfg.unknown2 = cfg.unknown2;
411+
priv->cfg.pktlen = cfg->pktlen;
412+
priv->cfg.baudrate = cfg->baudrate;
413+
priv->cfg.databits = cfg->databits;
414+
priv->cfg.unknown1 = cfg->unknown1;
415+
priv->cfg.unknown2 = cfg->unknown2;
399416
spin_unlock_irqrestore(&priv->lock, flags);
400417

401418
/* READ_ON and urb submission */
@@ -441,6 +458,7 @@ static int klsi_105_open(struct tty_struct *tty, struct usb_serial_port *port)
441458
retval = rc;
442459

443460
exit:
461+
kfree(cfg);
444462
return retval;
445463
} /* klsi_105_open */
446464

@@ -714,10 +732,17 @@ static void klsi_105_set_termios(struct tty_struct *tty,
714732
unsigned int old_iflag = old_termios->c_iflag;
715733
unsigned int cflag = tty->termios->c_cflag;
716734
unsigned int old_cflag = old_termios->c_cflag;
717-
struct klsi_105_port_settings cfg;
735+
struct klsi_105_port_settings *cfg;
718736
unsigned long flags;
719737
speed_t baud;
720738

739+
cfg = kmalloc(sizeof(*cfg), GFP_KERNEL);
740+
if (!cfg) {
741+
dev_err(&port->dev, "%s - out of memory for config buffer.\n",
742+
__func__);
743+
return;
744+
}
745+
721746
/* lock while we are modifying the settings */
722747
spin_lock_irqsave(&priv->lock, flags);
723748

@@ -793,11 +818,11 @@ static void klsi_105_set_termios(struct tty_struct *tty,
793818
case CS5:
794819
dbg("%s - 5 bits/byte not supported", __func__);
795820
spin_unlock_irqrestore(&priv->lock, flags);
796-
return ;
821+
goto err;
797822
case CS6:
798823
dbg("%s - 6 bits/byte not supported", __func__);
799824
spin_unlock_irqrestore(&priv->lock, flags);
800-
return ;
825+
goto err;
801826
case CS7:
802827
priv->cfg.databits = kl5kusb105a_dtb_7;
803828
break;
@@ -856,11 +881,13 @@ static void klsi_105_set_termios(struct tty_struct *tty,
856881
#endif
857882
;
858883
}
859-
memcpy(&cfg, &priv->cfg, sizeof(cfg));
884+
memcpy(cfg, &priv->cfg, sizeof(*cfg));
860885
spin_unlock_irqrestore(&priv->lock, flags);
861886

862887
/* now commit changes to device */
863-
klsi_105_chg_port_settings(port, &cfg);
888+
klsi_105_chg_port_settings(port, cfg);
889+
err:
890+
kfree(cfg);
864891
} /* klsi_105_set_termios */
865892

866893

0 commit comments

Comments
 (0)