]> git.kaiwu.me - haproxy.git/commitdiff
BUG/MINOR: mqtt: fix PUBLISH flags validation that want all bits to be set
authorWilly Tarreau <w@1wt.eu>
Mon, 11 May 2026 13:38:58 +0000 (15:38 +0200)
committerWilly Tarreau <w@1wt.eu>
Mon, 11 May 2026 14:04:19 +0000 (16:04 +0200)
The definition of the PUBLISH message type indicates that the LSB are
independent, but uses a value of 0xF that clearly shows an attempt to
use a mask instead, but it results in all messages not having all flags
set to be rejected. A sane approach would have been to check for a mask
and an expected value. Let's just add a special case for it in function
mqtt_read_fixed_hdr() since that's for a single message type.

This can be backported anywhere.

src/mqtt.c

index 97839eed7236b47e443a818d565e4e1db41975b3..340e1295a68e5d1bfb24758d5a345bc68211325d 100644 (file)
@@ -19,7 +19,7 @@ uint8_t mqtt_cpt_flags[MQTT_CPT_ENTRIES] = {
        [MQTT_CPT_CONNACK]     = 0x00,
 
        /* MQTT_CPT_PUBLISH flags can have different values (DUP, QoS, RETAIN), must be
-        * check more carefully
+        * check more carefully (any combination of the 4 bits is valid).
         */
        [MQTT_CPT_PUBLISH]     = 0x0F,
 
@@ -162,7 +162,8 @@ static inline struct ist mqtt_read_fixed_hdr(struct ist parser, struct mqtt_pkt
        uint8_t ptype = (type & 0xF0) >> 4;
        uint8_t flags = type & 0x0F;
 
-       if (ptype == MQTT_CPT_INVALID || ptype >= MQTT_CPT_ENTRIES || flags != mqtt_cpt_flags[ptype])
+       if (ptype == MQTT_CPT_INVALID || ptype >= MQTT_CPT_ENTRIES ||
+           (ptype != MQTT_CPT_PUBLISH && flags != mqtt_cpt_flags[ptype]))
                return IST_NULL;
 
        pkt->fixed_hdr.type = ptype;