From: Tomasz Swierczek Date: Tue, 22 Oct 2024 14:52:08 +0000 (+0200) Subject: Add check for CAP_MAC_ADMIN inside prepare_app2 call X-Git-Tag: accepted/tizen/unified/20241030.154513~5 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=c12eab27f9d39c9eaae1703cce51e1472868422e;p=platform%2Fcore%2Fsecurity%2Fsecurity-manager.git Add check for CAP_MAC_ADMIN inside prepare_app2 call Apparently in some weird scenarios, the wrt-loader or other launcher that attempts at running apps, doesn't have the caps required. Added check just prints proper error logs. TODO: libsmack lacks function to get relabel-self list of labels which probably should also be checked in the future (this is why the check for CAP_MAC_ADMIN doesn't exit when there's no capability). Change-Id: I5eeacb5ecb84883f6a4b2097887b82708297e98f --- diff --git a/src/client/client-security-manager.cpp b/src/client/client-security-manager.cpp index 7197f723..ab2ed3af 100644 --- a/src/client/client-security-manager.cpp +++ b/src/client/client-security-manager.cpp @@ -613,6 +613,38 @@ inline static int label_for_self_internal(int tid) return ret < 0 ? -1 : 0; } +// Checks if caller has CAP_MAC_ADMIN configured properly. +// In cases where the capability is missing, this function +// will write proper error logs for faster debugging. +// +// TODO the function would also probably need to check +// list of "relabel-self" labels set in the process, but +// libsmack doesn't have such function available (as of Oct 2024). +// +// Thats why its a void function & it doesn't abort too +// (if capability is missing, we CAN have relabel-self configured). +static inline void security_manager_pre_check() +{ + cap_t my_caps = cap_get_proc(); + if (!my_caps) { + LogError("Unable to allocate capability object"); + return; + } + cap_flag_value_t cap_flags_value; + if (cap_get_flag(my_caps, CAP_MAC_ADMIN, CAP_EFFECTIVE, &cap_flags_value) != 0) { + LogError("Can't check if process has CAP_MAC_ADMIN!!!"); + cap_free(my_caps); + return; + } + if(cap_flags_value != CAP_SET) { + LogWarning("Process ****doesn't**** have effective CAP_MAC_ADMIN!" + " It can still have dyntransition/relabel-self configured"); + cap_free(my_caps); + return; + } + cap_free(my_caps); +} + static inline int security_manager_sync_threads_internal(const std::string &app_label) { static_assert(ATOMIC_INT_LOCK_FREE == 2, "std::atomic is not always lock free"); @@ -1069,6 +1101,7 @@ int security_manager_prepare_app2(const char *app_name, const char *subsession_i (subsession_id ?: "(default)") + ")", Credentials::getCredentialsFromSelf()); return try_catch([&] { + security_manager_pre_check(); std::string appLabel, pkgName; PrepareAppFlags prepareAppFlags;