Skip to content

Commit

Permalink
libselinux: add selinux_unshare() to unshare the SELinux namespace
Browse files Browse the repository at this point in the history
Signed-off-by: Stephen Smalley <stephen.smalley.work@gmail.com>
  • Loading branch information
stephensmalley committed Oct 8, 2024
1 parent b411742 commit 30d7363
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 0 deletions.
9 changes: 9 additions & 0 deletions libselinux/include/selinux/selinux.h
Original file line number Diff line number Diff line change
Expand Up @@ -749,6 +749,15 @@ extern int selinux_lsetfilecon_default(const char *path);
*/
extern void selinux_reset_config(void);

/*
* Unshare the SELinux namespace, unmounting any pre-existing selinuxfs
* mount and mounting a new selinuxfs for the new namespace. Caller
* must have previously done an unshare(CLONE_NEWNS) or clone(CLONE_NEWNS)
* to unshare the mount namespace so that this does not affect other
* mount namespaces.
*/
extern int selinux_unshare(void);

#ifdef __cplusplus
}
#endif
Expand Down
5 changes: 5 additions & 0 deletions libselinux/src/libselinux.map
Original file line number Diff line number Diff line change
Expand Up @@ -252,3 +252,8 @@ LIBSELINUX_3.5 {
getpidprevcon;
getpidprevcon_raw;
} LIBSELINUX_3.4;

LIBSELINUX_3.8 {
global:
selinux_unshare;
} LIBSELINUX_3.5;
54 changes: 54 additions & 0 deletions libselinux/src/unshare.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif

#include <sched.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <sys/mount.h>

#include "selinux_internal.h"
#include "policy.h"

/*
* Precondition: caller must have already done unshare(CLONE_NEWNS) or
* been created via clone(CLONE_NEWNS) so that the selinuxfs mount
* changes do not affect anyone else.
*/
int selinux_unshare(void)
{
int ret, fd;
char buf[3] = "1\n";

/* unmount any previously mounted selinuxfs since it might be read-only */
umount2(SELINUXMNT, MNT_DETACH);

/* mount selinuxfs read-write for the unshare */
ret = mount(SELINUXFS, SELINUXMNT, SELINUXFS, MS_NOEXEC|MS_NOSUID|MS_NODEV, 0);
if (ret < 0)
return -1;

/* unshare SELinux namespace */
fd = open(SELINUXMNT "/unshare", O_WRONLY);
if (fd < 0)
return -1;

ret = write(fd, buf, sizeof(buf));
if (ret != sizeof(buf)) {
int sv_errno = errno;
close(fd);
errno = sv_errno;
return -1;
}
close(fd);

/* mount new selinuxfs instance for this namespace */
umount2(SELINUXMNT, MNT_DETACH);
ret = mount(SELINUXFS, SELINUXMNT, SELINUXFS, MS_NOEXEC|MS_NOSUID|MS_NODEV, 0);
if (ret < 0)
return -1;
return 0;
}

0 comments on commit 30d7363

Please sign in to comment.