Verify in ttyname() that the symlink is valid.

This commit is contained in:
Miklos Szeredi 2010-11-03 00:25:45 -04:00 committed by Ulrich Drepper
parent 0e012e8734
commit 0e516e0e14
4 changed files with 66 additions and 13 deletions

View File

@ -1,3 +1,11 @@
2010-11-03 Ulrich Drepper <drepper@gmail.com>
[BZ #12167]
* sysdeps/unix/sysv/linux/ttyname.c (ttyname): Recognize new mangling
of inacessible symlinks. Verify result of symlink before returning it.
* sysdeps/unix/sysv/linux/ttyname_r.c (__ttyname_r): Likewise.
Patch mostly by Miklos Szeredi <miklos@szeredi.hu>.
2010-10-28 Erich Ritz <erichritz@gmail.com>
* math/math.h (isinf): Fix typo in comment.

4
NEWS
View File

@ -1,4 +1,4 @@
GNU C Library NEWS -- history of user-visible changes. 2010-10-24
GNU C Library NEWS -- history of user-visible changes. 2010-11-2
Copyright (C) 1992-2009, 2010 Free Software Foundation, Inc.
See the end for copying conditions.
@ -11,7 +11,7 @@ Version 2.13
3268, 7066, 10851, 11611, 11640, 11701, 11840, 11856, 11883, 11903, 11904,
11968, 11979, 12005, 12037, 12067, 12077, 12078, 12092, 12093, 12107, 12108,
12113, 12140, 12159
12113, 12140, 12159, 12167
* New Linux interfaces: prlimit, prlimit64, fanotify_init, fanotify_mark

View File

@ -1,4 +1,5 @@
/* Copyright (C) 1991,92,93,1996-2002,2006,2009 Free Software Foundation, Inc.
/* Copyright (C) 1991-1993,1996-2002,2006,2009,2010
Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@ -131,6 +132,9 @@ ttyname (int fd)
if (__builtin_expect (__tcgetattr (fd, &term) < 0, 0))
return NULL;
if (__fxstat64 (_STAT_VER, fd, &st) < 0)
return NULL;
/* We try using the /proc filesystem. */
*_fitoa_word (fd, __stpcpy (procname, "/proc/self/fd/"), 10, 0) = '\0';
@ -161,13 +165,32 @@ ttyname (int fd)
{
if ((size_t) len >= buflen)
return NULL;
#define UNREACHABLE_LEN strlen ("(unreachable)")
if (len > UNREACHABLE_LEN
&& memcmp (ttyname_buf, "(unreachable)", UNREACHABLE_LEN) == 0)
{
memmove (ttyname_buf, ttyname_buf + UNREACHABLE_LEN,
len - UNREACHABLE_LEN);
len -= UNREACHABLE_LEN;
}
/* readlink need not terminate the string. */
ttyname_buf[len] = '\0';
return ttyname_buf;
}
if (__fxstat64 (_STAT_VER, fd, &st) < 0)
return NULL;
/* Verify readlink result, fall back on iterating through devices. */
if (ttyname_buf[0] == '/'
&& __xstat64 (_STAT_VER, ttyname_buf, &st1) == 0
#ifdef _STATBUF_ST_RDEV
&& S_ISCHR (st1.st_mode)
&& st1.st_rdev == st.st_rdev
#else
&& st1.st_ino == st.st_ino
&& st1.st_dev == st.st_dev
#endif
)
return ttyname_buf;
}
if (__xstat64 (_STAT_VER, "/dev/pts", &st1) == 0 && S_ISDIR (st1.st_mode))
{

View File

@ -1,4 +1,5 @@
/* Copyright (C) 1991,92,93,1995-2001,2003,2006 Free Software Foundation, Inc.
/* Copyright (C) 1991-1993,1995-2001,2003,2006,2010
Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@ -122,6 +123,9 @@ __ttyname_r (int fd, char *buf, size_t buflen)
if (__builtin_expect (__tcgetattr (fd, &term) < 0, 0))
return errno;
if (__fxstat64 (_STAT_VER, fd, &st) < 0)
return errno;
/* We try using the /proc filesystem. */
*_fitoa_word (fd, __stpcpy (procname, "/proc/self/fd/"), 10, 0) = '\0';
@ -145,12 +149,30 @@ __ttyname_r (int fd, char *buf, size_t buflen)
#endif
, 1))
{
buf[ret] = '\0';
return 0;
}
#define UNREACHABLE_LEN strlen ("(unreachable)")
if (ret > UNREACHABLE_LEN
&& memcmp (buf, "(unreachable)", UNREACHABLE_LEN) == 0)
{
memmove (buf, buf + UNREACHABLE_LEN, ret - UNREACHABLE_LEN);
ret -= UNREACHABLE_LEN;
}
if (__fxstat64 (_STAT_VER, fd, &st) < 0)
return errno;
/* readlink need not terminate the string. */
buf[ret] = '\0';
/* Verify readlink result, fall back on iterating through devices. */
if (buf[0] == '/'
&& __xstat64 (_STAT_VER, buf, &st1) == 0
#ifdef _STATBUF_ST_RDEV
&& S_ISCHR (st1.st_mode)
&& st1.st_rdev == st.st_rdev
#else
&& st1.st_ino == st.st_ino
&& st1.st_dev == st.st_dev
#endif
)
return 0;
}
/* Prepare the result buffer. */
memcpy (buf, "/dev/pts/", sizeof ("/dev/pts/"));