[systemd-devel] [PATCH] Refuse mount on symlink
Timofey Titovets
nefelim4ag at gmail.com
Sat Jul 19 06:15:54 PDT 2014
Just completed TODO:
* refuse mounting on symlinks
If systemd try mounting entry from fstab on symlink, user get something
like that:
Jul 19 15:49:38 beplan.lan systemd[1]: Mounting /var/tmp/lol1...
Jul 19 15:49:38 beplan.lan systemd[1]: var-tmp-lol1.mount Refuse mount
on symlink: Operation not permitted
Can be pulled from:
https://github.com/Nefelim4ag/systemd.git
----
TODO | 2 --
src/core/mount.c | 17 +++++++++++++++++
src/core/mount.h | 2 ++
src/shared/util.c | 11 +++++++++++
src/shared/util.h | 2 ++
5 files changed, 32 insertions(+), 2 deletions(-)
diff --git a/TODO b/TODO
index bfa06de..be58ff3 100644
--- a/TODO
+++ b/TODO
@@ -55,8 +55,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..e5e8e94 100644
--- a/src/core/mount.c
+++ b/src/core/mount.c
@@ -826,6 +826,19 @@ 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;
+
+ log_warning_unit(unit,
+ "%s Refuse mount on symlink: %s",
+ unit, strerror(1));
+
+ return -1;
+}
+
static void mount_enter_unmounting(Mount *m) {
int r;
@@ -876,6 +889,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..f389e74 100644
--- a/src/shared/util.c
+++ b/src/shared/util.c
@@ -6866,3 +6866,14 @@ int take_password_lock(const char *root) {
return fd;
}
+
+bool is_symlink(const char *path) {
+ struct stat info;
+
+ lstat(path, &info);
+
+ 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..6a438b7 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);
+
+bool is_symlink(const char *path);
\ No newline at end of file
More information about the systemd-devel
mailing list