Just complete TODO:
* refuse mounting on symlinks

I not add this TODO, but i think what it avoid potential security {and/or} bug issues

if systemd try mounting entry from fstab on symlink, user get something systemctl status symlink.mount
● symlink.mount - /symlink
   Loaded: loaded (/etc/fstab)
   Active: failed (Result: resources)
    Where: /symlink
     What: tmpfs
     Docs: man:fstab(5)
           man:systemd-fstab-generator(8)

Jul 21 19:10:39 beplan.lan systemd[1]: Mounting /symlink...
Jul 21 19:10:39 beplan.lan systemd[1]: symlink.mount: Directory /symlink to mount over is not empty, mounting anyway. Jul 21 19:10:39 beplan.lan systemd[1]: symlink.mount failed to run 'mount' task: Too many levels of symbolic links
Jul 21 19:10:39 beplan.lan systemd[1]: Failed to mount /symlink.
Jul 21 19:10:39 beplan.lan systemd[1]: Unit symlink.mount entered failed state.

can be pulled from:
https://github.com/Nefelim4ag/systemd.git

----
 TODO              |  2 --
 src/core/mount.c  | 13 +++++++++++++
 src/core/mount.h  |  2 ++
 src/shared/util.c | 12 ++++++++++++
 src/shared/util.h |  2 ++
 5 files changed, 29 insertions(+), 2 deletions(-)

diff --git a/TODO b/TODO
index 4a1313d..fd5105d 100644
--- a/TODO
+++ b/TODO
@@ -54,8 +54,6 @@ Features:

* order OnCalendar timer units after timer-sync.target if DefaultDependencies=no so that we don't trigger them prematurely

-* refuse mounting on symlinks
-
 * logind: allow users to kill or lock their own sessions

 * add new gpt type for btrfs volumes
diff --git a/src/core/mount.c b/src/core/mount.c
index 102bbef..6bef486 100644
--- a/src/core/mount.c
+++ b/src/core/mount.c
@@ -826,6 +826,15 @@ void warn_if_dir_nonempty(const char *unit, const char* where) {
                    NULL);
 }

+int fail_if_symlink(const char *unit, const char* where) {
+        assert(where);
+
+        if (!is_symlink(where))
+                return 0;
+
+        return -ELOOP;
+}
+
 static void mount_enter_unmounting(Mount *m) {
         int r;

@@ -876,6 +885,10 @@ static void mount_enter_mounting(Mount *m) {
         if (p && mount_is_bind(p))
                 mkdir_p_label(p->what, m->directory_mode);

+        r = fail_if_symlink(m->meta.id, m->where);
+        if (r < 0)
+                goto fail;
+
         if (m->from_fragment)
                 r = exec_command_set(
                                 m->control_command,
diff --git a/src/core/mount.h b/src/core/mount.h
index 2dcb663..5fc1fe1 100644
--- a/src/core/mount.h
+++ b/src/core/mount.h
@@ -128,3 +128,5 @@ const char* mount_result_to_string(MountResult i) _const_;
 MountResult mount_result_from_string(const char *s) _pure_;

 void warn_if_dir_nonempty(const char *unit, const char* where);
+
+int fail_if_symlink(const char *unit, const char* where);
\ No newline at end of file
diff --git a/src/shared/util.c b/src/shared/util.c
index 4fda31c..d13c6e6 100644
--- a/src/shared/util.c
+++ b/src/shared/util.c
@@ -6866,3 +6866,15 @@ int take_password_lock(const char *root) {

         return fd;
 }
+
+int is_symlink(const char *path) {
+        struct stat info;
+
+        if (lstat(path, &info) < 0)
+                return -errno;
+
+        if (S_ISLNK(info.st_mode))
+                return 1;
+
+        return 0;
+}
\ No newline at end of file
diff --git a/src/shared/util.h b/src/shared/util.h
index d9d525e..90cb45b 100644
--- a/src/shared/util.h
+++ b/src/shared/util.h
@@ -973,3 +973,5 @@ char *tempfn_random(const char *p);
 bool is_localhost(const char *hostname);

 int take_password_lock(const char *root);
+
+int is_symlink(const char *path);
\ No newline at end of file
_______________________________________________
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel

Reply via email to