Apply correct SELinux labels to PDX endpoint and channel sockets.
Bug: 37646189
Test: Compiled for sailfish-eng
Device booted, normal 2D UI works as before
Was able to run Daydream app and CubeSea (before O1 VR rendering
path was disabled by recent change in HW composer).
Change-Id: I1f7040324992d3c784f072ea6b64a65fa7ed0589
diff --git a/libs/vr/libpdx_uds/Android.bp b/libs/vr/libpdx_uds/Android.bp
index cfc2022..82a5ea7 100644
--- a/libs/vr/libpdx_uds/Android.bp
+++ b/libs/vr/libpdx_uds/Android.bp
@@ -24,6 +24,9 @@
"libbase",
"libpdx",
],
+ whole_static_libs: [
+ "libselinux",
+ ],
}
cc_test {
diff --git a/libs/vr/libpdx_uds/service_endpoint.cpp b/libs/vr/libpdx_uds/service_endpoint.cpp
index d96eeff..27a56f9 100644
--- a/libs/vr/libpdx_uds/service_endpoint.cpp
+++ b/libs/vr/libpdx_uds/service_endpoint.cpp
@@ -11,6 +11,7 @@
#include <android-base/strings.h>
#include <cutils/sockets.h>
#include <pdx/service.h>
+#include <selinux/selinux.h>
#include <uds/channel_manager.h>
#include <uds/client_channel_factory.h>
#include <uds/ipc_helper.h>
@@ -364,6 +365,36 @@
Status<void> Endpoint::CreateChannelSocketPair(LocalHandle* local_socket,
LocalHandle* remote_socket) {
Status<void> status;
+ char* endpoint_context = nullptr;
+ // Make sure the channel socket has the correct SELinux label applied.
+ // Here we get the label from the endpoint file descriptor, which should be
+ // something like "u:object_r:pdx_service_endpoint_socket:s0" and replace
+ // "endpoint" with "channel" to produce the channel label such as this:
+ // "u:object_r:pdx_service_channel_socket:s0".
+ if (fgetfilecon_raw(socket_fd_.Get(), &endpoint_context) > 0) {
+ std::string channel_context = endpoint_context;
+ freecon(endpoint_context);
+ const std::string suffix = "_endpoint_socket";
+ auto pos = channel_context.find(suffix);
+ if (pos != std::string::npos) {
+ channel_context.replace(pos, suffix.size(), "_channel_socket");
+ } else {
+ ALOGW(
+ "Endpoint::CreateChannelSocketPair: Endpoint security context '%s' "
+ "does not contain expected substring '%s'",
+ channel_context.c_str(), suffix.c_str());
+ }
+ ALOGE_IF(setsockcreatecon_raw(channel_context.c_str()) == -1,
+ "Endpoint::CreateChannelSocketPair: Failed to set channel socket "
+ "security context: %s",
+ strerror(errno));
+ } else {
+ ALOGE(
+ "Endpoint::CreateChannelSocketPair: Failed to obtain the endpoint "
+ "socket's security context: %s",
+ strerror(errno));
+ }
+
int channel_pair[2] = {};
if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, channel_pair) == -1) {
ALOGE("Endpoint::CreateChannelSocketPair: Failed to create socket pair: %s",
@@ -372,6 +403,8 @@
return status;
}
+ setsockcreatecon_raw(nullptr);
+
local_socket->Reset(channel_pair[0]);
remote_socket->Reset(channel_pair[1]);