Fix race condition in gatekeeper ipc

Current trusty ipc logic (trusty/kernel/lib/trusty/tipc_virtio_dev.c)
drops a message on a channel when its receive fifo is full
(the receive fifo size is determined by the argument `recv_buf_size`
passed in the port_create api).

Filling the receive fifo can only happen when a new message
is received while the previous one has not been retired yet
(via a call to put_msg).

HAL to TA IPC won't hit this issue when following the recommended pattern:
- HAL:
    - send a message
    - wait for its response
    - send the next message.
- TA:
    - receive a message
    - retire it from the receive fifo
    - then send the response.

Prior to this fix, gatekeeper TA used to send the response THEN retire
the message, while having a receive fifo size of 1.

This creates the race condition where the message would be dropped.
The fix consists in retiring the message (put_msg) prior to sending
the response.

Bug: 211378534
Change-Id: I957e72183d92131adb37316f29d7e2963679df29
diff --git a/ipc/gatekeeper_ipc.cpp b/ipc/gatekeeper_ipc.cpp
index 9994697..fd88770 100644
--- a/ipc/gatekeeper_ipc.cpp
+++ b/ipc/gatekeeper_ipc.cpp
@@ -33,20 +33,6 @@
     ~SessionManager() { device->CloseSession(); }
 };
 
-class MessageDeleter {
-public:
-    explicit MessageDeleter(handle_t chan, int id) {
-        chan_ = chan;
-        id_ = id;
-    }
-
-    ~MessageDeleter() { put_msg(chan_, id_); }
-
-private:
-    handle_t chan_;
-    int id_;
-};
-
 static gatekeeper_error_t tipc_err_to_gatekeeper_err(long tipc_err) {
     switch (tipc_err) {
     case NO_ERROR:
@@ -187,8 +173,9 @@
         return tipc_err_to_gatekeeper_err(rc);
     }
 
-    MessageDeleter md(chan, msg_inf.id);
-
+    /* TODO: handle heap allocation failure
+     * and retire the message on failure too
+     */
     UniquePtr<uint8_t[]> msg_buf(new uint8_t[msg_inf.len]);
 
     /* read msg content */
@@ -197,6 +184,9 @@
 
     rc = read_msg(chan, msg_inf.id, 0, &msg);
 
+    // retire the message (note msg_inf.id becomes invalid after put_msg)
+    put_msg(chan, msg_inf.id);
+
     if (rc < 0) {
         TLOGE("failed to read msg (%ld) for chan (%d)\n", rc, chan);
         return tipc_err_to_gatekeeper_err(rc);