ueventd: only relabel devices if there's a delta
Since commit: 24a3cbfa732dc14c1a559f4ad79e1700fbae888f
ueventd is attempting to relabel devices on calls to
make_device() when the device already exists. However, it
should only be called if the contexts for relabelfrom and
relabelto are different.
When this condition occurs, one will see denials like this:
[ 14.409448] type=1400 audit(978307239.225:26): avc: denied { relabelfrom } for pid=1572 comm="ueventd" name="ttyS0" dev="tmpfs" ino=9613 scontext=u:r:ueventd:s0 tcontext=u:object_r:hci_attach_dev:s0 tclass=chr_file permissive=1
[ 14.428107] type=1400 audit(978307239.225:27): avc: denied { relabelto } for pid=1572 comm="ueventd" name="ttyS0" dev="tmpfs" ino=9613 scontext=u:r:ueventd:s0 tcontext=u:object_r:hci_attach_dev:s0 tclass=chr_file permissive=1
Bug: 29106809
Change-Id: I2105b169206f0b26420f3c4b0ba5c49aeb98da92
Signed-off-by: William Roberts <william.c.roberts@intel.com>
diff --git a/init/devices.cpp b/init/devices.cpp
index 1410e3b..32fec52 100644
--- a/init/devices.cpp
+++ b/init/devices.cpp
@@ -257,11 +257,25 @@
/* If the node already exists update its SELinux label to handle cases when
* it was created with the wrong context during coldboot procedure. */
if (mknod(path, mode, dev) && (errno == EEXIST)) {
- if (lsetfilecon(path, secontext)) {
+
+ char* fcon = nullptr;
+ int rc = lgetfilecon(path, &fcon);
+ if (rc < 0) {
+ ERROR("Cannot get SELinux label on '%s' device (%s)\n",
+ path, strerror(errno));
+ goto out;
+ }
+
+ bool different = strcmp(fcon, secontext) != 0;
+ freecon(fcon);
+
+ if (different && lsetfilecon(path, secontext)) {
ERROR("Cannot set '%s' SELinux label on '%s' device (%s)\n",
secontext, path, strerror(errno));
}
}
+
+out:
chown(path, uid, -1);
setegid(AID_ROOT);