[PATCH] read(tty, (char *)-1, 1) exempt from EFAULT ?

From: Steven Rostedt (rostedt@goodmis.org)
Date: Tue Mar 18 2003 - 21:19:04 EST


Hi all,

John Reiser posted a question on c.o.l.d.s about why reading from
a tty with a bad buffer doesn't return -EFAULT to the user.
I looked into it and believe that this is a minor bug. Below is
part of John's post and below that is my patch.

John Reiser wrote:
> Why is reading from a tty exempt from EFAULT?
>
> -----readerr.c
> #include <errno.h>
>
> int
> main()
> {
> int v = read(0,(char *)-1,1); /* should get EFAULT [14] */
> printf("read(0,(char *)-1,1)=0x%x errno=%d\n", v, errno);
> return v;
> }
> -----
> $ gcc -o readerr readerr.c
> $ ./readerr </dev/tty; echo $?
> # type <Enter>
> read(0,(char *)-1,1)=0x1 errno=0
> 1
> $ date | ./readerr; echo $?
> read(0,(char *)-1,1)=0xffffffff errno=14
> 255
> $

===========================
--- linux-2.4.20/drivers/char/n_tty.c_orig Tue Mar 18 20:19:33 2003
+++ linux-2.4.20/drivers/char/n_tty.c Tue Mar 18 21:06:57 2003
@@ -1030,7 +1030,10 @@
                                  break;
                          cs = tty->link->ctrl_status;
                          tty->link->ctrl_status = 0;
- put_user(cs, b++);
+ if (put_user(cs, b++)) {
+ retval = -EFAULT;
+ break;
+ }
+ retval = -EFAULT;
+ break;
+ }
                         nr--;
                         break;
                 }
@@ -1069,7 +1072,10 @@

                 /* Deal with packet mode. */
                 if (tty->packet && b == buf) {
- put_user(TIOCPKT_DATA, b++);
+ if (put_user(TIOCPKT_DATA, b++)) {
+ retval = -EFAULT;
+ break;
+ }
                         nr--;
                 }

@@ -1096,12 +1102,17 @@
                                 spin_unlock_irqrestore(&tty->read_lock,
flags);

                                 if (!eol || (c != __DISABLED_CHAR)) {
- put_user(c, b++);
+ if (put_user(c, b++)) {
+ retval = -EFAULT;
+ break;
+ }
                                         nr--;
                                 }
                                 if (eol)
                                         break;
                         }
+ if (retval)
+ break;
                 } else {
                         int uncopied;
                         uncopied = copy_from_read_buf(tty, &b, &nr);
@@ -1136,7 +1147,7 @@

         current->state = TASK_RUNNING;
         size = b - buf;
- if (size) {
+ if (!retval && size) {
                 retval = size;
                 if (nr)
                         clear_bit(TTY_PUSH, &tty->flags);

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Sun Mar 23 2003 - 22:00:25 EST