Re: is_selinux_enabled() after chroot()

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Mon, Jun 18, 2018 at 04:06:11PM -0400, Stephen Smalley wrote:
> On 06/18/2018 03:24 PM, Petr Lautrbach wrote:
> > Hello,
> > 
> > libselinux sets selinut_mnt and has_selinux_config only in its constructor and
> > is_selinux_enabled() and others just use selinux_mnt to check if SELinux is
> > enabled. But it doesn't work correctly when you use chroot() to a directory without /proc
> > and /sys/fs/selinux mounted as it was discovered in
> > https://bugzilla.redhat.com/show_bug.cgi?id=1321375 
> > 
> > In this case, is_selinux_enabled() after chroot() returns true while in a new
> > program run from chrooted process it returns false. It can be demonstrated by
> > the steps below.
> > 
> > The solution could be to check if selinux_mnt still exists whenever a function
> > depending on this is called. Would this be acceptable?
> 
> You want to call stat() or access(F_OK) on selinux_mnt and/or SELINUXCONFIG in is_selinux_enabled()?

Yes. I was thinking about something like this:

@@ -16,7 +16,7 @@ int is_selinux_enabled(void)
 #ifdef ANDROID
 	return (selinux_mnt ? 1 : 0);
 #else
-	return (selinux_mnt && has_selinux_config);
+	return (selinux_mnt && (access(selinux_mnt, F_OK) == 0) && has_selinux_config);
 #endif
 }

But the problem seems to be more complex and it would probably be better to fix
it on a callers side - mount /sys/fs/selinux and /proc into chroots or do all
SELinux checks before chroot().

> Could potentially trigger a permission check that wasn't previously required, thereby breaking existing policies.
> Caller might just be checking to see if SELinux is enabled before using interfaces other than selinuxfs (e.g. setexeccon, setfilecon, etc) and therefore didn't previously need permissions to selinuxfs or /etc/selinux/config.
> So, possible but you'd need to make sure you don't break anything.  Definitely don't want that changed in Android.
> > 
> > 
> > 
> > 
> > $ sudo dnf --nogpg --installroot=/var/lib/machines/example  install systemd
> > 
> > $ cat > test_libselinux.c <<EOF
> > #include <selinux/selinux.h>
> > #include <stdio.h>
> > #include <sys/types.h>
> > #include <sys/wait.h>
> > #include <unistd.h>
> > 
> > int main(int argc, char *argv[]) {
> >   pid_t pid;
> >   int wstatus;
> > 
> >   if (argc > 1) {
> >     printf("SELinux in chrooted process: %d\n", is_selinux_enabled());
> >     return 0;
> >   }
> >   if (chroot("/var/lib/machines/example") != 0)
> >     return -1;
> > 
> >   printf("SELinux in process after chroot(): %d\n", is_selinux_enabled());
> >   printf("/sys/fs/selinux exists: %d\n", access("/sys/fs/selinux", F_OK));
> >   printf("/etc/selinux/config exists: %d\n\n", access("/etc/selinux/config", F_OK));
> > 
> >   if ((pid = fork()) == 0 ) {
> >     execv("./test_is_selinux_enabled", (char *[]){ "./test_is_selinux_enabled", "chrooted", NULL});
> >   }
> > 
> >   wait(&wstatus);
> >   return 0;
> > }
> > EOF
> > 
> > $ gcc -o test_is_selinux_enabled test_libselinux.c -lselinux
> > 
> > $ sudo ./test_is_selinux_enabled                            
> > SELinux in process after chroot(): 1
> > /sys/fs/selinux exists: -1
> > /etc/selinux/config exists: -1
> > 
> > SELinux in chrooted process: 0
> > 
> > 
> > 
> > _______________________________________________
> > Selinux mailing list
> > Selinux@xxxxxxxxxxxxx
> > To unsubscribe, send email to Selinux-leave@xxxxxxxxxxxxx.
> > To get help, send an email containing "help" to Selinux-request@xxxxxxxxxxxxx.
> > 
> 

Attachment: signature.asc
Description: PGP signature

_______________________________________________
Selinux mailing list
Selinux@xxxxxxxxxxxxx
To unsubscribe, send email to Selinux-leave@xxxxxxxxxxxxx.
To get help, send an email containing "help" to Selinux-request@xxxxxxxxxxxxx.

[Index of Archives]     [Selinux Refpolicy]     [Linux SGX]     [Fedora Users]     [Fedora Desktop]     [Yosemite Photos]     [Yosemite Camping]     [Yosemite Campsites]     [KDE Users]     [Gnome Users]

  Powered by Linux