| 1 | |
| 2 | |
| 3 | * Test which characters may delimit the fields of a register string.
|
| 4 |
|
| 5 | #define _GNU_SOURCE
|
| 6 | #include <stdio.h>
|
| 7 | #include <stdlib.h>
|
| 8 |
|
| 9 | #include "binfmt_misc_common.h"
|
| 10 | #include "kselftest_harness.h"
|
| 11 |
|
| 12 | #define ENTRY "bmdelim"
|
| 13 |
|
| 14 | #define MAGIC "bmmagic"
|
| 15 | #define INTERP "/bin/true"
|
| 16 |
|
| 17 | |
| 18 | * ASCII punctuation without '\' and '/'. The backslash is refused because
|
| 19 | * it would cut a magic that uses \x to escape short. '/' is accepted
|
| 20 | * but cannot delimit a rule that names an absolute interpreter.
|
| 21 |
|
| 22 | #define PUNCTUATION "!\"#$%&'()*+,-.:;<=>?@[]^_`{|}~"
|
| 23 |
|
| 24 |
|
| 25 | #define LETTERS "MEBPOCFTLDqz"
|
| 26 | #define DIGITS "0157"
|
| 27 | #define WHITESPACE " \t\n"
|
| 28 | #define CONTROL "\001\033\177"
|
| 29 | #define NON_ASCII "\200\244\377"
|
| 30 |
|
| 31 |
|
| 32 | static int register_with(char del)
|
| 33 | {
|
| 34 | char rule[128];
|
| 35 |
|
| 36 | snprintf(rule, sizeof(rule), "%c%s%cE%c%c%s%c%c%s%c", del, ENTRY, del,
|
| 37 | del, del, MAGIC, del, del, INTERP, del);
|
| 38 | return write_reg(rule);
|
| 39 | }
|
| 40 |
|
| 41 |
|
| 42 | static void expect_refused(struct __test_metadata *_metadata, const char *set)
|
| 43 | {
|
| 44 | const char *d;
|
| 45 |
|
| 46 | for (d = set; *d; d++) {
|
| 47 | int rc = register_with(*d);
|
| 48 |
|
| 49 | EXPECT_EQ(rc, -1)
|
| 50 | TH_LOG("%#x delimited a register string",
|
| 51 | (unsigned char)*d);
|
| 52 | if (rc == 0) {
|
| 53 | unregister(ENTRY);
|
| 54 | continue;
|
| 55 | }
|
| 56 | EXPECT_EQ(errno, EINVAL);
|
| 57 | }
|
| 58 | }
|
| 59 |
|
| 60 | FIXTURE(delim) {
|
| 61 | };
|
| 62 |
|
| 63 | FIXTURE_SETUP(delim)
|
| 64 | {
|
| 65 | if (getuid() != 0)
|
| 66 | SKIP(return, "test must be run as root");
|
| 67 | if (!binfmt_misc_available())
|
| 68 | SKIP(return, "no binfmt_misc");
|
| 69 |
|
| 70 |
|
| 71 | if (register_with('q') == 0) {
|
| 72 | unregister(ENTRY);
|
| 73 | SKIP(return, "kernel without the delimiter allow-list");
|
| 74 | }
|
| 75 | }
|
| 76 |
|
| 77 | FIXTURE_TEARDOWN(delim)
|
| 78 | {
|
| 79 | unregister(ENTRY);
|
| 80 | }
|
| 81 |
|
| 82 |
|
| 83 | TEST_F(delim, punctuation_accepted)
|
| 84 | {
|
| 85 | const char *d;
|
| 86 |
|
| 87 | for (d = PUNCTUATION; *d; d++) {
|
| 88 | EXPECT_EQ(register_with(*d), 0)
|
| 89 | TH_LOG("'%c' refused with errno %d", *d, errno);
|
| 90 | unregister(ENTRY);
|
| 91 | }
|
| 92 | }
|
| 93 |
|
| 94 |
|
| 95 | TEST_F(delim, letters_refused)
|
| 96 | {
|
| 97 | expect_refused(_metadata, LETTERS);
|
| 98 | }
|
| 99 |
|
| 100 |
|
| 101 | TEST_F(delim, digits_refused)
|
| 102 | {
|
| 103 | expect_refused(_metadata, DIGITS);
|
| 104 | }
|
| 105 |
|
| 106 | TEST_F(delim, whitespace_refused)
|
| 107 | {
|
| 108 | expect_refused(_metadata, WHITESPACE);
|
| 109 | }
|
| 110 |
|
| 111 | TEST_F(delim, control_refused)
|
| 112 | {
|
| 113 | expect_refused(_metadata, CONTROL);
|
| 114 | }
|
| 115 |
|
| 116 | TEST_F(delim, non_ascii_refused)
|
| 117 | {
|
| 118 | expect_refused(_metadata, NON_ASCII);
|
| 119 | }
|
| 120 |
|
| 121 |
|
| 122 | TEST_F(delim, backslash_refused)
|
| 123 | {
|
| 124 | expect_refused(_metadata, "\\");
|
| 125 | }
|
| 126 |
|
| 127 | TEST_HARNESS_MAIN
|