read(tty, (char *)-1, 1) exempt from EFAULT ?
A message that is not in the archive (sent off-list or not yet received): [email protected]
PATCH 1/1 read(tty, (char *)-1, 1) exempt from EFAULT ?
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);