diff options
author | Armelle Laine <armellel@google.com> | 2022-01-24 05:18:40 +0000 |
---|---|---|
committer | Armelle Laine <armellel@google.com> | 2022-01-26 03:40:02 +0000 |
commit | d3586e84c998fba6577f203c62b5405e1ea8d96a (patch) | |
tree | 8b858232e50606d2e0a0215b4001ac79ffb3c011 | |
parent | 16ac6d28aeb70cd5fced6f65061cc74058da0484 (diff) | |
download | gatekeeper-d3586e84c998fba6577f203c62b5405e1ea8d96a.tar.gz |
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
-rw-r--r-- | ipc/gatekeeper_ipc.cpp | 22 |
1 files changed, 6 insertions, 16 deletions
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 @@ public: ~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 @@ static gatekeeper_error_t handle_msg(handle_t chan) { 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 @@ static gatekeeper_error_t handle_msg(handle_t chan) { 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); |