From 7f160af14246e8819839e1693496c7e2f304a7b8 Mon Sep 17 00:00:00 2001 From: Tom Cherry Date: Mon, 22 Apr 2019 13:28:28 -0700 Subject: [PATCH] init: handle getpeercon() errors Though unlikely, it is possible for getpeercon() to fail. This change adds code to handle this case gracefully. Bug: 130209483 Test: boots, properties are set Change-Id: I3b3fb76b2312a5cbc87c0da2a044be3ddf8aa400 --- init/property_service.cpp | 36 +++++++++++++++++++++++++----------- 1 file changed, 25 insertions(+), 11 deletions(-) diff --git a/init/property_service.cpp b/init/property_service.cpp index bf3b3172d..3ca3bec30 100644 --- a/init/property_service.cpp +++ b/init/property_service.cpp @@ -329,18 +329,20 @@ class SocketConnection { return result == sizeof(value); } + bool GetSourceContext(std::string* source_context) const { + char* c_source_context = nullptr; + if (getpeercon(socket_, &c_source_context) != 0) { + return false; + } + *source_context = c_source_context; + freecon(c_source_context); + return true; + } + int socket() { return socket_; } const ucred& cred() { return cred_; } - std::string source_context() const { - char* source_context = nullptr; - getpeercon(socket_, &source_context); - std::string result = source_context; - freecon(source_context); - return result; - } - private: bool PollIn(uint32_t* timeout_ms) { struct pollfd ufds[1]; @@ -553,10 +555,15 @@ static void handle_property_set_fd() { prop_name[PROP_NAME_MAX-1] = 0; prop_value[PROP_VALUE_MAX-1] = 0; + std::string source_context; + if (!socket.GetSourceContext(&source_context)) { + PLOG(ERROR) << "Unable to set property '" << prop_name << "': getpeercon() failed"; + return; + } + const auto& cr = socket.cred(); std::string error; - uint32_t result = - HandlePropertySet(prop_name, prop_value, socket.source_context(), cr, &error); + uint32_t result = HandlePropertySet(prop_name, prop_value, source_context, cr, &error); if (result != PROP_SUCCESS) { LOG(ERROR) << "Unable to set property '" << prop_name << "' from uid:" << cr.uid << " gid:" << cr.gid << " pid:" << cr.pid << ": " << error; @@ -575,9 +582,16 @@ static void handle_property_set_fd() { return; } + std::string source_context; + if (!socket.GetSourceContext(&source_context)) { + PLOG(ERROR) << "Unable to set property '" << name << "': getpeercon() failed"; + socket.SendUint32(PROP_ERROR_PERMISSION_DENIED); + return; + } + const auto& cr = socket.cred(); std::string error; - uint32_t result = HandlePropertySet(name, value, socket.source_context(), cr, &error); + uint32_t result = HandlePropertySet(name, value, source_context, cr, &error); if (result != PROP_SUCCESS) { LOG(ERROR) << "Unable to set property '" << name << "' from uid:" << cr.uid << " gid:" << cr.gid << " pid:" << cr.pid << ": " << error;