if (!n)
return log_oom();
- if (!filename_is_safe(n)) {
+ if (!filename_is_valid(n)) {
log_syntax(unit, LOG_ERR, filename, line, EINVAL,
"Runtime directory is not valid, ignoring assignment: %s", rvalue);
continue;
/* The icon name might ultimately be used as file
* name, so better be safe than sorry */
- if (prop == PROP_ICON_NAME && !filename_is_safe(name))
+ if (prop == PROP_ICON_NAME && !filename_is_valid(name))
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid icon name '%s'", name);
if (prop == PROP_PRETTY_HOSTNAME && string_has_cc(name, NULL))
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid pretty host name '%s'", name);
if (r < 0)
return log_error_errno(r, "Failed to determine coredump file name: %m");
- tmp = tempfn_random(fn);
- if (!tmp)
- return log_oom();
+ r = tempfn_random(fn, &tmp);
+ if (r < 0)
+ return log_error_errno(r, "Failed to determine temporary file name: %m");
mkdir_p_label("/var/lib/systemd/coredump", 0755);
goto uncompressed;
}
- tmp_compressed = tempfn_random(fn_compressed);
- if (!tmp_compressed) {
- log_oom();
+ r = tempfn_random(fn_compressed, &tmp_compressed);
+ if (r < 0) {
+ log_error_errno(r, "Failed to determine temporary file name for %s: %m", fn_compressed);
goto uncompressed;
}
return;
}
- if (!filename_is_safe(e)) {
+ if (!filename_is_valid(e)) {
log_error("Received file in subdirectory of allowed directories. Refusing.");
return;
}
if (!streq_ptr(keymap, c->vc_keymap) ||
!streq_ptr(keymap_toggle, c->vc_keymap_toggle)) {
- if ((keymap && (!filename_is_safe(keymap) || !string_is_safe(keymap))) ||
- (keymap_toggle && (!filename_is_safe(keymap_toggle) || !string_is_safe(keymap_toggle))))
+ if ((keymap && (!filename_is_valid(keymap) || !string_is_safe(keymap))) ||
+ (keymap_toggle && (!filename_is_valid(keymap_toggle) || !string_is_safe(keymap_toggle))))
return sd_bus_error_set_errnof(error, -EINVAL, "Received invalid keymap data");
r = bus_verify_polkit_async(m, CAP_SYS_ADMIN, "org.freedesktop.locale1.set-keyboard", interactive, &c->polkit_registry, error);
if (!b)
return -ENOMEM;
- if (!filename_is_safe(b))
+ if (!filename_is_valid(b))
return -EINVAL;
p = strjoin(dir, "/", unit, ".d", NULL);
if (!utf8_is_valid(name))
return false;
- if (!filename_is_safe(name))
+ if (!filename_is_valid(name))
return false;
if (!string_is_safe(name))
int fopen_temporary(const char *path, FILE **_f, char **_temp_path) {
FILE *f;
char *t;
- int fd;
+ int r, fd;
assert(path);
assert(_f);
assert(_temp_path);
- t = tempfn_xxxxxx(path);
- if (!t)
- return -ENOMEM;
+ r = tempfn_xxxxxx(path, &t);
+ if (r < 0)
+ return r;
fd = mkostemp_safe(t, O_WRONLY|O_CLOEXEC);
if (fd < 0) {
int symlink_atomic(const char *from, const char *to) {
_cleanup_free_ char *t = NULL;
+ int r;
assert(from);
assert(to);
- t = tempfn_random(to);
- if (!t)
- return -ENOMEM;
+ r = tempfn_random(to, &t);
+ if (r < 0)
+ return r;
if (symlink(from, t) < 0)
return -errno;
int mknod_atomic(const char *path, mode_t mode, dev_t dev) {
_cleanup_free_ char *t = NULL;
+ int r;
assert(path);
- t = tempfn_random(path);
- if (!t)
- return -ENOMEM;
+ r = tempfn_random(path, &t);
+ if (r < 0)
+ return r;
if (mknod(t, mode, dev) < 0)
return -errno;
int mkfifo_atomic(const char *path, mode_t mode) {
_cleanup_free_ char *t = NULL;
+ int r;
assert(path);
- t = tempfn_random(path);
- if (!t)
- return -ENOMEM;
+ r = tempfn_random(path, &t);
+ if (r < 0)
+ return r;
if (mkfifo(t, mode) < 0)
return -errno;
return 0;
}
-bool filename_is_safe(const char *p) {
+bool filename_is_valid(const char *p) {
if (isempty(p))
return false;
return 0;
}
-char *tempfn_xxxxxx(const char *p) {
+int tempfn_xxxxxx(const char *p, char **ret) {
const char *fn;
char *t;
- size_t k;
assert(p);
+ assert(ret);
+
+ fn = basename(p);
+ if (!filename_is_valid(fn))
+ return -EINVAL;
t = new(char, strlen(p) + 1 + 6 + 1);
if (!t)
- return NULL;
-
- fn = basename(p);
- k = fn - p;
+ return -ENOMEM;
- strcpy(stpcpy(stpcpy(mempcpy(t, p, k), "."), fn), "XXXXXX");
+ strcpy(stpcpy(stpcpy(mempcpy(t, p, fn - p), "."), fn), "XXXXXX");
- return t;
+ *ret = t;
+ return 0;
}
-char *tempfn_random(const char *p) {
+int tempfn_random(const char *p, char **ret) {
const char *fn;
char *t, *x;
uint64_t u;
- size_t k;
unsigned i;
assert(p);
+ assert(ret);
+
+ fn = basename(p);
+ if (!filename_is_valid(fn))
+ return -EINVAL;
t = new(char, strlen(p) + 1 + 16 + 1);
if (!t)
- return NULL;
-
- fn = basename(p);
- k = fn - p;
+ return -ENOMEM;
- x = stpcpy(stpcpy(mempcpy(t, p, k), "."), fn);
+ x = stpcpy(stpcpy(mempcpy(t, p, fn - p), "."), fn);
u = random_u64();
for (i = 0; i < 16; i++) {
*x = 0;
- return t;
+ *ret = t;
+ return 0;
}
/* make sure the hostname is not "localhost" */
return memdup(p, a * b);
}
-bool filename_is_safe(const char *p) _pure_;
+bool filename_is_valid(const char *p) _pure_;
bool path_is_safe(const char *p) _pure_;
bool string_is_safe(const char *p) _pure_;
bool string_has_cc(const char *p, const char *ok) _pure_;
int fflush_and_check(FILE *f);
-char *tempfn_xxxxxx(const char *p);
-char *tempfn_random(const char *p);
+int tempfn_xxxxxx(const char *p, char **ret);
+int tempfn_random(const char *p, char **ret);
bool is_localhost(const char *hostname);
}
static int create_edit_temp_file(const char *new_path, const char *original_path, char **ret_tmp_fn) {
- int r;
char *t;
+ int r;
assert(new_path);
assert(original_path);
assert(ret_tmp_fn);
- t = tempfn_random(new_path);
- if (!t)
- return log_oom();
+ r = tempfn_random(new_path, &t);
+ if (r < 0)
+ return log_error_errno(r, "Failed to determine temporary filename for %s: %m", new_path);
r = mkdir_parents(new_path, 0755);
if (r < 0) {
assert_se(streq(x, "zzz"));
}
-static void test_filename_is_safe(void) {
+static void test_filename_is_valid(void) {
char foo[FILENAME_MAX+2];
int i;
- assert_se(!filename_is_safe(""));
- assert_se(!filename_is_safe("/bar/foo"));
- assert_se(!filename_is_safe("/"));
- assert_se(!filename_is_safe("."));
- assert_se(!filename_is_safe(".."));
+ assert_se(!filename_is_valid(""));
+ assert_se(!filename_is_valid("/bar/foo"));
+ assert_se(!filename_is_valid("/"));
+ assert_se(!filename_is_valid("."));
+ assert_se(!filename_is_valid(".."));
for (i=0; i<FILENAME_MAX+1; i++)
foo[i] = 'a';
foo[FILENAME_MAX+1] = '\0';
- assert_se(!filename_is_safe(foo));
+ assert_se(!filename_is_valid(foo));
- assert_se(filename_is_safe("foo_bar-333"));
- assert_se(filename_is_safe("o.o"));
+ assert_se(filename_is_valid("foo_bar-333"));
+ assert_se(filename_is_valid("o.o"));
}
static void test_string_has_cc(void) {
test_hexdump();
test_log2i();
test_foreach_string();
- test_filename_is_safe();
+ test_filename_is_valid();
test_string_has_cc();
test_ascii_strlower();
test_files_same();