Commit 528ce3c0 authored by Dave Jones's avatar Dave Jones Committed by Jeff Garzik

[PATCH] check copy_from_user return codes in serial drivers.

forward-ported from 2.4
parent efd1a62e
...@@ -143,9 +143,14 @@ int gs_write(struct tty_struct * tty, int from_user, ...@@ -143,9 +143,14 @@ int gs_write(struct tty_struct * tty, int from_user,
/* Can't copy more? break out! */ /* Can't copy more? break out! */
if (c <= 0) break; if (c <= 0) break;
if (from_user) if (from_user)
copy_from_user (port->xmit_buf + port->xmit_head, buf, c); if (copy_from_user (port->xmit_buf + port->xmit_head,
buf, c)) {
up (& port->port_write_sem);
return -EFAULT;
}
else else
memcpy (port->xmit_buf + port->xmit_head, buf, c); memcpy (port->xmit_buf + port->xmit_head, buf, c);
port -> xmit_cnt += c; port -> xmit_cnt += c;
port -> xmit_head = (port->xmit_head + c) & (SERIAL_XMIT_SIZE -1); port -> xmit_head = (port->xmit_head + c) & (SERIAL_XMIT_SIZE -1);
...@@ -604,7 +609,7 @@ int gs_block_til_ready(void *port_, struct file * filp) ...@@ -604,7 +609,7 @@ int gs_block_til_ready(void *port_, struct file * filp)
* until it's done, and then try again. * until it's done, and then try again.
*/ */
if (tty_hung_up_p(filp) || port->flags & ASYNC_CLOSING) { if (tty_hung_up_p(filp) || port->flags & ASYNC_CLOSING) {
interruptible_sleep_on(&port->close_wait); interruptible_sleep_on(&port->close_wait);
if (port->flags & ASYNC_HUP_NOTIFY) if (port->flags & ASYNC_HUP_NOTIFY)
return -EAGAIN; return -EAGAIN;
else else
...@@ -1003,7 +1008,8 @@ int gs_setserial(struct gs_port *port, struct serial_struct *sp) ...@@ -1003,7 +1008,8 @@ int gs_setserial(struct gs_port *port, struct serial_struct *sp)
{ {
struct serial_struct sio; struct serial_struct sio;
copy_from_user(&sio, sp, sizeof(struct serial_struct)); if (copy_from_user(&sio, sp, sizeof(struct serial_struct)))
return(-EFAULT);
if (!capable(CAP_SYS_ADMIN)) { if (!capable(CAP_SYS_ADMIN)) {
if ((sio.baud_base != port->baud_base) || if ((sio.baud_base != port->baud_base) ||
...@@ -1033,7 +1039,7 @@ int gs_setserial(struct gs_port *port, struct serial_struct *sp) ...@@ -1033,7 +1039,7 @@ int gs_setserial(struct gs_port *port, struct serial_struct *sp)
* Generate the serial struct info. * Generate the serial struct info.
*/ */
void gs_getserial(struct gs_port *port, struct serial_struct *sp) int gs_getserial(struct gs_port *port, struct serial_struct *sp)
{ {
struct serial_struct sio; struct serial_struct sio;
...@@ -1055,7 +1061,10 @@ void gs_getserial(struct gs_port *port, struct serial_struct *sp) ...@@ -1055,7 +1061,10 @@ void gs_getserial(struct gs_port *port, struct serial_struct *sp)
if (port->rd->getserial) if (port->rd->getserial)
port->rd->getserial (port, &sio); port->rd->getserial (port, &sio);
copy_to_user(sp, &sio, sizeof(struct serial_struct)); if (copy_to_user(sp, &sio, sizeof(struct serial_struct)))
return -EFAULT;
return 0;
} }
......
...@@ -742,7 +742,7 @@ static int rio_ioctl (struct tty_struct * tty, struct file * filp, ...@@ -742,7 +742,7 @@ static int rio_ioctl (struct tty_struct * tty, struct file * filp,
case TIOCGSERIAL: case TIOCGSERIAL:
if ((rc = verify_area(VERIFY_WRITE, (void *) arg, if ((rc = verify_area(VERIFY_WRITE, (void *) arg,
sizeof(struct serial_struct))) == 0) sizeof(struct serial_struct))) == 0)
gs_getserial(&PortP->gs, (struct serial_struct *) arg); rc = gs_getserial(&PortP->gs, (struct serial_struct *) arg);
break; break;
case TCSBRK: case TCSBRK:
if ( PortP->State & RIO_DELETED ) { if ( PortP->State & RIO_DELETED ) {
......
...@@ -673,7 +673,7 @@ static int rs_ioctl (struct tty_struct * tty, struct file * filp, ...@@ -673,7 +673,7 @@ static int rs_ioctl (struct tty_struct * tty, struct file * filp,
case TIOCGSERIAL: case TIOCGSERIAL:
if ((rc = verify_area(VERIFY_WRITE, (void *) arg, if ((rc = verify_area(VERIFY_WRITE, (void *) arg,
sizeof(struct serial_struct))) == 0) sizeof(struct serial_struct))) == 0)
gs_getserial(&port->gs, (struct serial_struct *) arg); rc = gs_getserial(&port->gs, (struct serial_struct *) arg);
break; break;
case TIOCSSERIAL: case TIOCSSERIAL:
if ((rc = verify_area(VERIFY_READ, (void *) arg, if ((rc = verify_area(VERIFY_READ, (void *) arg,
......
...@@ -919,7 +919,7 @@ static int sci_ioctl(struct tty_struct * tty, struct file * filp, ...@@ -919,7 +919,7 @@ static int sci_ioctl(struct tty_struct * tty, struct file * filp,
case TIOCGSERIAL: case TIOCGSERIAL:
if ((rc = verify_area(VERIFY_WRITE, (void *) arg, if ((rc = verify_area(VERIFY_WRITE, (void *) arg,
sizeof(struct serial_struct))) == 0) sizeof(struct serial_struct))) == 0)
gs_getserial(&port->gs, (struct serial_struct *) arg); rc = gs_getserial(&port->gs, (struct serial_struct *) arg);
break; break;
case TIOCSSERIAL: case TIOCSSERIAL:
if ((rc = verify_area(VERIFY_READ, (void *) arg, if ((rc = verify_area(VERIFY_READ, (void *) arg,
......
...@@ -1160,7 +1160,8 @@ static inline void sx_check_modem_signals (struct sx_port *port) ...@@ -1160,7 +1160,8 @@ static inline void sx_check_modem_signals (struct sx_port *port)
/* DCD went UP */ /* DCD went UP */
if( (~(port->gs.flags & ASYNC_NORMAL_ACTIVE) || if( (~(port->gs.flags & ASYNC_NORMAL_ACTIVE) ||
~(port->gs.flags & ASYNC_CALLOUT_ACTIVE)) && ~(port->gs.flags & ASYNC_CALLOUT_ACTIVE)) &&
(sx_read_channel_byte(port, hi_hstat) != HS_IDLE_CLOSED)) { (sx_read_channel_byte(port, hi_hstat) != HS_IDLE_CLOSED) &&
!(port->gs.tty->termios->c_cflag & CLOCAL) ) {
/* Are we blocking in open?*/ /* Are we blocking in open?*/
sx_dprintk (SX_DEBUG_MODEMSIGNALS, "DCD active, unblocking open\n"); sx_dprintk (SX_DEBUG_MODEMSIGNALS, "DCD active, unblocking open\n");
wake_up_interruptible(&port->gs.open_wait); wake_up_interruptible(&port->gs.open_wait);
...@@ -1170,7 +1171,8 @@ static inline void sx_check_modem_signals (struct sx_port *port) ...@@ -1170,7 +1171,8 @@ static inline void sx_check_modem_signals (struct sx_port *port)
} else { } else {
/* DCD went down! */ /* DCD went down! */
if (!((port->gs.flags & ASYNC_CALLOUT_ACTIVE) && if (!((port->gs.flags & ASYNC_CALLOUT_ACTIVE) &&
(port->gs.flags & ASYNC_CALLOUT_NOHUP))) { (port->gs.flags & ASYNC_CALLOUT_NOHUP)) &&
!(port->gs.tty->termios->c_cflag & CLOCAL) ) {
sx_dprintk (SX_DEBUG_MODEMSIGNALS, "DCD dropped. hanging up....\n"); sx_dprintk (SX_DEBUG_MODEMSIGNALS, "DCD dropped. hanging up....\n");
tty_hangup (port->gs.tty); tty_hangup (port->gs.tty);
} else { } else {
...@@ -1815,7 +1817,7 @@ static int sx_ioctl (struct tty_struct * tty, struct file * filp, ...@@ -1815,7 +1817,7 @@ static int sx_ioctl (struct tty_struct * tty, struct file * filp,
case TIOCGSERIAL: case TIOCGSERIAL:
if ((rc = verify_area(VERIFY_WRITE, (void *) arg, if ((rc = verify_area(VERIFY_WRITE, (void *) arg,
sizeof(struct serial_struct))) == 0) sizeof(struct serial_struct))) == 0)
gs_getserial(&port->gs, (struct serial_struct *) arg); rc = gs_getserial(&port->gs, (struct serial_struct *) arg);
break; break;
case TIOCSSERIAL: case TIOCSSERIAL:
if ((rc = verify_area(VERIFY_READ, (void *) arg, if ((rc = verify_area(VERIFY_READ, (void *) arg,
......
...@@ -12,9 +12,6 @@ ...@@ -12,9 +12,6 @@
#ifndef GENERIC_SERIAL_H #ifndef GENERIC_SERIAL_H
#define GENERIC_SERIAL_H #define GENERIC_SERIAL_H
struct real_driver { struct real_driver {
void (*disable_tx_interrupts) (void *); void (*disable_tx_interrupts) (void *);
void (*enable_tx_interrupts) (void *); void (*enable_tx_interrupts) (void *);
...@@ -98,7 +95,7 @@ void gs_set_termios (struct tty_struct * tty, ...@@ -98,7 +95,7 @@ void gs_set_termios (struct tty_struct * tty,
struct termios * old_termios); struct termios * old_termios);
int gs_init_port(struct gs_port *port); int gs_init_port(struct gs_port *port);
int gs_setserial(struct gs_port *port, struct serial_struct *sp); int gs_setserial(struct gs_port *port, struct serial_struct *sp);
void gs_getserial(struct gs_port *port, struct serial_struct *sp); int gs_getserial(struct gs_port *port, struct serial_struct *sp);
void gs_got_break(struct gs_port *port); void gs_got_break(struct gs_port *port);
extern int gs_debug; extern int gs_debug;
......
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