cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

non-regular.c (3647B)


      1// SPDX-License-Identifier: GPL-2.0+
      2#include <errno.h>
      3#include <fcntl.h>
      4#include <stdio.h>
      5#include <string.h>
      6#include <unistd.h>
      7#include <sys/socket.h>
      8#include <sys/stat.h>
      9#include <sys/sysmacros.h>
     10#include <sys/types.h>
     11
     12#include "../kselftest_harness.h"
     13
     14/* Remove a file, ignoring the result if it didn't exist. */
     15void rm(struct __test_metadata *_metadata, const char *pathname,
     16	int is_dir)
     17{
     18	int rc;
     19
     20	if (is_dir)
     21		rc = rmdir(pathname);
     22	else
     23		rc = unlink(pathname);
     24
     25	if (rc < 0) {
     26		ASSERT_EQ(errno, ENOENT) {
     27			TH_LOG("Not ENOENT: %s", pathname);
     28		}
     29	} else {
     30		ASSERT_EQ(rc, 0) {
     31			TH_LOG("Failed to remove: %s", pathname);
     32		}
     33	}
     34}
     35
     36FIXTURE(file) {
     37	char *pathname;
     38	int is_dir;
     39};
     40
     41FIXTURE_VARIANT(file)
     42{
     43	const char *name;
     44	int expected;
     45	int is_dir;
     46	void (*setup)(struct __test_metadata *_metadata,
     47		      FIXTURE_DATA(file) *self,
     48		      const FIXTURE_VARIANT(file) *variant);
     49	int major, minor, mode; /* for mknod() */
     50};
     51
     52void setup_link(struct __test_metadata *_metadata,
     53		FIXTURE_DATA(file) *self,
     54		const FIXTURE_VARIANT(file) *variant)
     55{
     56	const char * const paths[] = {
     57		"/bin/true",
     58		"/usr/bin/true",
     59	};
     60	int i;
     61
     62	for (i = 0; i < ARRAY_SIZE(paths); i++) {
     63		if (access(paths[i], X_OK) == 0) {
     64			ASSERT_EQ(symlink(paths[i], self->pathname), 0);
     65			return;
     66		}
     67	}
     68	ASSERT_EQ(1, 0) {
     69		TH_LOG("Could not find viable 'true' binary");
     70	}
     71}
     72
     73FIXTURE_VARIANT_ADD(file, S_IFLNK)
     74{
     75	.name = "S_IFLNK",
     76	.expected = ELOOP,
     77	.setup = setup_link,
     78};
     79
     80void setup_dir(struct __test_metadata *_metadata,
     81	       FIXTURE_DATA(file) *self,
     82	       const FIXTURE_VARIANT(file) *variant)
     83{
     84	ASSERT_EQ(mkdir(self->pathname, 0755), 0);
     85}
     86
     87FIXTURE_VARIANT_ADD(file, S_IFDIR)
     88{
     89	.name = "S_IFDIR",
     90	.is_dir = 1,
     91	.expected = EACCES,
     92	.setup = setup_dir,
     93};
     94
     95void setup_node(struct __test_metadata *_metadata,
     96		FIXTURE_DATA(file) *self,
     97		const FIXTURE_VARIANT(file) *variant)
     98{
     99	dev_t dev;
    100	int rc;
    101
    102	dev = makedev(variant->major, variant->minor);
    103	rc = mknod(self->pathname, 0755 | variant->mode, dev);
    104	ASSERT_EQ(rc, 0) {
    105		if (errno == EPERM)
    106			SKIP(return, "Please run as root; cannot mknod(%s)",
    107				variant->name);
    108	}
    109}
    110
    111FIXTURE_VARIANT_ADD(file, S_IFBLK)
    112{
    113	.name = "S_IFBLK",
    114	.expected = EACCES,
    115	.setup = setup_node,
    116	/* /dev/loop0 */
    117	.major = 7,
    118	.minor = 0,
    119	.mode = S_IFBLK,
    120};
    121
    122FIXTURE_VARIANT_ADD(file, S_IFCHR)
    123{
    124	.name = "S_IFCHR",
    125	.expected = EACCES,
    126	.setup = setup_node,
    127	/* /dev/zero */
    128	.major = 1,
    129	.minor = 5,
    130	.mode = S_IFCHR,
    131};
    132
    133void setup_fifo(struct __test_metadata *_metadata,
    134		FIXTURE_DATA(file) *self,
    135		const FIXTURE_VARIANT(file) *variant)
    136{
    137	ASSERT_EQ(mkfifo(self->pathname, 0755), 0);
    138}
    139
    140FIXTURE_VARIANT_ADD(file, S_IFIFO)
    141{
    142	.name = "S_IFIFO",
    143	.expected = EACCES,
    144	.setup = setup_fifo,
    145};
    146
    147FIXTURE_SETUP(file)
    148{
    149	ASSERT_GT(asprintf(&self->pathname, "%s.test", variant->name), 6);
    150	self->is_dir = variant->is_dir;
    151
    152	rm(_metadata, self->pathname, variant->is_dir);
    153	variant->setup(_metadata, self, variant);
    154}
    155
    156FIXTURE_TEARDOWN(file)
    157{
    158	rm(_metadata, self->pathname, self->is_dir);
    159}
    160
    161TEST_F(file, exec_errno)
    162{
    163	char * const argv[2] = { (char * const)self->pathname, NULL };
    164
    165	EXPECT_LT(execv(argv[0], argv), 0);
    166	EXPECT_EQ(errno, variant->expected);
    167}
    168
    169/* S_IFSOCK */
    170FIXTURE(sock)
    171{
    172	int fd;
    173};
    174
    175FIXTURE_SETUP(sock)
    176{
    177	self->fd = socket(AF_INET, SOCK_STREAM, 0);
    178	ASSERT_GE(self->fd, 0);
    179}
    180
    181FIXTURE_TEARDOWN(sock)
    182{
    183	if (self->fd >= 0)
    184		ASSERT_EQ(close(self->fd), 0);
    185}
    186
    187TEST_F(sock, exec_errno)
    188{
    189	char * const argv[2] = { " magic socket ", NULL };
    190	char * const envp[1] = { NULL };
    191
    192	EXPECT_LT(fexecve(self->fd, argv, envp), 0);
    193	EXPECT_EQ(errno, EACCES);
    194}
    195
    196TEST_HARNESS_MAIN