Home Home > GIT Browse
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Jones <davej@suse.de>2002-02-10 00:44:58 -0800
committerJeff Garzik <gkernel.adm@hostme.bitkeeper.com>2002-02-10 00:44:58 -0800
commit528ce3c01427a95744fca2147f5a8ccd66de483b (patch)
treed88fc3e39e3e9a07188b00028fdfa0a3477151a1
parentefd1a62e84fc9dfd251c467d18209908588b1bd4 (diff)
[PATCH] check copy_from_user return codes in serial drivers.
forward-ported from 2.4
-rw-r--r--drivers/char/generic_serial.c21
-rw-r--r--drivers/char/rio/rio_linux.c2
-rw-r--r--drivers/char/serial_tx3912.c2
-rw-r--r--drivers/char/sh-sci.c2
-rw-r--r--drivers/char/sx.c8
-rw-r--r--include/linux/generic_serial.h5
6 files changed, 24 insertions, 16 deletions
diff --git a/drivers/char/generic_serial.c b/drivers/char/generic_serial.c
index 9fa07e66fade..4ff7dc3fe453 100644
--- a/drivers/char/generic_serial.c
+++ b/drivers/char/generic_serial.c
@@ -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;
+
}
diff --git a/drivers/char/rio/rio_linux.c b/drivers/char/rio/rio_linux.c
index 3b41b68f19f8..293008c70a73 100644
--- a/drivers/char/rio/rio_linux.c
+++ b/drivers/char/rio/rio_linux.c
@@ -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 ) {
diff --git a/drivers/char/serial_tx3912.c b/drivers/char/serial_tx3912.c
index d2b46ac4419a..4743489b0e66 100644
--- a/drivers/char/serial_tx3912.c
+++ b/drivers/char/serial_tx3912.c
@@ -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,
diff --git a/drivers/char/sh-sci.c b/drivers/char/sh-sci.c
index 7b5b22b3088a..6ae9b63721af 100644
--- a/drivers/char/sh-sci.c
+++ b/drivers/char/sh-sci.c
@@ -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,
diff --git a/drivers/char/sx.c b/drivers/char/sx.c
index 3ff09849024c..947f76a60898 100644
--- a/drivers/char/sx.c
+++ b/drivers/char/sx.c
@@ -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,
diff --git a/include/linux/generic_serial.h b/include/linux/generic_serial.h
index 1d8b041bfaae..5c30fc929cab 100644
--- a/include/linux/generic_serial.h
+++ b/include/linux/generic_serial.h
@@ -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;