]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
make fr_tacacs_packet_log_hex() take and check a length field
authorAlan T. DeKok <aland@freeradius.org>
Mon, 17 Jul 2023 12:28:42 +0000 (08:28 -0400)
committerAlan T. DeKok <aland@freeradius.org>
Mon, 17 Jul 2023 12:29:03 +0000 (08:29 -0400)
src/protocols/tacacs/base.c
src/protocols/tacacs/decode.c
src/protocols/tacacs/encode.c
src/protocols/tacacs/tacacs.h

index b78c0f5f2d57bdc6b93e52b03a2343ebdfd450de..a1ee03e2b247abecb8ac5dc6e9fc765f8bc4f3c2 100644 (file)
@@ -385,12 +385,19 @@ static void print_args(fr_log_t const *log, char const *file, int line, size_t a
        }
 }
 
-void _fr_tacacs_packet_log_hex(fr_log_t const *log, fr_tacacs_packet_t const *packet, char const *file, int line)
+void _fr_tacacs_packet_log_hex(fr_log_t const *log, fr_tacacs_packet_t const *packet, size_t packet_len, char const *file, int line)
 {
        size_t length;
        uint8_t const *p = (uint8_t const *) packet;
        uint8_t const *hdr, *end, *args;
 
+       end = ((uint8_t const *) packet) + packet_len;
+
+       if (packet_len < 12) {
+               print_hex(log, file, line, "header ", p, packet_len, end);
+               return;
+       }
+
        /*
         *      It has to be at least 12 bytes long.
         */
@@ -419,7 +426,11 @@ void _fr_tacacs_packet_log_hex(fr_log_t const *log, fr_tacacs_packet_t const *pa
 
        p += 12;
        hdr = p;
-       end = hdr + length;
+
+       if ((p + length) != end) {
+               fr_log(log, L_DBG, file, line, "length field does not match input packet length %08lx", packet_len - 12);
+               return;
+       }
 
 #define OVERFLOW8(_field, _name) do { \
        if ((p + _field) > end) { \
index 649ad2cf754c58cfbac6846a1bfb6c714e6e2c9b..d73395a84152f8674f25b469f1014206189468e1 100644 (file)
@@ -557,7 +557,7 @@ ssize_t fr_tacacs_decode(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_attr_t co
        }
 
 #ifndef NDEBUG
-       if (fr_debug_lvl >= L_DBG_LVL_4) fr_tacacs_packet_log_hex(&default_log, pkt);
+       if (fr_debug_lvl >= L_DBG_LVL_4) fr_tacacs_packet_log_hex(&default_log, pkt, (end - buffer));
 #endif
 
        if (code) {
index 6029060e9e0ce09918f4df4523fe2223e676413d..cacbcac0319edeb002203b4154ae9f8eb105353a 100644 (file)
@@ -978,7 +978,7 @@ ssize_t fr_tacacs_encode(fr_dbuff_t *dbuff, uint8_t const *original_packet, char
                uint8_t flags = packet->hdr.flags;
 
                packet->hdr.flags |= FR_TAC_PLUS_UNENCRYPTED_FLAG;
-               fr_tacacs_packet_log_hex(&default_log, packet);
+               fr_tacacs_packet_log_hex(&default_log, packet, packet_len);
                packet->hdr.flags = flags;
        }
 #endif
index 9999a31e2fae73bf8fcb6d6a55c098f81d67e593..b15b8492bf96ddcabac03baf68feab601fc20e75 100644 (file)
@@ -351,5 +351,5 @@ void                fr_tacacs_free(void);
 
 int            fr_tacacs_body_xor(fr_tacacs_packet_t const *pkt, uint8_t *body, size_t body_len, char const *secret, size_t secret_len) CC_HINT(nonnull(1,2,4));
 
-#define fr_tacacs_packet_log_hex(_log, _packet) _fr_tacacs_packet_log_hex(_log, _packet, __FILE__, __LINE__);
-void           _fr_tacacs_packet_log_hex(fr_log_t const *log, fr_tacacs_packet_t const *packet, char const *file, int line) CC_HINT(nonnull);
+#define fr_tacacs_packet_log_hex(_log, _packet, _size) _fr_tacacs_packet_log_hex(_log, _packet, _size, __FILE__, __LINE__);
+void           _fr_tacacs_packet_log_hex(fr_log_t const *log, fr_tacacs_packet_t const *packet, size_t packet_len, char const *file, int line) CC_HINT(nonnull);