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,
/* Can't copy more? break out! */
if (c <= 0) break;
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
memcpy (port->xmit_buf + port->xmit_head, buf, c);
memcpy (port->xmit_buf + port->xmit_head, buf, c);
port -> xmit_cnt += c;
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)
* until it's done, and then try again.
*/
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)
return -EAGAIN;
else
......@@ -1003,7 +1008,8 @@ int gs_setserial(struct gs_port *port, struct serial_struct *sp)
{
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 ((sio.baud_base != port->baud_base) ||
......@@ -1033,7 +1039,7 @@ int gs_setserial(struct gs_port *port, struct serial_struct *sp)
* 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;
......@@ -1055,7 +1061,10 @@ void gs_getserial(struct gs_port *port, struct serial_struct *sp)
if (port->rd->getserial)
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,
case TIOCGSERIAL:
if ((rc = verify_area(VERIFY_WRITE, (void *) arg,
sizeof(struct serial_struct))) == 0)
gs_getserial(&PortP->gs, (struct serial_struct *) arg);
rc = gs_getserial(&PortP->gs, (struct serial_struct *) arg);
break;
case TCSBRK:
if ( PortP->State & RIO_DELETED ) {
......
......@@ -673,7 +673,7 @@ static int rs_ioctl (struct tty_struct * tty, struct file * filp,
case TIOCGSERIAL:
if ((rc = verify_area(VERIFY_WRITE, (void *) arg,
sizeof(struct serial_struct))) == 0)
gs_getserial(&port->gs, (struct serial_struct *) arg);
rc = gs_getserial(&port->gs, (struct serial_struct *) arg);
break;
case TIOCSSERIAL:
if ((rc = verify_area(VERIFY_READ, (void *) arg,
......
......@@ -919,7 +919,7 @@ static int sci_ioctl(struct tty_struct * tty, struct file * filp,
case TIOCGSERIAL:
if ((rc = verify_area(VERIFY_WRITE, (void *) arg,
sizeof(struct serial_struct))) == 0)
gs_getserial(&port->gs, (struct serial_struct *) arg);
rc = gs_getserial(&port->gs, (struct serial_struct *) arg);
break;
case TIOCSSERIAL:
if ((rc = verify_area(VERIFY_READ, (void *) arg,
......
......@@ -1160,7 +1160,8 @@ static inline void sx_check_modem_signals (struct sx_port *port)
/* DCD went UP */
if( (~(port->gs.flags & ASYNC_NORMAL_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?*/
sx_dprintk (SX_DEBUG_MODEMSIGNALS, "DCD active, unblocking open\n");
wake_up_interruptible(&port->gs.open_wait);
......@@ -1170,7 +1171,8 @@ static inline void sx_check_modem_signals (struct sx_port *port)
} else {
/* DCD went down! */
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");
tty_hangup (port->gs.tty);
} else {
......@@ -1815,7 +1817,7 @@ static int sx_ioctl (struct tty_struct * tty, struct file * filp,
case TIOCGSERIAL:
if ((rc = verify_area(VERIFY_WRITE, (void *) arg,
sizeof(struct serial_struct))) == 0)
gs_getserial(&port->gs, (struct serial_struct *) arg);
rc = gs_getserial(&port->gs, (struct serial_struct *) arg);
break;
case TIOCSSERIAL:
if ((rc = verify_area(VERIFY_READ, (void *) arg,
......
......@@ -12,9 +12,6 @@
#ifndef GENERIC_SERIAL_H
#define GENERIC_SERIAL_H
struct real_driver {
void (*disable_tx_interrupts) (void *);
void (*enable_tx_interrupts) (void *);
......@@ -98,7 +95,7 @@ void gs_set_termios (struct tty_struct * tty,
struct termios * old_termios);
int gs_init_port(struct gs_port *port);
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);
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