Path: blob/master/tools/testing/selftests/exec/non-regular.c
26285 views
// SPDX-License-Identifier: GPL-2.0+1#include <errno.h>2#include <fcntl.h>3#include <stdio.h>4#include <string.h>5#include <unistd.h>6#include <sys/socket.h>7#include <sys/stat.h>8#include <sys/sysmacros.h>9#include <sys/types.h>1011#include "../kselftest_harness.h"1213/* Remove a file, ignoring the result if it didn't exist. */14void rm(struct __test_metadata *_metadata, const char *pathname,15int is_dir)16{17int rc;1819if (is_dir)20rc = rmdir(pathname);21else22rc = unlink(pathname);2324if (rc < 0) {25ASSERT_EQ(errno, ENOENT) {26TH_LOG("Not ENOENT: %s", pathname);27}28} else {29ASSERT_EQ(rc, 0) {30TH_LOG("Failed to remove: %s", pathname);31}32}33}3435FIXTURE(file) {36char *pathname;37int is_dir;38};3940FIXTURE_VARIANT(file)41{42const char *name;43int expected;44int is_dir;45void (*setup)(struct __test_metadata *_metadata,46FIXTURE_DATA(file) *self,47const FIXTURE_VARIANT(file) *variant);48int major, minor, mode; /* for mknod() */49};5051void setup_link(struct __test_metadata *_metadata,52FIXTURE_DATA(file) *self,53const FIXTURE_VARIANT(file) *variant)54{55const char * const paths[] = {56"/bin/true",57"/usr/bin/true",58};59int i;6061for (i = 0; i < ARRAY_SIZE(paths); i++) {62if (access(paths[i], X_OK) == 0) {63ASSERT_EQ(symlink(paths[i], self->pathname), 0);64return;65}66}67ASSERT_EQ(1, 0) {68TH_LOG("Could not find viable 'true' binary");69}70}7172FIXTURE_VARIANT_ADD(file, S_IFLNK)73{74.name = "S_IFLNK",75.expected = ELOOP,76.setup = setup_link,77};7879void setup_dir(struct __test_metadata *_metadata,80FIXTURE_DATA(file) *self,81const FIXTURE_VARIANT(file) *variant)82{83ASSERT_EQ(mkdir(self->pathname, 0755), 0);84}8586FIXTURE_VARIANT_ADD(file, S_IFDIR)87{88.name = "S_IFDIR",89.is_dir = 1,90.expected = EACCES,91.setup = setup_dir,92};9394void setup_node(struct __test_metadata *_metadata,95FIXTURE_DATA(file) *self,96const FIXTURE_VARIANT(file) *variant)97{98dev_t dev;99int rc;100101dev = makedev(variant->major, variant->minor);102rc = mknod(self->pathname, 0755 | variant->mode, dev);103ASSERT_EQ(rc, 0) {104if (errno == EPERM)105SKIP(return, "Please run as root; cannot mknod(%s)",106variant->name);107}108}109110FIXTURE_VARIANT_ADD(file, S_IFBLK)111{112.name = "S_IFBLK",113.expected = EACCES,114.setup = setup_node,115/* /dev/loop0 */116.major = 7,117.minor = 0,118.mode = S_IFBLK,119};120121FIXTURE_VARIANT_ADD(file, S_IFCHR)122{123.name = "S_IFCHR",124.expected = EACCES,125.setup = setup_node,126/* /dev/zero */127.major = 1,128.minor = 5,129.mode = S_IFCHR,130};131132void setup_fifo(struct __test_metadata *_metadata,133FIXTURE_DATA(file) *self,134const FIXTURE_VARIANT(file) *variant)135{136ASSERT_EQ(mkfifo(self->pathname, 0755), 0);137}138139FIXTURE_VARIANT_ADD(file, S_IFIFO)140{141.name = "S_IFIFO",142.expected = EACCES,143.setup = setup_fifo,144};145146FIXTURE_SETUP(file)147{148ASSERT_GT(asprintf(&self->pathname, "%s.test", variant->name), 6);149self->is_dir = variant->is_dir;150151rm(_metadata, self->pathname, variant->is_dir);152variant->setup(_metadata, self, variant);153}154155FIXTURE_TEARDOWN(file)156{157rm(_metadata, self->pathname, self->is_dir);158}159160TEST_F(file, exec_errno)161{162char * const argv[2] = { (char * const)self->pathname, NULL };163164EXPECT_LT(execv(argv[0], argv), 0);165EXPECT_EQ(errno, variant->expected);166}167168/* S_IFSOCK */169FIXTURE(sock)170{171int fd;172};173174FIXTURE_SETUP(sock)175{176self->fd = socket(AF_INET, SOCK_STREAM, 0);177ASSERT_GE(self->fd, 0);178}179180FIXTURE_TEARDOWN(sock)181{182if (self->fd >= 0)183ASSERT_EQ(close(self->fd), 0);184}185186TEST_F(sock, exec_errno)187{188char * const argv[2] = { " magic socket ", NULL };189char * const envp[1] = { NULL };190191EXPECT_LT(fexecve(self->fd, argv, envp), 0);192EXPECT_EQ(errno, EACCES);193}194195TEST_HARNESS_MAIN196197198