Fix memory leak in dcm_free_key_context() 31/307731/1 accepted/tizen/unified/20240313.134655 accepted/tizen/unified/20240313.135701 accepted/tizen/unified/dev/20240620.005613 accepted/tizen/unified/x/20240314.073210
authorDariusz Michaluk <d.michaluk@samsung.com>
Tue, 12 Mar 2024 12:26:13 +0000 (13:26 +0100)
committerDariusz Michaluk <d.michaluk@samsung.com>
Tue, 12 Mar 2024 13:24:43 +0000 (14:24 +0100)
Change-Id: If5d18401bd9312bd67f52c7692813f67976d680f

src/dcm-client/dcm_client.cpp
src/dcm-client/dcm_client.h
src/dcm-client/dcm_support.proto
src/dcm-client/device_certificate_manager.cpp
src/dcm-daemon/dcm_session.cpp
src/dcm-daemon/dcm_session.h

index 5e8d24aa62d8fd5b99534fd9cbe46a154e09f8d0..40eada9b3de72b48c5b86836c29113acd441bb2f 100644 (file)
@@ -127,6 +127,42 @@ int dcm_client_connection::create_context(
        return DCM_ERROR_NONE;
 }
 
+int dcm_client_connection::close_context() noexcept
+{
+       std::lock_guard<std::mutex> locker(fLock);
+
+       if(!fCookie) {
+               LOGE("Trying to close key context in session %p without connection", this);
+               return DCM_ERROR_SOCKET;
+       }
+
+       try {
+               RequestMessage request;
+               ResponseMessage response;
+
+               auto* close_req = request.mutable_close_context();
+               close_req->set_context_cookie(fCookie);
+
+               send_receive(request, response);
+               auto& close_resp(response.close_context());
+               if(close_resp.result() != 0) {
+                       LOGE("Close key context for session %p received error %d", this, close_resp.result());
+                       return DCM_ERROR_INVALID_PARAMETER;
+               }
+       } catch(std::bad_alloc&) {
+               LOGE("Out of memory when requesting close key context for session %p", this);
+               return DCM_ERROR_OUT_OF_MEMORY;
+       } catch(std::exception& ex) {
+               LOGE("When requesting close key context for session %p received exception : %s", this, ex.what());
+               return DCM_ERROR_UNKNOWN;
+       } catch(...) {
+               LOGE("When requesting close key context for session %p received exception : %s", this, "Unknown error");
+               return DCM_ERROR_UNKNOWN;
+       }
+
+       return DCM_ERROR_NONE;
+}
+
 int dcm_client_connection::get_certificate_chain(std::vector<uint8_t>& chain) noexcept
 {
        std::lock_guard<std::mutex> locker(fLock);
index 105848508a13a87abac034604d9e2c2e6f961980..fc2da3f2fe81dfefe0e3ddfbdc466055e87a3b30 100644 (file)
@@ -45,6 +45,8 @@ public:
                const std::string& usage,
                const std::string& key_type) noexcept;
 
+       int close_context() noexcept;
+
        int get_certificate_chain(std::vector<uint8_t>& chain) noexcept;
 
        const std::string& key_type() const noexcept;
index 50a2f43fe122a514fb1de3343681e75677d833d1..4737247d22c799619d645fbb526cce7957d0a731 100644 (file)
@@ -71,12 +71,23 @@ message ExtCallResponse
        optional bytes output_data = 2;
 }
 
+message CloseKeyContext
+{
+    required uint64 context_cookie = 1;
+}
+
+message CloseKeyContextResponse
+{
+    required int32 result = 1;
+}
+
 message RequestMessage {
        oneof request_oneof {
                AssociateKeyContext associate_context = 1;
                RequestCertificateChain request_chain = 2;
                SignRequest sign_data = 3;
                ExtCallRequest ext_call = 4;
+               CloseKeyContext close_context = 5;
        }
 }
 
@@ -86,5 +97,6 @@ message ResponseMessage {
                RequestCertificateChainResponse request_chain = 2;
                SignResponse sign_data = 3;
                ExtCallResponse ext_call = 4;
+               CloseKeyContextResponse close_context = 5;
        }
 }
index c4dd8010d5395e61d3627a4ad2c326740224868a..c76b4b5a795992b4c9689cae3c1aa8eb653fa974 100644 (file)
@@ -103,6 +103,10 @@ int dcm_free_key_context(void *key_ctx)
        if(!key_ctx)
                return DCM_ERROR_NONE;
 
+       const dcm_key_context_internal *context =
+               reinterpret_cast<const dcm_key_context_internal *>(key_ctx);
+
+       context->connection->close_context();
        delete reinterpret_cast<dcm_key_context_internal *>(key_ctx);
 
        return DCM_ERROR_NONE;
index e16c467b278e49729d6e388f77fe680b0ac201b9..bafed39f0ded243b756c46edbfd1d2a509e9a363 100644 (file)
@@ -109,6 +109,9 @@ void dcm_session::decode_message() noexcept
                        case RequestMessage::kExtCall:
                                handle_ext_call_request(requestMessage.ext_call());
                                break;
+                       case RequestMessage::kCloseContext:
+                               handle_close_context(requestMessage.close_context());
+                               break;
                        default:
                                LOGE("Incorrect request message type");
                                // This will terminate connection
@@ -429,3 +432,45 @@ void dcm_session::handle_ext_call_request(const ExtCallRequest& message)
        }
        reply(msg);
 }
+
+void dcm_session::handle_close_context(const CloseKeyContext& message)
+{
+       LOGD("Request close key context");
+
+       if(!verify_privileges(fSocket.native_handle(), DCM_DEFAULT_PRIVILEGE)) {
+               LOGE("Client privilege check failure. Disconnect");
+               return;
+       }
+
+       ResponseMessage msg;
+       auto* closeResponse = msg.mutable_close_context();
+
+       if(message.context_cookie() != fCookie) {
+               LOGE("Received unknown context cookie");
+               closeResponse->set_result(-EINVAL);
+               reply(msg);
+               return;
+       }
+
+       if(!fBackendContext) {
+               LOGE("Context not associated with connection");
+               closeResponse->set_result(-EINVAL);
+               reply(msg);
+               return;
+       }
+
+       int error = 0;
+       try {
+               fSoResolver->invoke<void, dcm_backend_context&>(
+                       "dcm_backend_free_key_context", *fBackendContext);
+       } catch(std::bad_alloc&) {
+               error = -ENOMEM;
+       } catch(std::exception&) {
+               error = -EINVAL;
+       } catch(...) {
+               error = -EFAULT;
+       }
+
+       closeResponse->set_result(error);
+       reply(msg);
+}
index f3b57cd57e7b270915608da413a59c43e4fb614a..8b63e45c40b8361867d595a0649fbddcd712ca64 100644 (file)
@@ -61,6 +61,7 @@ private:
        void handle_cert_chain(const RequestCertificateChain& message);
        void handle_sign_request(const SignRequest& message);
        void handle_ext_call_request(const ExtCallRequest& message);
+       void handle_close_context(const CloseKeyContext& message);
 
        int sign(MessageDigestType digest_type, const std::string& message, std::string& signature);
        int sign_request_check(const SignRequest& message);