You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by ch...@apache.org on 2020/05/12 12:19:06 UTC

[qpid-dispatch] branch master updated: DISPATCH-1645: Use uint64_t values for max message size enforcement

This is an automated email from the ASF dual-hosted git repository.

chug pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/qpid-dispatch.git


The following commit(s) were added to refs/heads/master by this push:
     new cd09cc0  DISPATCH-1645: Use uint64_t values for max message size enforcement
cd09cc0 is described below

commit cd09cc0c9fcee65f2d093c93a813d3a27ee0a28d
Author: Chuck Rolke <ch...@apache.org>
AuthorDate: Tue May 12 08:12:30 2020 -0400

    DISPATCH-1645: Use uint64_t values for max message size enforcement
    
    Policy settings and statistics already use unsigned 64 bit values.
    Runtime code was demoting the settings to signed 32 bit values.
    
    Release 1.12 works correctly only for max message size limits less
    than 2^31, including values from 1 to 2147483647.
    
    This closes #734
---
 include/qpid/dispatch/server.h              |  2 +-
 src/container.c                             |  4 ++--
 src/message_private.h                       |  4 ++--
 src/policy.h                                |  2 +-
 src/server.c                                |  2 +-
 tests/system_tests_policy_oversize_basic.py | 22 ++++++++++++++++++++++
 6 files changed, 29 insertions(+), 7 deletions(-)

diff --git a/include/qpid/dispatch/server.h b/include/qpid/dispatch/server.h
index abe5a9a..98df6f7 100644
--- a/include/qpid/dispatch/server.h
+++ b/include/qpid/dispatch/server.h
@@ -604,7 +604,7 @@ bool qd_connection_strip_annotations_in(const qd_connection_t *c);
 
 void qd_connection_wake(qd_connection_t *ctx);
 
-int qd_connection_max_message_size(const qd_connection_t *c);
+uint64_t qd_connection_max_message_size(const qd_connection_t *c);
 
 /**
  * @}
diff --git a/src/container.c b/src/container.c
index 651db95..01d878b 100644
--- a/src/container.c
+++ b/src/container.c
@@ -161,7 +161,7 @@ static void setup_outgoing_link(qd_container_t *container, pn_link_t *pn_link)
 }
 
 
-static void setup_incoming_link(qd_container_t *container, pn_link_t *pn_link, int max_size)
+static void setup_incoming_link(qd_container_t *container, pn_link_t *pn_link, uint64_t max_size)
 {
     qd_node_t *node = container->default_node;
 
@@ -194,7 +194,7 @@ static void setup_incoming_link(qd_container_t *container, pn_link_t *pn_link, i
     link->remote_snd_settle_mode = pn_link_remote_snd_settle_mode(pn_link);
 
     if (max_size) {
-        pn_link_set_max_message_size(pn_link, (uint64_t)max_size);
+        pn_link_set_max_message_size(pn_link, max_size);
     }
     pn_link_set_context(pn_link, link);
     node->ntype->incoming_handler(node->context, link);
diff --git a/src/message_private.h b/src/message_private.h
index ba13538..3d3c59e 100644
--- a/src/message_private.h
+++ b/src/message_private.h
@@ -109,8 +109,8 @@ typedef struct {
     qd_parsed_field_t   *ma_pf_to_override;
     qd_parsed_field_t   *ma_pf_trace;
     int                  ma_int_phase;
-    int                  max_message_size;               // configured max; 0 if no max to enforce
-    int                  bytes_received;                 // bytes returned by pn_link_recv() when enforcing max_message_size
+    uint64_t             max_message_size;               // configured max; 0 if no max to enforce
+    uint64_t             bytes_received;                 // bytes returned by pn_link_recv() when enforcing max_message_size
     uint32_t             fanout;                         // The number of receivers for this message, including in-process subscribers.
     qd_link_t_sp         input_link_sp;                  // message received on this link
 
diff --git a/src/policy.h b/src/policy.h
index 44e8794..5ad937b 100644
--- a/src/policy.h
+++ b/src/policy.h
@@ -50,7 +50,7 @@ struct qd_policy__settings_s {
     int  maxSessions;
     int  maxSenders;
     int  maxReceivers;
-    int  maxMessageSize;
+    uint64_t  maxMessageSize;
     bool allowDynamicSource;
     bool allowAnonymousSender;
     bool allowUserIdProxy;
diff --git a/src/server.c b/src/server.c
index be9508a..3005517 100644
--- a/src/server.c
+++ b/src/server.c
@@ -1668,6 +1668,6 @@ sys_mutex_t *qd_server_get_activation_lock(qd_server_t * server)
     return server->conn_activation_lock;
 }
 
-int qd_connection_max_message_size(const qd_connection_t *c) {
+uint64_t qd_connection_max_message_size(const qd_connection_t *c) {
     return (c && c->policy_settings) ? c->policy_settings->maxMessageSize : 0;
 }
diff --git a/tests/system_tests_policy_oversize_basic.py b/tests/system_tests_policy_oversize_basic.py
index 6bc35c7..7c41936 100644
--- a/tests/system_tests_policy_oversize_basic.py
+++ b/tests/system_tests_policy_oversize_basic.py
@@ -262,6 +262,11 @@ INTA_MAX_SIZE = 100000
 INTB_MAX_SIZE = 150000
 EB1_MAX_SIZE = 200000
 
+# DISPATCH-1645 S32 max size is chosen to expose signed 32-bit
+# wraparound bug. Sizes with bit 31 set look negative when used as
+# C 'int' and prevent any message from passing policy checks.
+S32_MAX_SIZE = 2**31
+
 # Interior routers enforce max size directly.
 # Edge routers are also checked by the attached interior router.
 
@@ -379,6 +384,10 @@ class MaxMessageSizeBlockOversize(TestCase):
         cls.EB1 = cls.routers[3]
         cls.EB1.listener = cls.EB1.addresses[0]
 
+        router('S32', 'standalone', S32_MAX_SIZE, [])
+        cls.S32 = cls.routers[4]
+        cls.S32.listener = cls.S32.addresses[0]
+
         cls.INT_A.wait_router_connected('INT.B')
         cls.INT_B.wait_router_connected('INT.A')
         cls.EA1.wait_connectors()
@@ -791,5 +800,18 @@ class MaxMessageSizeBlockOversize(TestCase):
         self.assertTrue(test.error is None)
 
 
+    def test_s32_allow_gt_signed_32bit_max(self):
+        test = OversizeMessageTransferTest(MaxMessageSizeBlockOversize.S32,
+                                           MaxMessageSizeBlockOversize.S32,
+                                           "s32",
+                                           message_size=200,
+                                           expect_block=False)
+        test.run()
+        if test.error is not None:
+            test.logger.log("test_s32 test error: %s" % (test.error))
+            test.logger.dump()
+        self.assertTrue(test.error is None)
+
+
 if __name__ == '__main__':
     unittest.main(main_module())


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org