Add access control for daemon 53/323753/2
authorjusung son <jusung07.son@samsung.com>
Wed, 7 May 2025 06:08:29 +0000 (15:08 +0900)
committerjusung son <jusung07.son@samsung.com>
Wed, 7 May 2025 06:13:04 +0000 (15:13 +0900)
Change-Id: I1a6436f53c16a787cedbefc715de47aa6de9499a
Signed-off-by: jusung son <jusung07.son@samsung.com>
13 files changed:
idlc/gen/version2/c_body_generator_base.cc
idlc/gen/version2/c_body_generator_base.hh
idlc/gen/version2/c_body_generator_base_cb.hh
idlc/gen/version2/c_stub_body_generator.cc
idlc/gen/version2/c_stub_body_generator.hh
idlc/gen/version2/c_stub_body_generator_cb.hh
idlc/gen/version2/cpp_generator_base.cc
idlc/gen/version2/cpp_generator_base.hh
idlc/gen/version2/cpp_generator_base_cb.hh
idlc/gen/version2/cpp_stub_body_generator.cc
idlc/gen/version2/cpp_stub_body_generator_cb.hh
idlc/gen/version2/cpp_stub_header_generator_cb.hh
idlc/gen/version2/rs_stub_gen_cb.h

index 2d6fe7c6266c4a12d70acde3c635555543e64c53..ceba75d7ed999af63d1072498846c977983c5dfc 100644 (file)
@@ -107,6 +107,10 @@ void CBodyGeneratorBase::AddTypeName(const Structure& st) {
   struct_types_[std::move(name)] = std::move(type_name);
 }
 
+void CBodyGeneratorBase::GetRpcPortInternalAPIs(std::ofstream& stream) {
+  stream << SmartIndent(CB_RPC_PORT_INTERNAL_APIS);
+}
+
 void CBodyGeneratorBase::GenIncludeLemHeaders(std::ofstream& stream) {
   stream << SmartIndent(CB_LEM_HEADER);
 }
index 4444889d20130b32d541d3a5d20d2abad228a959..a1b7b89c0e3c367d243f26bc3b6fabdedc5fc4ff 100644 (file)
@@ -41,6 +41,7 @@ class CBodyGeneratorBase : public tidl::CBodyGeneratorBase {
   std::string GetHandlePrefixReverse();
   void GenRemoteExceptionDefinition(std::ofstream& stream);
   void GenRemoteExceptionBase(std::ofstream& stream);
+  void GetRpcPortInternalAPIs(std::ofstream& stream);
 
  private:
   void AddTypeName(const Structure& st);
index 1ae929de3b29908853676e2350946415d8cf7e22..66f2a94e3fd858022dad7d10ce142ff5358a3cc8 100644 (file)
@@ -1273,6 +1273,32 @@ int <PREFIX>_remote_exception_throw(<PREFIX>_remote_exception_h h)
 }
 )__cpp_cb";
 
+constexpr const char CB_RPC_PORT_INTERNAL_APIS[] =
+R"__cpp_cb(
+
+typedef int (*rpc_port_get_peer_info_t)(rpc_port_h h, pid_t* pid, uid_t* uid);
+
+static rpc_port_get_peer_info_t rpc_port_get_peer_info;
+
+static bool rpc_port_internal_loaded;
+
+static void rpc_port_internal_init(void)
+{
+    if (rpc_port_internal_loaded)
+      return;
+
+    const char * symbol = "rpc_port_get_peer_info";
+    rpc_port_get_peer_info = dlsym(RTLD_DEFAULT, symbol);
+    if (rpc_port_get_peer_info == nullptr) {
+      _E("Failed to find symbol(%s). Please check rpc-port version", symbol);
+      return;
+    }
+
+    rpc_port_internal_loaded = true;
+}
+
+)__cpp_cb";
+
 }  // namespace version2
 }  // namespace tidl
 
index 75b493aa3b1ce4c562f020c14ec1c4dcf2c83ea4..7bf5d552755fde005e0f5076e0600d147c09b88a 100644 (file)
@@ -42,6 +42,8 @@ void CStubBodyGenerator::OnInitGen(std::ofstream& stream) {
   GenLogDefinition(stream);
   GenVersionDefinition(stream);
   GenBaseDefinition(stream);
+  GenUidMinDefinition(stream);
+  GetRpcPortInternalAPIs(stream);
   GenThreadEnableDefinition(stream);
   GenInterfaceEnums(stream);
   GenUnitMapDefinition(stream);
@@ -128,6 +130,10 @@ void CStubBodyGenerator::GenDelegateBase(std::ofstream& stream) {
     stream << SmartIndent(CB_DELEGATE_BASE);
 }
 
+void CStubBodyGenerator::GenUidMinDefinition(std::ofstream& stream) {
+  stream << std::string(CB_UID_MIN_DEF);
+}
+
 // @see #CB_THREAD_ENABLE_DEF
 void CStubBodyGenerator::GenThreadEnableDefinition(std::ofstream& stream) {
   if (!options_->IsThreadEnabled())
index afd87c640a7dc979ad0d200a31bb033eddcb1950..6d266e83fa041986b3f42e43d9cd364c383ca197 100644 (file)
@@ -107,6 +107,7 @@ class CStubBodyGenerator : public CBodyGeneratorBase {
   std::string GenAccessControlSet(const Interface& iface);
   void GenDelegateDefinition(std::ofstream& stream);
   void GenDelegateBase(std::ofstream& stream);
+  void GenUidMinDefinition(std::ofstream& stream);
   std::string GenLemContext();
   void GenLemDefinition(std::ofstream& stream);
   void GenLemBase(std::ofstream& stream);
index 0748060c597c83bdffcf386f7c227ba7af5d339b..b8d679bac658e74515a0517f00214d8d6b459b29 100644 (file)
@@ -104,6 +104,13 @@ static rpc_port_delegate_h rpc_port_delegate_create()
 }
 )__c_cb";
 
+constexpr const char CB_UID_MIN_DEF[] =
+R"__c_cb(
+#ifndef REGULAR_UID_MIN
+#define REGULAR_UID_MIN 5000
+#endif
+)__c_cb";
+
 constexpr const char CB_THREAD_ENABLE_DEF[] =
 R"__c_cb(
 #define TIDL_THREAD_ENABLE 1
@@ -1516,6 +1523,8 @@ int <PREFIX>_<NAME>_register(<PREFIX>_<NAME>_callback_s *callback, void *user_da
     return RPC_PORT_ERROR_NONE;
   }
 
+  rpc_port_internal_init();
+
   g_rec_mutex_init(&__<NAME>.mutex);
   __<NAME>.callback = *callback;
   __<NAME>.user_data = user_data;
@@ -1727,8 +1736,21 @@ R"__c_cb(
 static const char *privileges[] = {
   <PRIVILEGES>
 };
+int ret;
+uid_t uid;
+pid_t pid;
 
 *sync = <SYNC_TRUE_OR_FALSE>;
+
+if (ARRAY_SIZE(privileges) < 1)
+  return RPC_PORT_ERROR_NONE;
+
+ret = rpc_port_get_peer_info(h->port, &pid, &uid);
+if (ret == RPC_PORT_ERROR_NONE && uid < REGULAR_UID_MIN) {
+  _W("Bypass access control. pid(%d), uid(%u)", pid, uid);
+  return RPC_PORT_ERROR_NONE;
+}
+
 for (size_t i = 0; i < ARRAY_SIZE(privileges); ++i) {
   if (!g_hash_table_contains(h->privileges, privileges[i])) {
     _E("Permission denied. %s : %s", h->sender, privileges[i]);
index f631a38602f9dd2c6458a0e0141e203db04ad560..84132c758d0b8e23acc0e85d7751d82551120c44 100644 (file)
@@ -1045,5 +1045,9 @@ std::string CppGeneratorBase::GenRemoteExceptionForHeader() {
   return std::string(CB_HEADER_REMOTE_EXCEPTION);
 }
 
+std::string CppGeneratorBase::GenRpcPortInternals() {
+  return std::string(CB_RPC_PORT_INTERNAL_APIS);
+}
+
 }  // namespace version2
 }  // namespace tidl
index 4f5677a9d9febef7866a11ffcb0ab815b87f3021..7d72248b83ce6488842c26a74d10b06f063446e4 100644 (file)
@@ -64,6 +64,7 @@ class CppGeneratorBase : public tidl::Generator {
   std::string GenEnumerations(const Enums& enums);
   std::string GenRemoteException();
   std::string GenRemoteExceptionForHeader();
+  std::string GenRpcPortInternals();
 
  private:
   void AddTypeName(const Structure& st);
index a8c753c42219fffe8a5d553609a0b93ef45a8193..205b3e92739dc91fb57b176c5d30cbff85467d39 100644 (file)
@@ -1037,6 +1037,29 @@ R"__cpp_cb(
 #define EXPORT_API extern "C" __attribute__ ((visibility("default")))
 )__cpp_cb";
 
+constexpr const char CB_RPC_PORT_INTERNAL_APIS[] =
+R"__cpp_cb(
+using rpc_port_get_peer_info_t = int (*)(rpc_port_h h, pid_t* pid, uid_t* uid);
+
+rpc_port_get_peer_info_t rpc_port_get_peer_info;
+
+class RpcPortInternals {
+ public:
+  RpcPortInternals() {
+    std::string symbol = "rpc_port_get_peer_info";
+    rpc_port_get_peer_info = reinterpret_cast<rpc_port_get_peer_info_t>(
+    dlsym(RTLD_DEFAULT, symbol.c_str()));
+    if (rpc_port_get_peer_info == nullptr) {
+      _E("Failed to find symbol(%s). Please check rpc-port version", symbol.c_str());
+      return;
+    }
+  }
+};
+
+RpcPortInternals rpc_port_internals_;
+
+)__cpp_cb";
+
 }  // namespace version2
 }  // namespace tidl
 
index 7d30b798bd49a7531aabca1f12448c9972ed7291..1879d914c458f2a179fb6ad325b0536010a3eed6 100644 (file)
@@ -78,6 +78,7 @@ void CppStubBodyGenerator::GenNamespace(std::ofstream& stream) {
 void CppStubBodyGenerator::GenLemAnonymousNamespace(std::ofstream& stream) {
   ReplaceAll(CB_LEM_ANONYMOUS_NAMESPACE)
       .Change("<LEM_CONTEXT>", GenLemContext())
+      .Change("<RPC_PORT_INTERNALS>", GenRpcPortInternals())
       .Transform([&](std::string code) { return SmartIndent(code); })
       .Out(stream);
   stream << NLine(1);
index 88eea6ee23253779ca7e613b364364ac39f990ff..c4758501145aed32a1b799492fd49aaab4ed2216 100644 (file)
@@ -253,11 +253,21 @@ void <CLS_NAME>::ServiceBase::SetPrivilegeMap() {
   <IMPL_SERVICE_BASE_SET_PRIVILEGE_MAP>
 }
 
-bool <CLS_NAME>::ServiceBase::CheckPrivileges(int method_id) {
+bool <CLS_NAME>::ServiceBase::CheckPrivileges(rpc_port_h port, int method_id) {
+  int ret;
+  uid_t uid;
+  pid_t pid;
+
   auto found = privilege_map_.find(method_id);
   if (found == privilege_map_.end())
     return true;
 
+  ret = rpc_port_get_peer_info(port, &pid, &uid);
+  if(ret == RPC_PORT_ERROR_NONE && uid < kRegularUidMin) {
+    _W("Bypass access control. pid(%d), uid(%u)", pid, uid);
+    return true;
+  }
+
   for (const auto& privilege : found->second) {
     if (privileges_.find(privilege) == privileges_.end()) {
       _E("%s does not exist", privilege.c_str());
@@ -462,7 +472,7 @@ active_object_->Send(std::make_shared<Job>(port, callback_port, parcel, std::mov
 constexpr const char CB_INTERFACE_SERVICE_BASE_DISPATCH_FUNC_ASYNC[] =
 R"__cpp_cb(
 void <IFACE_NAME>::ServiceBase::Dispatch<NAME>(rpc_port_h port, rpc_port_h callback_port, int seq_num, const UnitMap& unit_map) {
-  if (!CheckPrivileges(static_cast<int>(MethodId::<NAME>))) {
+  if (!CheckPrivileges(port, static_cast<int>(MethodId::<NAME>))) {
     _E("Permission denied");
     return;
   }
@@ -483,7 +493,7 @@ constexpr const char CB_INTERFACE_SERVICE_BASE_DISPATCH_FUNC[] =
 R"__cpp_cb(
 void <IFACE_NAME>::ServiceBase::Dispatch<NAME>(rpc_port_h port, rpc_port_h callback_port, int seq_num, const UnitMap& unit_map) {
   UnitMap map_;
-  if (!CheckPrivileges(static_cast<int>(MethodId::<NAME>))) {
+  if (!CheckPrivileges(port, static_cast<int>(MethodId::<NAME>))) {
     _E("Permission denied");
     RemoteException remote_except(RPC_PORT_ERROR_PERMISSION_DENIED, "Permission denied");
     map_.Write("[REMOTE_EXCEPTION]", remote_except);
@@ -574,6 +584,8 @@ constexpr const char CB_LEM_ANONYMOUS_NAMESPACE[] =
 R"__cpp_cb(
 namespace {
 
+constexpr const uid_t kRegularUidMin = 5000;
+
 rpc_port_parcel_h Clone(rpc_port_parcel_h parcel) {
   void* raw = nullptr;
   unsigned int size = 0;
@@ -605,6 +617,8 @@ bool IdleAddOnce(GMainContext* context, std::function<void()>* func) {
 
 <LEM_CONTEXT>
 
+<RPC_PORT_INTERNALS>
+
 }  // namespace
 )__cpp_cb";
 
index 5031d562e0506ffa7aa8867bbb00c477f3f850a4..e38a18ca2735d5f0e2a1d45258b0ad7a3f80c387 100644 (file)
@@ -320,7 +320,7 @@ class <CLS_NAME> : public LocalExecution::IEvent {
     static bool PrivilegeInfoCb(const char* privilege_name, void* user_data);
     void LoadPrivileges();
     void SetPrivilegeMap();
-    bool CheckPrivileges(int method_id);
+    bool CheckPrivileges(rpc_port_h port, int method_id);
     <SERVICE_BASE_DISPATCH_FUNCS>
 
     <SERVICE_BASE_IMPL_THREAD_MEMBER>
index 0245a7155d08cab9abee80b377a74232e4c941ea..c5a7923f96fb57565416039c990e260f25e5f54b 100644 (file)
@@ -382,6 +382,7 @@ pub mod <MOD_NAME> {
         privilege_map: HashMap<i32, LinkedList<String>>,
         privileges: HashSet<String>,
         handler: Box<dyn ServiceHandler + Send>,
+        is_app:bool
     }
 
     impl Service {
@@ -397,6 +398,7 @@ pub mod <MOD_NAME> {
                 privilege_map: HashMap::new(),
                 privileges: HashSet::new(),
                 handler: (factory)(peer),
+                is_app: true
             };
 
             service.load_privileges();
@@ -466,6 +468,7 @@ pub mod <MOD_NAME> {
             let sender = self.get_sender();
             let ret = unsafe { app_info_create(CString::new(sender).unwrap().as_ptr() as *const c_char, &mut app_info) };
             if ret != 0 {
+                self.is_app = false;
                 error!("app_info_create failed. ret({})", ret);
                 return;
             }
@@ -506,6 +509,11 @@ pub mod <MOD_NAME> {
 
         fn check_privileges(&self, method_id: i32) -> bool {
             info!("method_id {method_id}");
+            if self.is_app == false {
+                info!("Bypass access control");
+                return true;
+            }
+
             match self.privilege_map.get(&method_id) {
                 Some(privileges) => {
                     for privilege in privileges {