| 100 | } |
| 101 | |
| 102 | int main(int argc, char **argv) |
| 103 | { |
| 104 | if (argc != 2) { |
| 105 | fprintf(stderr, "usage: %s <test-dir>\n", argv[0]); |
| 106 | return 2; |
| 107 | } |
| 108 | if (chdir(argv[1]) < 0) { |
| 109 | perror("chdir"); |
| 110 | return 2; |
| 111 | } |
| 112 | |
| 113 | /* secure_relative_open's daemon-only confinement protections only |
| 114 | * fire when am_daemon && !am_chrooted (the threat model is the |
| 115 | * daemon-no-chroot deployment), but the front-door input |
| 116 | * validation runs unconditionally. We set am_daemon anyway so the |
| 117 | * helper exercises the same code shape the receiver does. */ |
| 118 | am_daemon = 1; |
| 119 | am_chrooted = 0; |
| 120 | |
| 121 | mkdir("subdir", 0755); |
| 122 | |
| 123 | /* Each of these relpaths must be rejected with EINVAL at the |
| 124 | * secure_relative_open() front door. ".." is the actual one-level |
| 125 | * escape; the others ("subdir/..", "subdir/../subdir") resolve |
| 126 | * back to the start dir on systems that allow them, but we still |
| 127 | * reject them as defence-in-depth: a path containing a ".." token |
| 128 | * is suspicious and the caller should normalise before passing |
| 129 | * it in. The "../foo" / "foo/../bar" / "/foo" / "/" cases are |
| 130 | * regression checks for the existing checks. */ |
| 131 | check_relpath(".."); |
| 132 | check_relpath("../foo"); |
| 133 | check_relpath("subdir/.."); |
| 134 | check_relpath("subdir/../subdir"); |
| 135 | check_relpath("foo/../bar"); |
| 136 | check_relpath("/foo"); |
| 137 | check_relpath("/"); |
| 138 | |
| 139 | /* Same checks against basedir (which the codex Finding 2 fix |
| 140 | * routes through the same RESOLVE_BENEATH-equivalent). Absolute |
| 141 | * basedirs are operator-trusted and intentionally not validated |
| 142 | * here. */ |
| 143 | check_basedir(".."); |
| 144 | check_basedir("../subdir"); |
| 145 | check_basedir("subdir/.."); |
| 146 | check_basedir("foo/../bar"); |
| 147 | |
| 148 | if (errs) |
| 149 | fprintf(stderr, "\n%d failure(s)\n", errs); |
| 150 | return errs ? 1 : 0; |
| 151 | } |
nothing calls this directly
no test coverage detected