nat: linux-namespaces: Also enter user namespace
Commit Message
From: Benjamin Berg <benjamin@sipsolutions.net>
The use of user namespaces is required for normal users to use mount
namespaces. Also entering the user namespace means that a normal user
can debug processes created that way.
---
gdb/nat/linux-namespaces.c | 19 ++++++++++++++++---
1 file changed, 16 insertions(+), 3 deletions(-)
Comments
>>>>> benjamin--- via Gdb-patches <gdb-patches@sourceware.org> writes:
> From: Benjamin Berg <benjamin@sipsolutions.net>
> The use of user namespaces is required for normal users to use mount
> namespaces. Also entering the user namespace means that a normal user
> can debug processes created that way.
I was going through my email backlog and didn't see a reply to this.
I don't know anything about mount namespaces. How would one test this
patch? Is it possible to modify some existing test to exercise the new
code?
Tom
On Tue, 2023-09-19 at 12:45 -0600, Tom Tromey wrote:
> > > > >
> > From: Benjamin Berg <benjamin@sipsolutions.net>
> > The use of user namespaces is required for normal users to use mount
> > namespaces. Also entering the user namespace means that a normal user
> > can debug processes created that way.
>
> I was going through my email backlog and didn't see a reply to this.
>
> I don't know anything about mount namespaces. How would one test this
> patch? Is it possible to modify some existing test to exercise the new
> code?
You can easily reproduce it by starting a target process as normal user
using:
$ unshare --mount -r target-process
Then, simply try to attach GDB to i. Without the patch, GDB will not be
able to enter the mount namespace unless it is run using e.g. "sudo"
instead of the original user (in the same way as "unshare --mount"
without "-r" will not work for the normal user). With the patch it will
succeed.
The patch works great for me solving my namespaces problem, but I never
checked if there is a test case that could be modified/extended. If
there is a test case, then it would likely already exercise the new
code path and I would also expect such a test to fail already if run as
a non-root user.
Benjamin
Hi Tom,
is there something I can do to unblock this patch?
I need it internally, and it is kind of annoying that I need to rebuild
GDB for this simple fix so that I don't need to run the debugger with
sudo.
Benjamin
On Tue, 2023-09-19 at 12:45 -0600, Tom Tromey wrote:
> > > > > > benjamin--- via Gdb-patches <gdb-patches@sourceware.org>
> > > > > > writes:
>
> > From: Benjamin Berg <benjamin@sipsolutions.net>
> > The use of user namespaces is required for normal users to use
> > mount
> > namespaces. Also entering the user namespace means that a normal
> > user
> > can debug processes created that way.
>
> I was going through my email backlog and didn't see a reply to this.
>
> I don't know anything about mount namespaces. How would one test
> this
> patch? Is it possible to modify some existing test to exercise the
> new
> code?
>
> Tom
>
@@ -880,11 +880,12 @@ enum mnsh_fs_code
static enum mnsh_fs_code
linux_mntns_access_fs (pid_t pid)
{
- struct linux_ns *ns;
+ struct linux_ns *ns, *ns_user;
struct stat sb;
struct linux_mnsh *helper;
ssize_t size;
- int fd;
+ int fd, fd_user = -1;
+ int result, error;
if (pid == getpid ())
return MNSH_FS_DIRECT;
@@ -901,6 +902,8 @@ linux_mntns_access_fs (pid_t pid)
{
int save_errno = errno;
close (fd);
+ if (fd_user >= 0)
+ close (fd_user);
errno = save_errno;
};
@@ -910,13 +913,23 @@ linux_mntns_access_fs (pid_t pid)
if (sb.st_ino == ns->id)
return MNSH_FS_DIRECT;
+ ns_user = linux_ns_get_namespace (LINUX_NS_USER);
+ if (ns_user != NULL)
+ fd_user = gdb_open_cloexec (linux_ns_filename (ns_user, pid), O_RDONLY, 0).release ();
+
helper = linux_mntns_get_helper ();
if (helper == NULL)
return MNSH_FS_ERROR;
if (sb.st_ino != helper->nsid)
{
- int result, error;
+ /* Try to enter user namespace */
+ if (fd_user >= 0)
+ {
+ mnsh_send_setns (helper, fd_user, 0);
+ if (mnsh_recv_int (helper, &result, &error) != 0)
+ warning (_("Could not enter user namespace"));
+ }
size = mnsh_send_setns (helper, fd, 0);
if (size < 0)