Subject: Segmentation fault when using cp -a with SELinux and fakeroot

From: Nicolas Iooss <[email-masked]>
Date: Fri, 03 Jan 2014 23:08:42 +0100

Hello,

After upgrading to coreutils 8.22 I can no longer build packages which
uses "cp -a" to copy files due to a segmentation fault happening in
libselinux.

I've tried to reproduce this bug with few commands, in a directory which
doesn't have any default context:

    $ mkdir /tmp/foobar
    $ matchpathcon
    /tmp/foobar	<<none>>
    $ touch /tmp/foobar/a
    $ fakeroot cp -a /tmp/foobar/a /tmp/foobar/b
    $ fakeroot cp -a /tmp/foobar/a /tmp/foobar/b
    /usr/bin/fakeroot: line 181:  9207 Segmentation fault

Without fakeroot there is no segmentation fault.

Even if the message says "/usr/bin/fakeroot", a coredump has been
created for cp. I've analyzed this dump using gdb and after some
debugging, I found out that restorecon_private (from src/selinux.c) was
calling lsetfilecon with a NULL security context which was obtained by
getfscreatecon (case "local = true" in the code [1]). This causes a null
pointer dereference in libselinux and so a SIGSEGV.

I've reported this bug to libselinux maintainers [2] and got the reply
that calling lsetfilecon with a NULL security context was like calling
strlen with a NULL string and that this was a problem in caller's code [3].

Hence I propose the attached patch to fix the segmentation fault. Could
you please accept it?

When you reply, please Cc me as I'm not subscribed.

Thanks,

Nicolas Iooss

-----------

System configuration during my tests:

* distro: ArchLinux which SELinux packages
* CPU arch: x86_64
* SELinux in permissive mode
* coreutils 8.22
* libselinux 2.2.1
* fakeroot 1.20

[1]
http://git.savannah.gnu.org/gitweb/?p=coreutils.git;a=blob;f=src/selinux.c;hb=v8.22#l191
[2] http://marc.info/?l=selinux&m=138763485330568&w=2
[3] http://marc.info/?l=selinux&m=138842015508829&w=2
>>From 2d9940379927d2536675a7970f16767e4d209f27 Mon Sep 17 00:00:00 2001
From: Nicolas Iooss <[email-masked]>
Date: Fri, 3 Jan 2014 22:47:17 +0100
Subject: [PATCH] Fix segmentation fault in restorecon_private

---
 src/selinux.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/selinux.c b/src/selinux.c
index cd38a81..e4deba3 100644
--- a/src/selinux.c
+++ b/src/selinux.c
@@ -190,7 +190,7 @@ restorecon_private (char const *path, bool local)
 
   if (local)
     {
-      if (getfscreatecon (&tcon) < 0)
+      if (getfscreatecon (&tcon) < 0 || tcon == NULL)
         return rc;
       rc = lsetfilecon (path, tcon);
       freecon (tcon);
-- 
1.8.5.2