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> 2010-10-28 Erich Ritz <erichritz@gmail.com>
* math/math.h (isinf): Fix typo in comment. * 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. Copyright (C) 1992-2009, 2010 Free Software Foundation, Inc.
See the end for copying conditions. See the end for copying conditions.
@ -11,7 +11,7 @@ Version 2.13
3268, 7066, 10851, 11611, 11640, 11701, 11840, 11856, 11883, 11903, 11904, 3268, 7066, 10851, 11611, 11640, 11701, 11840, 11856, 11883, 11903, 11904,
11968, 11979, 12005, 12037, 12067, 12077, 12078, 12092, 12093, 12107, 12108, 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 * 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. This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or 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)) if (__builtin_expect (__tcgetattr (fd, &term) < 0, 0))
return NULL; return NULL;
if (__fxstat64 (_STAT_VER, fd, &st) < 0)
return NULL;
/* We try using the /proc filesystem. */ /* We try using the /proc filesystem. */
*_fitoa_word (fd, __stpcpy (procname, "/proc/self/fd/"), 10, 0) = '\0'; *_fitoa_word (fd, __stpcpy (procname, "/proc/self/fd/"), 10, 0) = '\0';
@ -161,13 +165,32 @@ ttyname (int fd)
{ {
if ((size_t) len >= buflen) if ((size_t) len >= buflen)
return NULL; 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. */ /* readlink need not terminate the string. */
ttyname_buf[len] = '\0'; ttyname_buf[len] = '\0';
return ttyname_buf;
}
if (__fxstat64 (_STAT_VER, fd, &st) < 0) /* Verify readlink result, fall back on iterating through devices. */
return NULL; 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)) 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. This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or 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)) if (__builtin_expect (__tcgetattr (fd, &term) < 0, 0))
return errno; return errno;
if (__fxstat64 (_STAT_VER, fd, &st) < 0)
return errno;
/* We try using the /proc filesystem. */ /* We try using the /proc filesystem. */
*_fitoa_word (fd, __stpcpy (procname, "/proc/self/fd/"), 10, 0) = '\0'; *_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 #endif
, 1)) , 1))
{ {
buf[ret] = '\0'; #define UNREACHABLE_LEN strlen ("(unreachable)")
return 0; 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) /* readlink need not terminate the string. */
return errno; 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. */ /* Prepare the result buffer. */
memcpy (buf, "/dev/pts/", sizeof ("/dev/pts/")); memcpy (buf, "/dev/pts/", sizeof ("/dev/pts/"));