unix: reject non-tty fds in uv_tty_init()
Reject file descriptors that correspond to regular files or char/block devices. Such file descriptors are incompatible with epoll and trigger a run-time assert. Fixes: https://github.com/libuv/libuv/issues/255 PR-URL: https://github.com/libuv/libuv/pull/259 Reviewed-By: Saúl Ibarra Corretgé <saghul@gmail.com>
This commit is contained in:
parent
1df46fe478
commit
fc9e66e555
@ -66,6 +66,10 @@ API
|
||||
If opening ``/dev/tty`` fails, libuv falls back to blocking writes for
|
||||
non-readable TTY streams.
|
||||
|
||||
.. versionchanged:: 1.5.0: trying to initialize a TTY stream with a file
|
||||
descriptor that refers to a file returns `UV_EINVAL`
|
||||
on UNIX.
|
||||
|
||||
.. c:function:: int uv_tty_set_mode(uv_tty_t*, uv_tty_mode_t mode)
|
||||
|
||||
.. versionchanged:: 1.2.0: the mode is specified as a
|
||||
|
||||
@ -35,10 +35,19 @@ static uv_spinlock_t termios_spinlock = UV_SPINLOCK_INITIALIZER;
|
||||
|
||||
|
||||
int uv_tty_init(uv_loop_t* loop, uv_tty_t* tty, int fd, int readable) {
|
||||
uv_handle_type type;
|
||||
int flags;
|
||||
int newfd;
|
||||
int r;
|
||||
|
||||
/* File descriptors that refer to files cannot be monitored with epoll.
|
||||
* That restriction also applies to character devices like /dev/random
|
||||
* (but obviously not /dev/tty.)
|
||||
*/
|
||||
type = uv_guess_handle(fd);
|
||||
if (type == UV_FILE || type == UV_UNKNOWN_HANDLE)
|
||||
return -EINVAL;
|
||||
|
||||
flags = 0;
|
||||
newfd = -1;
|
||||
|
||||
@ -54,7 +63,7 @@ int uv_tty_init(uv_loop_t* loop, uv_tty_t* tty, int fd, int readable) {
|
||||
* different struct file, hence changing its properties doesn't affect
|
||||
* other processes.
|
||||
*/
|
||||
if (isatty(fd)) {
|
||||
if (type == UV_TTY) {
|
||||
r = uv__open_cloexec("/dev/tty", O_RDWR);
|
||||
|
||||
if (r < 0) {
|
||||
|
||||
@ -43,6 +43,7 @@ TEST_DECLARE (semaphore_1)
|
||||
TEST_DECLARE (semaphore_2)
|
||||
TEST_DECLARE (semaphore_3)
|
||||
TEST_DECLARE (tty)
|
||||
TEST_DECLARE (tty_file)
|
||||
TEST_DECLARE (stdio_over_pipes)
|
||||
TEST_DECLARE (ip6_pton)
|
||||
TEST_DECLARE (ipc_listen_before_write)
|
||||
@ -343,6 +344,7 @@ TASK_LIST_START
|
||||
#endif
|
||||
TEST_ENTRY (pipe_set_non_blocking)
|
||||
TEST_ENTRY (tty)
|
||||
TEST_ENTRY (tty_file)
|
||||
TEST_ENTRY (stdio_over_pipes)
|
||||
TEST_ENTRY (ip6_pton)
|
||||
TEST_ENTRY (ipc_listen_before_write)
|
||||
|
||||
@ -135,3 +135,45 @@ TEST_IMPL(tty) {
|
||||
MAKE_VALGRIND_HAPPY();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
TEST_IMPL(tty_file) {
|
||||
#ifndef _WIN32
|
||||
uv_loop_t loop;
|
||||
uv_tty_t tty;
|
||||
int fd;
|
||||
|
||||
ASSERT(0 == uv_loop_init(&loop));
|
||||
|
||||
fd = open("test/fixtures/empty_file", O_RDONLY);
|
||||
if (fd != -1) {
|
||||
ASSERT(UV_EINVAL == uv_tty_init(&loop, &tty, fd, 1));
|
||||
ASSERT(0 == close(fd));
|
||||
}
|
||||
|
||||
fd = open("/dev/random", O_RDONLY);
|
||||
if (fd != -1) {
|
||||
ASSERT(UV_EINVAL == uv_tty_init(&loop, &tty, fd, 1));
|
||||
ASSERT(0 == close(fd));
|
||||
}
|
||||
|
||||
fd = open("/dev/zero", O_RDONLY);
|
||||
if (fd != -1) {
|
||||
ASSERT(UV_EINVAL == uv_tty_init(&loop, &tty, fd, 1));
|
||||
ASSERT(0 == close(fd));
|
||||
}
|
||||
|
||||
fd = open("/dev/tty", O_RDONLY);
|
||||
if (fd != -1) {
|
||||
ASSERT(0 == uv_tty_init(&loop, &tty, fd, 1));
|
||||
ASSERT(0 == close(fd));
|
||||
}
|
||||
|
||||
uv_close((uv_handle_t*) &tty, NULL);
|
||||
ASSERT(0 == uv_run(&loop, UV_RUN_DEFAULT));
|
||||
ASSERT(0 == uv_loop_close(&loop));
|
||||
|
||||
MAKE_VALGRIND_HAPPY();
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user