tmpfiles: add '=' action modifier.
Add the '=' action modifier that instructs tmpfiles.d to check the file type of a path and remove objects that do not match before trying to open or create the path. BUG=chromium:1186405 TEST=./test/test-systemd-tmpfiles.py "$(which systemd-tmpfiles)" Change-Id: If807dc0db427393e9e0047aba640d0d114897c26
This commit is contained in:
committed by
Zbigniew Jędrzejewski-Szmek
parent
90a404f5d4
commit
c46c323385
+1
-1
@@ -733,7 +733,7 @@ int inotify_add_watch_and_warn(int fd, const char *pathname, uint32_t mask) {
|
||||
return wd;
|
||||
}
|
||||
|
||||
static bool unsafe_transition(const struct stat *a, const struct stat *b) {
|
||||
bool unsafe_transition(const struct stat *a, const struct stat *b) {
|
||||
/* Returns true if the transition from a to b is safe, i.e. that we never transition from unprivileged to
|
||||
* privileged files or directories. Why bother? So that unprivileged code can't symlink to privileged files
|
||||
* making us believe we read something safe even though it isn't safe in the specific context we open it in. */
|
||||
|
||||
@@ -94,6 +94,8 @@ enum {
|
||||
CHASE_WARN = 1 << 7, /* Emit an appropriate warning when an error is encountered */
|
||||
};
|
||||
|
||||
bool unsafe_transition(const struct stat *a, const struct stat *b);
|
||||
|
||||
/* How many iterations to execute before returning -ELOOP */
|
||||
#define CHASE_SYMLINKS_MAX 32
|
||||
|
||||
|
||||
+10
-9
@@ -48,11 +48,7 @@ static int patch_dirfd_mode(
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int unlinkat_harder(
|
||||
int dfd,
|
||||
const char *filename,
|
||||
int unlink_flags,
|
||||
RemoveFlags remove_flags) {
|
||||
int unlinkat_harder(int dfd, const char *filename, int unlink_flags, RemoveFlags remove_flags) {
|
||||
|
||||
mode_t old_mode;
|
||||
int r;
|
||||
@@ -77,13 +73,15 @@ static int unlinkat_harder(
|
||||
return r;
|
||||
}
|
||||
|
||||
/* If this worked, we won't reset the old mode, since we'll need it for other entries too, and we
|
||||
* should destroy the whole thing */
|
||||
if (FLAGS_SET(remove_flags, REMOVE_CHMOD_RESTORE) && fchmod(dfd, old_mode) < 0)
|
||||
return -errno;
|
||||
|
||||
/* If this worked, we won't reset the old mode by default, since we'll need it for other entries too,
|
||||
* and we should destroy the whole thing */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fstatat_harder(
|
||||
int dfd,
|
||||
int fstatat_harder(int dfd,
|
||||
const char *filename,
|
||||
struct stat *ret,
|
||||
int fstatat_flags,
|
||||
@@ -109,6 +107,9 @@ static int fstatat_harder(
|
||||
return r;
|
||||
}
|
||||
|
||||
if (FLAGS_SET(remove_flags, REMOVE_CHMOD_RESTORE) && fchmod(dfd, old_mode) < 0)
|
||||
return -errno;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
+9
-1
@@ -12,9 +12,17 @@ typedef enum RemoveFlags {
|
||||
REMOVE_PHYSICAL = 1 << 2, /* If not set, only removes files on tmpfs, never physical file systems */
|
||||
REMOVE_SUBVOLUME = 1 << 3, /* Drop btrfs subvolumes in the tree too */
|
||||
REMOVE_MISSING_OK = 1 << 4, /* If the top-level directory is missing, ignore the ENOENT for it */
|
||||
REMOVE_CHMOD = 1 << 5, /* chmod() for write access if we cannot delete something */
|
||||
REMOVE_CHMOD = 1 << 5, /* chmod() for write access if we cannot delete or access something */
|
||||
REMOVE_CHMOD_RESTORE = 1 << 6, /* Restore the old mode before returning */
|
||||
} RemoveFlags;
|
||||
|
||||
int unlinkat_harder(int dfd, const char *filename, int unlink_flags, RemoveFlags remove_flags);
|
||||
int fstatat_harder(int dfd,
|
||||
const char *filename,
|
||||
struct stat *ret,
|
||||
int fstatat_flags,
|
||||
RemoveFlags remove_flags);
|
||||
|
||||
int rm_rf_children(int fd, RemoveFlags flags, struct stat *root_dev);
|
||||
int rm_rf(const char *path, RemoveFlags flags);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user