Check for SELinux labelling errors
It's essential that files created by vold get the correct SELinux
labels, so make sure to check for errors when setting them.
ENOENT (no label defined) is expected on some files such as
/mnt/appfuse/*, so allow ENOENT but log a DEBUG message.
This will help debug b/269567270. This is not a fix for b/269567270.
Bug: 269567270
Test: Created user and checked SELinux labels of user's directories
Test: atest CtsBlobStoreHostTestCases
Change-Id: Ife005bdd896952653943c57336deb33456f7c5d8
diff --git a/Utils.cpp b/Utils.cpp
index 33dbaf6..157b839 100644
--- a/Utils.cpp
+++ b/Utils.cpp
@@ -23,6 +23,7 @@
#include <android-base/file.h>
#include <android-base/logging.h>
#include <android-base/properties.h>
+#include <android-base/scopeguard.h>
#include <android-base/stringprintf.h>
#include <android-base/strings.h>
#include <android-base/unique_fd.h>
@@ -100,13 +101,21 @@
status_t CreateDeviceNode(const std::string& path, dev_t dev) {
std::lock_guard<std::mutex> lock(kSecurityLock);
const char* cpath = path.c_str();
- status_t res = 0;
+ auto clearfscreatecon = android::base::make_scope_guard([] { setfscreatecon(nullptr); });
+ auto secontext = std::unique_ptr<char, void (*)(char*)>(nullptr, freecon);
+ char* tmp_secontext;
- char* secontext = nullptr;
- if (sehandle) {
- if (!selabel_lookup(sehandle, &secontext, cpath, S_IFBLK)) {
- setfscreatecon(secontext);
+ if (selabel_lookup(sehandle, &tmp_secontext, cpath, S_IFBLK) == 0) {
+ secontext.reset(tmp_secontext);
+ if (setfscreatecon(secontext.get()) != 0) {
+ LOG(ERROR) << "Failed to setfscreatecon for device node " << path;
+ return -EINVAL;
}
+ } else if (errno == ENOENT) {
+ LOG(DEBUG) << "No selabel defined for device node " << path;
+ } else {
+ PLOG(ERROR) << "Failed to look up selabel for device node " << path;
+ return -errno;
}
mode_t mode = 0660 | S_IFBLK;
@@ -114,16 +123,10 @@
if (errno != EEXIST) {
PLOG(ERROR) << "Failed to create device node for " << major(dev) << ":" << minor(dev)
<< " at " << path;
- res = -errno;
+ return -errno;
}
}
-
- if (secontext) {
- setfscreatecon(nullptr);
- freecon(secontext);
- }
-
- return res;
+ return OK;
}
status_t DestroyDeviceNode(const std::string& path) {
@@ -449,29 +452,26 @@
unsigned int attrs) {
std::lock_guard<std::mutex> lock(kSecurityLock);
const char* cpath = path.c_str();
+ auto clearfscreatecon = android::base::make_scope_guard([] { setfscreatecon(nullptr); });
+ auto secontext = std::unique_ptr<char, void (*)(char*)>(nullptr, freecon);
+ char* tmp_secontext;
- char* secontext = nullptr;
- if (sehandle) {
- if (!selabel_lookup(sehandle, &secontext, cpath, S_IFDIR)) {
- setfscreatecon(secontext);
+ if (selabel_lookup(sehandle, &tmp_secontext, cpath, S_IFDIR) == 0) {
+ secontext.reset(tmp_secontext);
+ if (setfscreatecon(secontext.get()) != 0) {
+ LOG(ERROR) << "Failed to setfscreatecon for directory " << path;
+ return -EINVAL;
}
- }
-
- int res = fs_prepare_dir(cpath, mode, uid, gid);
-
- if (secontext) {
- setfscreatecon(nullptr);
- freecon(secontext);
- }
-
- if (res) return -errno;
- if (attrs) res = SetAttrs(path, attrs);
-
- if (res == 0) {
- return OK;
+ } else if (errno == ENOENT) {
+ LOG(DEBUG) << "No selabel defined for directory " << path;
} else {
+ PLOG(ERROR) << "Failed to look up selabel for directory " << path;
return -errno;
}
+
+ if (fs_prepare_dir(cpath, mode, uid, gid) != 0) return -errno;
+ if (attrs && SetAttrs(path, attrs) != 0) return -errno;
+ return OK;
}
status_t ForceUnmount(const std::string& path) {