With Linux user namespaces, why can clone() mount /proc, but unshare() cannot?

Clash Royale CLAN TAG#URR8PPP
up vote
0
down vote
favorite
I am trying to get a non-root user to mount /proc in a Linux user namespace.
If I create a namespace via clone(), then I can mount /proc.
However, if I create a namespace via unshare(), then the call to mount() fails with Operation not permitted.
Why does mount() behave differently when the namespace is created with clone() as opposed to unshare()?
The below code demonstrates the difference.
#define _GNU_SOURCE
#include <errno.h>
#include <sched.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/syscall.h>
#include <sys/mount.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <fcntl.h>
#define STACK_SIZE (1024 * 1024)
static char child_stack[STACK_SIZE]; /* Space for child's stack */
void try ( const char * msg, int rv )
printf ( "%-8s %6d %sn", msg, rv, strerror ( rv < 0 ? errno : 0 ) );
int child ( void * arg )
try( "mount_1", mount ( "PROC", "/proc", "proc", 0, NULL ));
try( "umount_1", umount ( "/proc" ));
return 0;
int main ()
int clone_flags = 0;
clone_flags
Output:
clone 31478 Success
mount_1 0 Success
umount_1 0 Success
wait 31478 Success
unshare 0 Success
mount_2 -1 Operation not permitted
I am running on Ubuntu 18.04 with kernel Linux 4.15.0-20-generic. I am running the above code as non-root.
mount proc namespace unshare clone
add a comment |
up vote
0
down vote
favorite
I am trying to get a non-root user to mount /proc in a Linux user namespace.
If I create a namespace via clone(), then I can mount /proc.
However, if I create a namespace via unshare(), then the call to mount() fails with Operation not permitted.
Why does mount() behave differently when the namespace is created with clone() as opposed to unshare()?
The below code demonstrates the difference.
#define _GNU_SOURCE
#include <errno.h>
#include <sched.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/syscall.h>
#include <sys/mount.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <fcntl.h>
#define STACK_SIZE (1024 * 1024)
static char child_stack[STACK_SIZE]; /* Space for child's stack */
void try ( const char * msg, int rv )
printf ( "%-8s %6d %sn", msg, rv, strerror ( rv < 0 ? errno : 0 ) );
int child ( void * arg )
try( "mount_1", mount ( "PROC", "/proc", "proc", 0, NULL ));
try( "umount_1", umount ( "/proc" ));
return 0;
int main ()
int clone_flags = 0;
clone_flags
Output:
clone 31478 Success
mount_1 0 Success
umount_1 0 Success
wait 31478 Success
unshare 0 Success
mount_2 -1 Operation not permitted
I am running on Ubuntu 18.04 with kernel Linux 4.15.0-20-generic. I am running the above code as non-root.
mount proc namespace unshare clone
add a comment |
up vote
0
down vote
favorite
up vote
0
down vote
favorite
I am trying to get a non-root user to mount /proc in a Linux user namespace.
If I create a namespace via clone(), then I can mount /proc.
However, if I create a namespace via unshare(), then the call to mount() fails with Operation not permitted.
Why does mount() behave differently when the namespace is created with clone() as opposed to unshare()?
The below code demonstrates the difference.
#define _GNU_SOURCE
#include <errno.h>
#include <sched.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/syscall.h>
#include <sys/mount.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <fcntl.h>
#define STACK_SIZE (1024 * 1024)
static char child_stack[STACK_SIZE]; /* Space for child's stack */
void try ( const char * msg, int rv )
printf ( "%-8s %6d %sn", msg, rv, strerror ( rv < 0 ? errno : 0 ) );
int child ( void * arg )
try( "mount_1", mount ( "PROC", "/proc", "proc", 0, NULL ));
try( "umount_1", umount ( "/proc" ));
return 0;
int main ()
int clone_flags = 0;
clone_flags
Output:
clone 31478 Success
mount_1 0 Success
umount_1 0 Success
wait 31478 Success
unshare 0 Success
mount_2 -1 Operation not permitted
I am running on Ubuntu 18.04 with kernel Linux 4.15.0-20-generic. I am running the above code as non-root.
mount proc namespace unshare clone
I am trying to get a non-root user to mount /proc in a Linux user namespace.
If I create a namespace via clone(), then I can mount /proc.
However, if I create a namespace via unshare(), then the call to mount() fails with Operation not permitted.
Why does mount() behave differently when the namespace is created with clone() as opposed to unshare()?
The below code demonstrates the difference.
#define _GNU_SOURCE
#include <errno.h>
#include <sched.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/syscall.h>
#include <sys/mount.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <fcntl.h>
#define STACK_SIZE (1024 * 1024)
static char child_stack[STACK_SIZE]; /* Space for child's stack */
void try ( const char * msg, int rv )
printf ( "%-8s %6d %sn", msg, rv, strerror ( rv < 0 ? errno : 0 ) );
int child ( void * arg )
try( "mount_1", mount ( "PROC", "/proc", "proc", 0, NULL ));
try( "umount_1", umount ( "/proc" ));
return 0;
int main ()
int clone_flags = 0;
clone_flags
Output:
clone 31478 Success
mount_1 0 Success
umount_1 0 Success
wait 31478 Success
unshare 0 Success
mount_2 -1 Operation not permitted
I am running on Ubuntu 18.04 with kernel Linux 4.15.0-20-generic. I am running the above code as non-root.
mount proc namespace unshare clone
mount proc namespace unshare clone
asked 3 hours ago
mpb
379110
379110
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
up vote
2
down vote
accepted
Maybe because you're still in the "wrong" PID namespace, and that means you don't have permission to mount the procfs instance?
CLONE_NEWPID [...] The calling process is
not moved into the new namespace. The first child created by
the calling process will have the process ID 1 and will assume
the role of init(1) in the new namespace.
http://man7.org/linux/man-pages/man2/unshare.2.html
Compare
CLONE_NEWPID [...]
If CLONE_NEWPID is set, then create the process in a new PID
namespace.
http://man7.org/linux/man-pages/man2/clone.2.html
It certainly appears you are correct. If Iunshare()followed by afork(), then the child process can mount/proc. Thanks!
– mpb
58 mins ago
add a comment |
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
2
down vote
accepted
Maybe because you're still in the "wrong" PID namespace, and that means you don't have permission to mount the procfs instance?
CLONE_NEWPID [...] The calling process is
not moved into the new namespace. The first child created by
the calling process will have the process ID 1 and will assume
the role of init(1) in the new namespace.
http://man7.org/linux/man-pages/man2/unshare.2.html
Compare
CLONE_NEWPID [...]
If CLONE_NEWPID is set, then create the process in a new PID
namespace.
http://man7.org/linux/man-pages/man2/clone.2.html
It certainly appears you are correct. If Iunshare()followed by afork(), then the child process can mount/proc. Thanks!
– mpb
58 mins ago
add a comment |
up vote
2
down vote
accepted
Maybe because you're still in the "wrong" PID namespace, and that means you don't have permission to mount the procfs instance?
CLONE_NEWPID [...] The calling process is
not moved into the new namespace. The first child created by
the calling process will have the process ID 1 and will assume
the role of init(1) in the new namespace.
http://man7.org/linux/man-pages/man2/unshare.2.html
Compare
CLONE_NEWPID [...]
If CLONE_NEWPID is set, then create the process in a new PID
namespace.
http://man7.org/linux/man-pages/man2/clone.2.html
It certainly appears you are correct. If Iunshare()followed by afork(), then the child process can mount/proc. Thanks!
– mpb
58 mins ago
add a comment |
up vote
2
down vote
accepted
up vote
2
down vote
accepted
Maybe because you're still in the "wrong" PID namespace, and that means you don't have permission to mount the procfs instance?
CLONE_NEWPID [...] The calling process is
not moved into the new namespace. The first child created by
the calling process will have the process ID 1 and will assume
the role of init(1) in the new namespace.
http://man7.org/linux/man-pages/man2/unshare.2.html
Compare
CLONE_NEWPID [...]
If CLONE_NEWPID is set, then create the process in a new PID
namespace.
http://man7.org/linux/man-pages/man2/clone.2.html
Maybe because you're still in the "wrong" PID namespace, and that means you don't have permission to mount the procfs instance?
CLONE_NEWPID [...] The calling process is
not moved into the new namespace. The first child created by
the calling process will have the process ID 1 and will assume
the role of init(1) in the new namespace.
http://man7.org/linux/man-pages/man2/unshare.2.html
Compare
CLONE_NEWPID [...]
If CLONE_NEWPID is set, then create the process in a new PID
namespace.
http://man7.org/linux/man-pages/man2/clone.2.html
answered 3 hours ago
sourcejedi
21.5k43396
21.5k43396
It certainly appears you are correct. If Iunshare()followed by afork(), then the child process can mount/proc. Thanks!
– mpb
58 mins ago
add a comment |
It certainly appears you are correct. If Iunshare()followed by afork(), then the child process can mount/proc. Thanks!
– mpb
58 mins ago
It certainly appears you are correct. If I
unshare() followed by a fork(), then the child process can mount /proc. Thanks!– mpb
58 mins ago
It certainly appears you are correct. If I
unshare() followed by a fork(), then the child process can mount /proc. Thanks!– mpb
58 mins ago
add a comment |
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f480873%2fwith-linux-user-namespaces-why-can-clone-mount-proc-but-unshare-cannot%23new-answer', 'question_page');
);
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password