From f1d8288e7a8d73e5d7441269a5d258eb90ed389e Mon Sep 17 00:00:00 2001 From: "E. Scott Daniels" Date: Fri, 1 Nov 2019 09:24:08 -0400 Subject: [PATCH] Prevent message truncation by populate function An attempt to write a payload to a received message in prep for returning the response to sender could result in the response message being truncated if it is longer than the payload in the received message. The populate and set length function was modified to ensure that the target message has a payload length which is not less than the message being added; if it does the message payload is reallocated through RMR. This change requires RMR version 1.10.2 or later. CP: dev-b Cherry-Id: I8fa26eaace814344481c2df715c7c2486a38f6df duplicated CID from an abandoned change Signed-off-by: E. Scott Daniels Change-Id: Iaf032cb0b5feb14c714077430e1962107eae8a42 --- src/bindings/rmr-python/docs/Changelog.rst | 7 +++++++ src/bindings/rmr-python/rmr-version.yaml | 2 +- src/bindings/rmr-python/rmr/rmr.py | 19 ++++++++++++++++++- src/bindings/rmr-python/tests/test_rmr.py | 18 ++++++++++++++++++ 4 files changed, 44 insertions(+), 2 deletions(-) diff --git a/src/bindings/rmr-python/docs/Changelog.rst b/src/bindings/rmr-python/docs/Changelog.rst index 3b29e66..4fa1629 100644 --- a/src/bindings/rmr-python/docs/Changelog.rst +++ b/src/bindings/rmr-python/docs/Changelog.rst @@ -7,6 +7,13 @@ The format is based on `Keep a Changelog `__ and this project adheres to `Semantic Versioning `__. +[X.X.X] - 10/30/2019 +-------------------- + +:: + * This is a breaking change as it rquires that RMR version 1.10.2 or later be used. + * The populate and set length function will reallocate the message buffer payload if the caller attempts to insert more bytes than the currrent message supports. + [1.0.0] - 10/24/2019 -------------------- diff --git a/src/bindings/rmr-python/rmr-version.yaml b/src/bindings/rmr-python/rmr-version.yaml index 1ea7883..0d9c301 100644 --- a/src/bindings/rmr-python/rmr-version.yaml +++ b/src/bindings/rmr-python/rmr-version.yaml @@ -1,3 +1,3 @@ # CI script installs RMR from PackageCloud using this version --- -version: 1.8.3 +version: 1.10.2 diff --git a/src/bindings/rmr-python/rmr/rmr.py b/src/bindings/rmr-python/rmr/rmr.py index 0265e21..99c2088 100644 --- a/src/bindings/rmr-python/rmr/rmr.py +++ b/src/bindings/rmr-python/rmr/rmr.py @@ -1,3 +1,4 @@ +# vim: expandtab ts=4 sw=4: # ================================================================================== # Copyright (c) 2019 Nokia # Copyright (c) 2018-2019 AT&T Intellectual Property. @@ -248,6 +249,19 @@ def rmr_alloc_msg(vctx, size, payload=None, gen_transaction_id=False, mtype=None raise BadBufferAllocation +_rmr_realloc_payload = rmr_c_lib.rmr_realloc_payload +_rmr_realloc_payload.argtypes = [POINTER(rmr_mbuf_t), c_int, c_int, c_int] # new_len, copy, clone +_rmr_realloc_payload.restype = POINTER(rmr_mbuf_t) + + +def rmr_realloc_payload(ptr_mbuf, new_len, copy=False, clone=False): + """ + Refer to the rmr C documentation for rmr_realloc_payload(). + extern rmr_mbuf_t* rmr_realloc_payload(rmr_mbuf_t*, int, int, int) + """ + return _rmr_realloc_payload(ptr_mbuf, new_len, copy, clone) + + _rmr_free_msg = rmr_c_lib.rmr_free_msg _rmr_free_msg.argtypes = [c_void_p] _rmr_free_msg.restype = None @@ -256,7 +270,7 @@ _rmr_free_msg.restype = None def rmr_free_msg(mbuf): """ Refer to the rmr C documentation for rmr_free_msg - extern void rmr_free_msg( rmr_mbuf_t* mbuf ) + extern void rmr_free_msg(rmr_mbuf_t* mbuf ) """ if mbuf is not None: _rmr_free_msg(mbuf) @@ -487,6 +501,9 @@ def set_payload_and_length(byte_str, ptr_mbuf): ptr_mbuf: ctypes c_void_p Pointer to an rmr message buffer """ + if rmr_payload_size(ptr_mbuf) < len(byte_str): # existing message payload too small + ptr_mbuf = rmr_realloc_payload(ptr_mbuf, len(byte_str), True) + memmove(ptr_mbuf.contents.payload, byte_str, len(byte_str)) ptr_mbuf.contents.len = len(byte_str) diff --git a/src/bindings/rmr-python/tests/test_rmr.py b/src/bindings/rmr-python/tests/test_rmr.py index e43b170..cd07545 100644 --- a/src/bindings/rmr-python/tests/test_rmr.py +++ b/src/bindings/rmr-python/tests/test_rmr.py @@ -287,3 +287,21 @@ def test_alloc_fancy(): assert summary["message state"] == 0 assert summary["message type"] == 14 assert summary["meid"] == b"asdf" + + +def test_resize_payload(): + """test the ability to insert a larger payload into an existing message""" + mtype = 99 + subid = 100 + + mbuf = rmr.rmr_alloc_msg(MRC_SEND, 25) # allocate buffer with small payload + mbuf.contents.mtype = mtype # type and sub-id should not change + mbuf.contents.sub_id = subid + + long_payload = b"This is a long payload that should force the message buffer to be reallocated" + rmr.set_payload_and_length(long_payload, mbuf) + summary = rmr.message_summary(mbuf) + assert summary["payload max size"] >= len(long_payload) # RMR may allocate a larger payload space + assert summary["payload length"] == len(long_payload) # however, the length must be exactly the same + assert summary["message type"] == mtype # both mtype and sub-id should be preserved in new + assert summary["subscription id"] == subid -- 2.16.6