blob: 723d0098b39b7484dbdd94f6a2b4ee828a036fcf [file] [log] [blame]
# Prevent nsenter(1) from following basename symlinks. This can allow an
# attacker with a symlink primitive to trick a privileged process into executing
# in a different namespace.
# Unfortunately this solution only protects against basename symlinks, not
# against symlinks in other path components. A more comprehensive solution
# exists and will be sent upstream.
# See b/226186172 for details.
diff --git a/sys-utils/nsenter.c b/sys-utils/nsenter.c
index 4432cd367..c520bf204 100644
--- a/sys-utils/nsenter.c
+++ b/sys-utils/nsenter.c
@@ -112,11 +112,16 @@ static int wd_fd = -1;
static void open_target_fd(int *fd, const char *type, const char *path)
{
char pathbuf[PATH_MAX];
+ int flags = O_NOFOLLOW;
if (!path && namespace_target_pid) {
snprintf(pathbuf, sizeof(pathbuf), "/proc/%u/%s",
namespace_target_pid, type);
path = pathbuf;
+ /* Clear O_NOFOLLOW when opening a path in /proc, because
+ * /proc/<pid>/ns/<type> is a symlink.
+ */
+ flags = 0;
}
if (!path)
errx(EXIT_FAILURE,
@@ -126,9 +131,13 @@ static void open_target_fd(int *fd, const char *type, const char *path)
if (*fd >= 0)
close(*fd);
- *fd = open(path, O_RDONLY);
- if (*fd < 0)
+ *fd = open(path, O_RDONLY | flags);
+ if (*fd < 0) {
+ if (errno == ELOOP)
+ errx(EXIT_FAILURE, _("refusing to follow symlink at %s"), path);
+
err(EXIT_FAILURE, _("cannot open %s"), path);
+ }
}
static void open_namespace_fd(int nstype, const char *path)