]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
Yes if len == 0 then SIGN_BIT_HIGH produces an invalid shift, but len is never 0...
authorArran Cudbard-Bell <a.cudbardb@freeradius.org>
Mon, 1 Mar 2021 19:18:13 +0000 (19:18 +0000)
committerArran Cudbard-Bell <a.cudbardb@freeradius.org>
Mon, 1 Mar 2021 19:18:13 +0000 (19:18 +0000)
src/lib/util/value.c

index 094ad195b687fa1666717f2dd7c893f43dfc74f6..7c61c7aee2790ba2f5a361be812f67f6e421de0c 100644 (file)
@@ -2561,10 +2561,33 @@ static inline int fr_value_box_cast_integer_to_integer(UNUSED TALLOC_CTX *ctx, f
        size_t                  len = fr_value_box_field_sizes[src->type];
        int64_t                 min;
 
-#define SIGN_BIT_HIGH(_int, _len)      ((((uint64_t)1) << ((_len << 3) - 1)) & _int)
+#define SIGN_BIT_HIGH(_int, _len)      ((((uint64_t)1) << (((_len) << 3) - 1)) & (_int))
 #define SIGN_PROMOTE(_int, _len)       ((_len) < sizeof(_int) ? \
                                        (_int) | (~((__typeof__(_int))0)) << ((_len) << 3) : (_int))
 
+#if !defined(NDEBUG) || defined(__clang_analyzer__)
+       /*
+        *      Helps catch invalid fr_value_box_field_sizes
+        *      entries, and shuts up clang analyzer.
+        */
+       if (unlikely(len == 0)) {
+               fr_strerror_printf("Invalid cast from %s to %s.  %"PRId64" "
+                                  "invalid source type len, expected > 0, got %zu",
+                                  fr_table_str_by_value(fr_value_box_type_table, src->type, "<INVALID>"),
+                                  fr_table_str_by_value(fr_value_box_type_table, dst_type, "<INVALID>"),
+                                  len);
+               return -1;
+       }
+       if (unlikely(len > sizeof(uint64_t))) {
+               fr_strerror_printf("Invalid cast from %s to %s.  %"PRId64" "
+                                  "invalid source type len, expected <= %zu, got %zu",
+                                  fr_table_str_by_value(fr_value_box_type_table, src->type, "<INVALID>"),
+                                  fr_table_str_by_value(fr_value_box_type_table, dst_type, "<INVALID>"),
+                                  sizeof(uint64_t), len);
+               return -1;
+       }
+#endif
+
        switch (src->type) {
        /*
         *      Dates are always represented in nanoseconds