From df0ba1eca130cd0b75fd671476d8e0aad115e46d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Duval?= Date: Sun, 12 May 2019 10:11:21 +0200 Subject: [PATCH] vfs: _user_ioctl: any buffer value is allowed for some ops. some ops want an integer value instead of a pointer as arg parameter ( #15058 ). http://pubs.opengroup.org/onlinepubs/9699919799/functions/ioctl.html clearly specifies that: "The type of arg depends upon the particular control request, but it shall be either an integer or a pointer to a device-specific data structure." add a test for functions which should return ENOTTY as errno. Change-Id: I4a98af73b17c79c3460123d3794ee866f8719898 Reviewed-on: https://review.haiku-os.org/c/1447 Reviewed-by: waddlesplash --- src/system/kernel/fs/fd.cpp | 7 +-- src/tests/system/libroot/posix/termios.cpp | 60 ++++++++++++++++++++++ 2 files changed, 64 insertions(+), 3 deletions(-) create mode 100644 src/tests/system/libroot/posix/termios.cpp diff --git a/src/system/kernel/fs/fd.cpp b/src/system/kernel/fs/fd.cpp index 45de3762ad..cc9d7f7fb4 100644 --- a/src/system/kernel/fs/fd.cpp +++ b/src/system/kernel/fs/fd.cpp @@ -919,11 +919,12 @@ _user_seek(int fd, off_t pos, int seekType) status_t _user_ioctl(int fd, uint32 op, void* buffer, size_t length) { - if (buffer != NULL && !IS_USER_ADDRESS(buffer)) - return B_BAD_ADDRESS; - TRACE(("user_ioctl: fd %d\n", fd)); + // "buffer" is not always a pointer depending on "op", so we cannot + // check that it is a userland buffer here; the underlying implementation + // must do that. + SyscallRestartWrapper status; return status = fd_ioctl(false, fd, op, buffer, length); diff --git a/src/tests/system/libroot/posix/termios.cpp b/src/tests/system/libroot/posix/termios.cpp new file mode 100644 index 0000000000..31bbed525e --- /dev/null +++ b/src/tests/system/libroot/posix/termios.cpp @@ -0,0 +1,60 @@ +/* + * Copyright 2019, Jérôme Duval, jerome.duval@gmail.com. + * Distributed under the terms of the MIT License. + */ + + +#include +#include +#include +#include +#include +#include +#include +#include + + +extern const char *__progname; + + +int +main(int argc, char **argv) +{ + if (argc < 2) { + fprintf(stderr, "usage: %s \n", __progname); + return 1; + } + + int fd = open(argv[1], O_RDONLY); + if (fd < 0) { + fprintf(stderr, "%s: could open the file read-only \"%s\": %s\n", + __progname, argv[1], strerror(errno)); + return 1; + } + int err = tcdrain(fd); + if (err != -1 || errno != ENOTTY) { + fprintf(stderr, "%s: tcdrain didn't fail with ENOTTY \"%s\": %s\n", + __progname, argv[1], strerror(errno)); + close(fd); + return 1; + } + err = tcflow(fd, TCION); + if (err != -1 || errno != ENOTTY) { + fprintf(stderr, "%s: tcflow didn't fail with ENOTTY \"%s\": %s\n", + __progname, argv[1], strerror(errno)); + close(fd); + return 1; + } + + err = tcflush(fd, TCIOFLUSH); + if (err != -1 || errno != ENOTTY) { + fprintf(stderr, "%s: tcflush didn't fail with ENOTTY \"%s\": %s\n", + __progname, argv[1], strerror(errno)); + close(fd); + return 1; + } + + close(fd); + + return 0; +}