Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0+
0002 #include <errno.h>
0003 #include <fcntl.h>
0004 #include <stdio.h>
0005 #include <string.h>
0006 #include <unistd.h>
0007 #include <sys/socket.h>
0008 #include <sys/stat.h>
0009 #include <sys/sysmacros.h>
0010 #include <sys/types.h>
0011 
0012 #include "../kselftest_harness.h"
0013 
0014 /* Remove a file, ignoring the result if it didn't exist. */
0015 void rm(struct __test_metadata *_metadata, const char *pathname,
0016     int is_dir)
0017 {
0018     int rc;
0019 
0020     if (is_dir)
0021         rc = rmdir(pathname);
0022     else
0023         rc = unlink(pathname);
0024 
0025     if (rc < 0) {
0026         ASSERT_EQ(errno, ENOENT) {
0027             TH_LOG("Not ENOENT: %s", pathname);
0028         }
0029     } else {
0030         ASSERT_EQ(rc, 0) {
0031             TH_LOG("Failed to remove: %s", pathname);
0032         }
0033     }
0034 }
0035 
0036 FIXTURE(file) {
0037     char *pathname;
0038     int is_dir;
0039 };
0040 
0041 FIXTURE_VARIANT(file)
0042 {
0043     const char *name;
0044     int expected;
0045     int is_dir;
0046     void (*setup)(struct __test_metadata *_metadata,
0047               FIXTURE_DATA(file) *self,
0048               const FIXTURE_VARIANT(file) *variant);
0049     int major, minor, mode; /* for mknod() */
0050 };
0051 
0052 void setup_link(struct __test_metadata *_metadata,
0053         FIXTURE_DATA(file) *self,
0054         const FIXTURE_VARIANT(file) *variant)
0055 {
0056     const char * const paths[] = {
0057         "/bin/true",
0058         "/usr/bin/true",
0059     };
0060     int i;
0061 
0062     for (i = 0; i < ARRAY_SIZE(paths); i++) {
0063         if (access(paths[i], X_OK) == 0) {
0064             ASSERT_EQ(symlink(paths[i], self->pathname), 0);
0065             return;
0066         }
0067     }
0068     ASSERT_EQ(1, 0) {
0069         TH_LOG("Could not find viable 'true' binary");
0070     }
0071 }
0072 
0073 FIXTURE_VARIANT_ADD(file, S_IFLNK)
0074 {
0075     .name = "S_IFLNK",
0076     .expected = ELOOP,
0077     .setup = setup_link,
0078 };
0079 
0080 void setup_dir(struct __test_metadata *_metadata,
0081            FIXTURE_DATA(file) *self,
0082            const FIXTURE_VARIANT(file) *variant)
0083 {
0084     ASSERT_EQ(mkdir(self->pathname, 0755), 0);
0085 }
0086 
0087 FIXTURE_VARIANT_ADD(file, S_IFDIR)
0088 {
0089     .name = "S_IFDIR",
0090     .is_dir = 1,
0091     .expected = EACCES,
0092     .setup = setup_dir,
0093 };
0094 
0095 void setup_node(struct __test_metadata *_metadata,
0096         FIXTURE_DATA(file) *self,
0097         const FIXTURE_VARIANT(file) *variant)
0098 {
0099     dev_t dev;
0100     int rc;
0101 
0102     dev = makedev(variant->major, variant->minor);
0103     rc = mknod(self->pathname, 0755 | variant->mode, dev);
0104     ASSERT_EQ(rc, 0) {
0105         if (errno == EPERM)
0106             SKIP(return, "Please run as root; cannot mknod(%s)",
0107                 variant->name);
0108     }
0109 }
0110 
0111 FIXTURE_VARIANT_ADD(file, S_IFBLK)
0112 {
0113     .name = "S_IFBLK",
0114     .expected = EACCES,
0115     .setup = setup_node,
0116     /* /dev/loop0 */
0117     .major = 7,
0118     .minor = 0,
0119     .mode = S_IFBLK,
0120 };
0121 
0122 FIXTURE_VARIANT_ADD(file, S_IFCHR)
0123 {
0124     .name = "S_IFCHR",
0125     .expected = EACCES,
0126     .setup = setup_node,
0127     /* /dev/zero */
0128     .major = 1,
0129     .minor = 5,
0130     .mode = S_IFCHR,
0131 };
0132 
0133 void setup_fifo(struct __test_metadata *_metadata,
0134         FIXTURE_DATA(file) *self,
0135         const FIXTURE_VARIANT(file) *variant)
0136 {
0137     ASSERT_EQ(mkfifo(self->pathname, 0755), 0);
0138 }
0139 
0140 FIXTURE_VARIANT_ADD(file, S_IFIFO)
0141 {
0142     .name = "S_IFIFO",
0143     .expected = EACCES,
0144     .setup = setup_fifo,
0145 };
0146 
0147 FIXTURE_SETUP(file)
0148 {
0149     ASSERT_GT(asprintf(&self->pathname, "%s.test", variant->name), 6);
0150     self->is_dir = variant->is_dir;
0151 
0152     rm(_metadata, self->pathname, variant->is_dir);
0153     variant->setup(_metadata, self, variant);
0154 }
0155 
0156 FIXTURE_TEARDOWN(file)
0157 {
0158     rm(_metadata, self->pathname, self->is_dir);
0159 }
0160 
0161 TEST_F(file, exec_errno)
0162 {
0163     char * const argv[2] = { (char * const)self->pathname, NULL };
0164 
0165     EXPECT_LT(execv(argv[0], argv), 0);
0166     EXPECT_EQ(errno, variant->expected);
0167 }
0168 
0169 /* S_IFSOCK */
0170 FIXTURE(sock)
0171 {
0172     int fd;
0173 };
0174 
0175 FIXTURE_SETUP(sock)
0176 {
0177     self->fd = socket(AF_INET, SOCK_STREAM, 0);
0178     ASSERT_GE(self->fd, 0);
0179 }
0180 
0181 FIXTURE_TEARDOWN(sock)
0182 {
0183     if (self->fd >= 0)
0184         ASSERT_EQ(close(self->fd), 0);
0185 }
0186 
0187 TEST_F(sock, exec_errno)
0188 {
0189     char * const argv[2] = { " magic socket ", NULL };
0190     char * const envp[1] = { NULL };
0191 
0192     EXPECT_LT(fexecve(self->fd, argv, envp), 0);
0193     EXPECT_EQ(errno, EACCES);
0194 }
0195 
0196 TEST_HARNESS_MAIN