Skip to contentSkip to conversation

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

PATCH New Steven Rostedt 1 participant 1 message Mar 19, 2003 1 message not in the archive Char and misc drivers

lore
Share & tools
lore
#1 lore raw

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

In reply to a message not in the archive

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.

Quoted 7 lines · John Reiser

Why is reading from a tty exempt from EFAULT?

-----readerr.c
#include <errno.h>

int
main()

Quoted 15 lines
{
    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
$

===========================

drivers/char/n_tty.c renamed from drivers/char/n_tty.c_orig +7 -1
@@ -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);