[systemd-commits] 4 commits - TODO src/core src/shared src/tmpfiles
Lennart Poettering
lennart at kemper.freedesktop.org
Tue Jul 10 10:07:16 PDT 2012
TODO | 14 ++++++-
src/core/mount.c | 6 ++-
src/shared/util.c | 96 +++++++++++++++++++++++++++++++++++++++++++-----
src/shared/util.h | 2 +
src/tmpfiles/tmpfiles.c | 2 -
5 files changed, 106 insertions(+), 14 deletions(-)
New commits:
commit 94163dd54328780b4539e7296eb0ba75b7290367
Author: Lennart Poettering <lennart at poettering.net>
Date: Tue Jul 10 19:06:59 2012 +0200
update TODO
diff --git a/TODO b/TODO
index 3d55f8a..a016c29 100644
--- a/TODO
+++ b/TODO
@@ -34,8 +34,6 @@ Bugfixes:
Features:
-* switch-root add extra safety check
-
* switch-root: reopen /dev/console before switching root
* switch-root: sockets need relabelling
commit f56d5db919902851535ac1591d5c95ebcd3a0b17
Author: Lennart Poettering <lennart at poettering.net>
Date: Tue Jul 10 19:05:58 2012 +0200
util: rm_rf() refuse cleaning non-memory file systems, as extra paranoia
diff --git a/src/shared/util.c b/src/shared/util.c
index 8caac7b..62121b5 100644
--- a/src/shared/util.c
+++ b/src/shared/util.c
@@ -3243,7 +3243,7 @@ int get_ctty(pid_t pid, dev_t *_devnr, char **r) {
return 0;
}
-int rm_rf_children(int fd, bool only_dirs, bool honour_sticky, struct stat *root_dev) {
+int rm_rf_children_dangerous(int fd, bool only_dirs, bool honour_sticky, struct stat *root_dev) {
DIR *d;
int ret = 0;
@@ -3335,14 +3335,43 @@ int rm_rf_children(int fd, bool only_dirs, bool honour_sticky, struct stat *root
return ret;
}
-int rm_rf(const char *path, bool only_dirs, bool delete_root, bool honour_sticky) {
- int fd;
- int r;
+int rm_rf_children(int fd, bool only_dirs, bool honour_sticky, struct stat *root_dev) {
+ struct statfs s;
+
+ assert(fd >= 0);
+
+ if (fstatfs(fd, &s) < 0) {
+ close_nointr_nofail(fd);
+ return -errno;
+ }
+
+ /* We refuse to clean disk file systems with this call. This
+ * is extra paranoia just to be sure we never ever remove
+ * non-state data */
+
+ if (s.f_type != TMPFS_MAGIC &&
+ s.f_type != RAMFS_MAGIC) {
+ log_error("Attempted to remove disk file system, and we can't allow that.");
+ close_nointr_nofail(fd);
+ return -EPERM;
+ }
+
+ return rm_rf_children_dangerous(fd, only_dirs, honour_sticky, root_dev);
+}
+
+static int rm_rf_internal(const char *path, bool only_dirs, bool delete_root, bool honour_sticky, bool dangerous) {
+ int fd, r;
+ struct statfs s;
assert(path);
- /* Be paranoid */
- assert(!streq(path, "/"));
+ /* We refuse to clean the root file system with this
+ * call. This is extra paranoia to never cause a really
+ * seriously broken system. */
+ if (path_equal(path, "/")) {
+ log_error("Attempted to remove entire root file system, and we can't allow that.");
+ return -EPERM;
+ }
fd = open(path, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|O_NOFOLLOW|O_NOATIME);
if (fd < 0) {
@@ -3350,6 +3379,17 @@ int rm_rf(const char *path, bool only_dirs, bool delete_root, bool honour_sticky
if (errno != ENOTDIR)
return -errno;
+ if (!dangerous) {
+ if (statfs(path, &s) < 0)
+ return -errno;
+
+ if (s.f_type != TMPFS_MAGIC &&
+ s.f_type != RAMFS_MAGIC) {
+ log_error("Attempted to remove disk file system, and we can't allow that.");
+ return -EPERM;
+ }
+ }
+
if (delete_root && !only_dirs)
if (unlink(path) < 0 && errno != ENOENT)
return -errno;
@@ -3357,8 +3397,21 @@ int rm_rf(const char *path, bool only_dirs, bool delete_root, bool honour_sticky
return 0;
}
- r = rm_rf_children(fd, only_dirs, honour_sticky, NULL);
+ if (!dangerous) {
+ if (fstatfs(fd, &s) < 0) {
+ close_nointr_nofail(fd);
+ return -errno;
+ }
+
+ if (s.f_type != TMPFS_MAGIC &&
+ s.f_type != RAMFS_MAGIC) {
+ log_error("Attempted to remove disk file system, and we can't allow that.");
+ close_nointr_nofail(fd);
+ return -EPERM;
+ }
+ }
+ r = rm_rf_children_dangerous(fd, only_dirs, honour_sticky, NULL);
if (delete_root) {
if (honour_sticky && file_is_priv_sticky(path) > 0)
@@ -3373,6 +3426,14 @@ int rm_rf(const char *path, bool only_dirs, bool delete_root, bool honour_sticky
return r;
}
+int rm_rf(const char *path, bool only_dirs, bool delete_root, bool honour_sticky) {
+ return rm_rf_internal(path, only_dirs, delete_root, honour_sticky, false);
+}
+
+int rm_rf_dangerous(const char *path, bool only_dirs, bool delete_root, bool honour_sticky) {
+ return rm_rf_internal(path, only_dirs, delete_root, honour_sticky, true);
+}
+
int chmod_and_chown(const char *path, mode_t mode, uid_t uid, gid_t gid) {
assert(path);
diff --git a/src/shared/util.h b/src/shared/util.h
index 47497b5..89e9a00 100644
--- a/src/shared/util.h
+++ b/src/shared/util.h
@@ -358,7 +358,9 @@ int chmod_and_chown(const char *path, mode_t mode, uid_t uid, gid_t gid);
int fchmod_and_fchown(int fd, mode_t mode, uid_t uid, gid_t gid);
int rm_rf_children(int fd, bool only_dirs, bool honour_sticky, struct stat *root_dev);
+int rm_rf_children_dangerous(int fd, bool only_dirs, bool honour_sticky, struct stat *root_dev);
int rm_rf(const char *path, bool only_dirs, bool delete_root, bool honour_sticky);
+int rm_rf_dangerous(const char *path, bool only_dirs, bool delete_root, bool honour_sticky);
int pipe_eof(int fd);
diff --git a/src/tmpfiles/tmpfiles.c b/src/tmpfiles/tmpfiles.c
index e0b0e94..2d5d90d 100644
--- a/src/tmpfiles/tmpfiles.c
+++ b/src/tmpfiles/tmpfiles.c
@@ -845,7 +845,7 @@ static int remove_item_instance(Item *i, const char *instance) {
case RECURSIVE_REMOVE_PATH:
/* FIXME: we probably should use dir_cleanup() here
* instead of rm_rf() so that 'x' is honoured. */
- r = rm_rf(instance, false, i->type == RECURSIVE_REMOVE_PATH, false);
+ r = rm_rf_dangerous(instance, false, i->type == RECURSIVE_REMOVE_PATH, false);
if (r < 0 && r != -ENOENT) {
log_error("rm_rf(%s): %s", instance, strerror(-r));
return r;
commit 825c6fe5eb362437aa46faa52b683a62eede9a13
Author: Lennart Poettering <lennart at poettering.net>
Date: Tue Jul 10 18:46:26 2012 +0200
util: add extra safety check to in_initrd()
initrds can only be on tmpfs or ramfs, so check for that
diff --git a/TODO b/TODO
index 96db4a5..3d55f8a 100644
--- a/TODO
+++ b/TODO
@@ -20,6 +20,18 @@ Bugfixes:
* we pull src/core/manager.h into src/shared/src/shared/path-lookup.c which is the wrong direction
rename enum "ManagerRunningAs" to "SystemdRunningAs" and move it to shared/
+* crash happens when running a service as forking and then changing it to simple and reloading.
+
+ Jul 09 18:20:57 mop systemd[1]: usbmuxd.service operation timed out. Terminating.
+ Jul 09 18:20:57 mop systemd[1]: Unit usbmuxd.service entered failed state.
+ Jul 09 18:22:24 mop systemd[1]: PID 21814 read from file /var/run/usbmuxd.pid does not exist.
+ Jul 09 18:22:24 mop systemd[1]: Unit usbmuxd.service entered failed state.
+ Jul 09 18:22:33 mop systemd[1]: Reloading.
+ Jul 09 18:22:37 mop systemd[1]: Assertion 's->type == SERVICE_FORKING' failed at src/core/service.c:3007, function service_sigchld_eve...Aborting.
+ Jul 09 18:22:37 mop systemd[1]: Caught <ABRT>, dumped core as pid 21865.
+ Jul 09 18:22:37 mop systemd[1]: Freezing execution.
+ Jul 09 18:22:37 mop [21866]: Process 21865 (systemd) dumped core.
+
Features:
* switch-root add extra safety check
diff --git a/src/shared/util.c b/src/shared/util.c
index 41505b2..8caac7b 100644
--- a/src/shared/util.c
+++ b/src/shared/util.c
@@ -54,6 +54,8 @@
#include <glob.h>
#include <grp.h>
#include <sys/mman.h>
+#include <sys/vfs.h>
+#include <linux/magic.h>
#include "macro.h"
#include "util.h"
@@ -5738,9 +5740,24 @@ bool is_valid_documentation_url(const char *url) {
bool in_initrd(void) {
static int saved = -1;
+ struct statfs s;
- if (saved < 0)
- saved = access("/etc/initrd-release", F_OK) >= 0;
+ if (saved >= 0)
+ return saved;
+
+ /* We make two checks here:
+ *
+ * 1. the flag file /etc/initrd-release must exist
+ * 2. the root file system must be a memory file system
+ *
+ * The second check is extra paranoia, since misdetecting an
+ * initrd can have bad bad consequences due the initrd
+ * emptying when transititioning to the main systemd.
+ */
+
+ saved = access("/etc/initrd-release", F_OK) >= 0 &&
+ statfs("/", &s) >= 0 &&
+ (s.f_type == TMPFS_MAGIC || s.f_type == RAMFS_MAGIC);
return saved;
}
commit 36fcd77e02cedf300e2f45f2449e7e091ef5a7ab
Author: Malte Starostik <m-starostik at versanet.de>
Date: Tue Jun 5 21:10:28 2012 +0200
mount: fix for complex automounts
If accessing an automount point triggers more changes to
/proc/self/mountinfo than just to add the directly wanted mount, these
changes can lead to spurious -ENODEV notifications on the automount unit
causing the request to fail when in fact the mount will be setup right
afterwards.
diff --git a/src/core/mount.c b/src/core/mount.c
index 69cb6e2..fab922e 100644
--- a/src/core/mount.c
+++ b/src/core/mount.c
@@ -687,8 +687,10 @@ static void mount_set_state(Mount *m, MountState state) {
state == MOUNT_REMOUNTING_SIGKILL ||
state == MOUNT_UNMOUNTING_SIGTERM ||
state == MOUNT_UNMOUNTING_SIGKILL ||
- state == MOUNT_FAILED)
- mount_notify_automount(m, -ENODEV);
+ state == MOUNT_FAILED) {
+ if (state != old_state)
+ mount_notify_automount(m, -ENODEV);
+ }
if (state != old_state)
log_debug("%s changed %s -> %s",
More information about the systemd-commits
mailing list