[systemd-devel] [PATCH] install: create_symlink() check unlink() return value
Djalal Harouni
tixxdz at opendz.org
Wed Apr 16 17:47:11 PDT 2014
create_symlink() do not check the return value of unlink(), this may
confuse the user.
Before the unlink() call we check the 'force' argument. If it is not set
we fail with -EEXIST, otherwise we unlink() the file, therefore the next
symlink() should not fail with -EEXIST (do not count races...).
However since callers may not have appropriate privileges to unlink()
the file we lose the -EPERM or any other errno code of unlink(), and
return the -EEXIST of the next symlink(). Fix this by checking unlink()
results.
Before:
$ systemctl --force --root=~/container-03 set-default multi-user.target
Failed to set default target: File exists
After:
$ systemctl --force --root=~/container-03 set-default multi-user.target
Failed to set default target: Permission denied
---
src/shared/install.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/src/shared/install.c b/src/shared/install.c
index 7409046..6334833 100644
--- a/src/shared/install.c
+++ b/src/shared/install.c
@@ -1170,7 +1170,9 @@ static int create_symlink(
if (!force)
return -EEXIST;
- unlink(new_path);
+ r = unlink(new_path);
+ if (r < 0 && errno != ENOENT)
+ return -errno;
if (symlink(old_path, new_path) >= 0) {
add_file_change(changes, n_changes, UNIT_FILE_UNLINK, new_path, NULL);
--
1.9.0
More information about the systemd-devel
mailing list