return missing_ok ? 0 : -ENOEXEC;
}
- r = path_simplify_and_warn(k, PATH_CHECK_ABSOLUTE | (missing_ok ? 0 : PATH_CHECK_FATAL), unit, filename, line, lvalue);
+ r = path_simplify_and_warn(k, PATH_CHECK_ABSOLUTE|PATH_CHECK_NON_API_VFS|(missing_ok ? 0 : PATH_CHECK_FATAL), unit, filename, line, lvalue);
if (r < 0)
return missing_ok ? 0 : -ENOEXEC;
#include "extract-word.h"
#include "ip-protocol-list.h"
#include "log.h"
+#include "mountpoint-util.h"
#include "parse-helpers.h"
#include "parse-util.h"
#include "path-util.h"
int path_simplify_and_warn(
char *path,
- unsigned flag,
+ PathSimplifyWarnFlags flags,
const char *unit,
const char *filename,
unsigned line,
const char *lvalue) {
- bool fatal = flag & PATH_CHECK_FATAL;
+ bool fatal = flags & PATH_CHECK_FATAL;
- assert(!FLAGS_SET(flag, PATH_CHECK_ABSOLUTE | PATH_CHECK_RELATIVE));
+ assert(path);
+ assert(!FLAGS_SET(flags, PATH_CHECK_ABSOLUTE | PATH_CHECK_RELATIVE));
+ assert(lvalue);
if (!utf8_is_valid(path))
return log_syntax_invalid_utf8(unit, LOG_ERR, filename, line, path);
- if (flag & (PATH_CHECK_ABSOLUTE | PATH_CHECK_RELATIVE)) {
+ if (flags & (PATH_CHECK_ABSOLUTE | PATH_CHECK_RELATIVE)) {
bool absolute;
absolute = path_is_absolute(path);
- if (!absolute && (flag & PATH_CHECK_ABSOLUTE))
+ if (!absolute && (flags & PATH_CHECK_ABSOLUTE))
return log_syntax(unit, LOG_ERR, filename, line, SYNTHETIC_ERRNO(EINVAL),
"%s= path is not absolute%s: %s",
lvalue, fatal ? "" : ", ignoring", path);
- if (absolute && (flag & PATH_CHECK_RELATIVE))
+ if (absolute && (flags & PATH_CHECK_RELATIVE))
return log_syntax(unit, LOG_ERR, filename, line, SYNTHETIC_ERRNO(EINVAL),
"%s= path is absolute%s: %s",
lvalue, fatal ? "" : ", ignoring", path);
}
- path_simplify_full(path, flag & PATH_KEEP_TRAILING_SLASH ? PATH_SIMPLIFY_KEEP_TRAILING_SLASH : 0);
+ path_simplify_full(path, flags & PATH_KEEP_TRAILING_SLASH ? PATH_SIMPLIFY_KEEP_TRAILING_SLASH : 0);
if (!path_is_valid(path))
return log_syntax(unit, LOG_ERR, filename, line, SYNTHETIC_ERRNO(EINVAL),
"%s= path is not normalized%s: %s",
lvalue, fatal ? "" : ", ignoring", path);
+ if (FLAGS_SET(flags, PATH_CHECK_NON_API_VFS) && path_below_api_vfs(path))
+ return log_syntax(unit, LOG_ERR, filename, line, SYNTHETIC_ERRNO(EINVAL),
+ "%s= path is below API VFS%s: %s",
+ lvalue, fatal ? ", refusing" : ", ignoring",
+ path);
+
return 0;
}
#include <stdint.h>
-enum {
- PATH_CHECK_FATAL = 1 << 0, /* If not set, then error message is appended with 'ignoring'. */
- PATH_CHECK_ABSOLUTE = 1 << 1,
- PATH_CHECK_RELATIVE = 1 << 2,
+typedef enum PathSimplifyWarnFlags {
+ PATH_CHECK_FATAL = 1 << 0, /* If not set, then error message is appended with 'ignoring'. */
+ PATH_CHECK_ABSOLUTE = 1 << 1,
+ PATH_CHECK_RELATIVE = 1 << 2,
PATH_KEEP_TRAILING_SLASH = 1 << 3,
-};
+ PATH_CHECK_NON_API_VFS = 1 << 4,
+} PathSimplifyWarnFlags;
int path_simplify_and_warn(
char *path,
- unsigned flag,
+ PathSimplifyWarnFlags flags,
const char *unit,
const char *filename,
unsigned line,
test_invalid_item("ipv6:tcp:6666\n zupa");
}
+static int test_path_simplify_and_warn_one(const char *p, const char *q, PathSimplifyWarnFlags f) {
+ _cleanup_free_ char *s = ASSERT_PTR(strdup(p));
+ int a, b;
+
+ a = path_simplify_and_warn(s, f, /* unit= */ NULL, /* filename= */ NULL, /* line= */ 0, "Foobar=");
+ assert(streq_ptr(s, q));
+
+ free(s);
+ s = ASSERT_PTR(strdup(p));
+
+ b = path_simplify_and_warn(s, f|PATH_CHECK_FATAL, /* unit= */ NULL, /* filename= */ NULL, /* line= */ 0, "Foobar=");
+ assert(streq_ptr(s, q));
+
+ assert(a == b);
+
+ return a;
+}
+
+TEST(path_simplify_and_warn) {
+
+ assert_se(test_path_simplify_and_warn_one("", "", 0) == -EINVAL);
+ assert_se(test_path_simplify_and_warn_one("/", "/", 0) == 0);
+ assert_se(test_path_simplify_and_warn_one("/foo/../bar", "/foo/../bar", 0) == -EINVAL);
+ assert_se(test_path_simplify_and_warn_one("/foo/./bar", "/foo/bar", 0) == 0);
+ assert_se(test_path_simplify_and_warn_one("/proc/self///fd", "/proc/self/fd", 0) == 0);
+ assert_se(test_path_simplify_and_warn_one("/proc/self///fd", "/proc/self/fd", PATH_CHECK_NON_API_VFS) == -EINVAL);
+ assert_se(test_path_simplify_and_warn_one("aaaa", "aaaa", 0) == 0);
+ assert_se(test_path_simplify_and_warn_one("aaaa", "aaaa", PATH_CHECK_ABSOLUTE) == -EINVAL);
+ assert_se(test_path_simplify_and_warn_one("aaaa", "aaaa", PATH_CHECK_RELATIVE) == 0);
+ assert_se(test_path_simplify_and_warn_one("/aaaa", "/aaaa", 0) == 0);
+ assert_se(test_path_simplify_and_warn_one("/aaaa", "/aaaa", PATH_CHECK_ABSOLUTE) == 0);
+ assert_se(test_path_simplify_and_warn_one("/aaaa", "/aaaa", PATH_CHECK_RELATIVE) == -EINVAL);
+
+}
+
DEFINE_TEST_MAIN(LOG_INFO);