VFS: disallow opening files of unsupported types

Any attempt to use open(2) to open a socket file now fails with
EOPNOTSUPP, as is common and in the process of being standardized.
The behavior and error code is now tested in test56.

Any attempt to open a file of which the type is not known to VFS
(e.g., as a result of bogus file system contents) now fails with EIO.
For now, this is a safety feature, to prevent VFS tripping over such
types in unchecked cases.  In the future, a proper VFS code audit
should determine whether we can lift this restriction again, although
it does not seem particularly useful to be able to open files of
unknown types anyway.  Another error code may be assigned to this case
later, too.

Change-Id: Ib4cb4341eec954f0448fe469ecf28bd78edebde2
This commit is contained in:
David van Moolenbroek 2015-12-27 22:44:34 +00:00
parent 63faa8fe9a
commit 0eb6caa076
2 changed files with 54 additions and 0 deletions

View File

@ -263,6 +263,14 @@ int common_open(char path[PATH_MAX], int oflags, mode_t omode, int for_exec)
}
}
break;
case S_IFSOCK:
r = EOPNOTSUPP;
break;
default:
printf("VFS: attempt to open file <%llu,%llu> of "
"type 0%o\n", vp->v_dev, vp->v_inode_nr,
vp->v_mode & S_IFMT);
r = EIO;
}
}
}

View File

@ -1379,6 +1379,51 @@ static void test_fchmod(void)
close(socks[1]);
}
/*
* Test various aspects related to the socket files on the file system.
* This subtest is woefully incomplete and currently only attempts to test
* aspects that have recently been affected by code changes. In the future,
* there should be tests for path canonicalization and the entire range of file
* system path and access related error codes (TODO).
*/
static void
test_file(void)
{
struct sockaddr_un addr;
int sd;
UNLINK(TEST_SUN_PATH);
memset(&addr, 0, sizeof(addr));
addr.sun_family = AF_UNIX;
strlcpy(addr.sun_path, TEST_SUN_PATH, sizeof(addr.sun_path));
/*
* Only socket(2), socketpair(2), and accept(2) may be used to obtain
* new file descriptors to sockets (or "sockets"); open(2) on a socket
* file is expected to fail with EOPNOTSUPP (Austin Group Issue #943),
* regardless of whether the socket is in use.
*/
if ((sd = socket(PF_UNIX, SOCK_DGRAM, 0)) == -1)
test_fail("Can't open socket");
if (bind(sd, (struct sockaddr *)&addr, sizeof(addr)) != 0)
test_fail("Can't bind socket");
if (open(TEST_SUN_PATH, O_RDWR) != -1)
test_fail("Unexpectedly opened socket file");
if (errno != EOPNOTSUPP)
test_fail("Open failed with wrong error");
CLOSE(sd);
if (open(TEST_SUN_PATH, O_RDONLY) != -1)
test_fail("Unexpectedly opened socket file");
if (errno != EOPNOTSUPP)
test_fail("Open failed with wrong error");
UNLINK(TEST_SUN_PATH);
}
int main(int argc, char *argv[])
{
int i;
@ -1463,6 +1508,7 @@ int main(int argc, char *argv[])
test_connect_close(&info);
test_listen_close(&info);
test_listen_close_nb(&info);
test_file();
quit();