]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
Add type checking functions for value box access
authorArran Cudbard-Bell <a.cudbardb@freeradius.org>
Fri, 19 May 2017 04:22:35 +0000 (00:22 -0400)
committerArran Cudbard-Bell <a.cudbardb@freeradius.org>
Fri, 19 May 2017 04:22:35 +0000 (00:22 -0400)
src/include/cbuff.h [new file with mode: 0644]
src/include/debug.h [new file with mode: 0644]
src/include/libradius.h
src/include/pair.h
src/include/value.h

diff --git a/src/include/cbuff.h b/src/include/cbuff.h
new file mode 100644 (file)
index 0000000..bb59e18
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+#ifndef _FR_CBUFF_H
+#define _FR_CBUFF_H
+/*
+ * $Id$
+ *
+ * @file include/cbuff.h
+ * @brief Simple circular buffer for debugging purposes.
+ *
+ * @copyright 2015-2017 Arran Cudbard-Bell <a.cudbardb@freeradius.org>
+ */
+#include <stdbool.h>
+#include <stdint.h>
+
+typedef struct fr_cbuff fr_cbuff_t;
+
+fr_cbuff_t     *fr_cbuff_alloc(TALLOC_CTX *ctx, uint32_t size, bool lock);
+void           fr_cbuff_rp_insert(fr_cbuff_t *cbuff, void *obj);
+void           *fr_cbuff_rp_next(fr_cbuff_t *cbuff, TALLOC_CTX *ctx);
+#endif /* _FR_CBUFF_H */
diff --git a/src/include/debug.h b/src/include/debug.h
new file mode 100644 (file)
index 0000000..373538d
--- /dev/null
@@ -0,0 +1,95 @@
+/*
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+#ifndef _FR_DEBUG_H
+#define _FR_DEBUG_H
+/*
+ * $Id$
+ *
+ * @file include/debug.h
+ * @brief Debugging function definitions and structures.
+ *
+ * @copyright 2015-2017 Arran Cudbard-Bell <a.cudbardb@freeradius.org>
+ */
+#include <freeradius-devel/cbuff.h>
+
+typedef enum {
+       DEBUGGER_STATE_UNKNOWN_NO_PTRACE        = -3,   //!< We don't have ptrace so can't check.
+       DEBUGGER_STATE_UNKNOWN_NO_PTRACE_CAP    = -2,   //!< CAP_SYS_PTRACE not set for the process.
+       DEBUGGER_STATE_UNKNOWN                  = -1,   //!< Unknown, likely fr_get_debug_state() not called yet.
+       DEBUGGER_STATE_NOT_ATTACHED             = 0,    //!< We can attach, so a debugger must not be.
+       DEBUGGER_STATE_ATTACHED                 = 1     //!< We can't attach, it's likely a debugger is already tracing.
+} fr_debug_state_t;
+
+extern fr_debug_state_t fr_debug_state;
+
+#define FR_FAULT_LOG(fmt, ...) fr_fault_log(fmt "\n", ## __VA_ARGS__)
+typedef void (*fr_fault_log_t)(char const *msg, ...) CC_HINT(format (printf, 1, 2));
+
+/** Optional callback passed to fr_fault_setup
+ *
+ * Allows optional logic to be run before calling the main fault handler.
+ *
+ * If the callback returns < 0, the main fault handler will not be called.
+ *
+ * @param signum signal raised.
+ * @return
+ *     - 0 on success.
+ *     - < 0 on failure.
+ */
+typedef int (*fr_fault_cb_t)(int signum);
+typedef struct fr_bt_marker fr_bt_marker_t;
+
+void           fr_debug_state_store(void);
+char const     *fr_debug_state_to_msg(fr_debug_state_t state);
+void           fr_debug_break(bool always);
+void           backtrace_print(fr_cbuff_t *cbuff, void *obj);
+int            fr_backtrace_do(fr_bt_marker_t *marker);
+fr_bt_marker_t *fr_backtrace_attach(fr_cbuff_t **cbuff, TALLOC_CTX *obj);
+
+void           fr_panic_on_free(TALLOC_CTX *ctx);
+int            fr_set_dumpable_init(void);
+int            fr_set_dumpable(bool allow_core_dumps);
+int            fr_reset_dumpable(void);
+int            fr_log_talloc_report(TALLOC_CTX *ctx);
+void           fr_fault(int sig);
+void           fr_talloc_fault_setup(void);
+int            fr_fault_setup(char const *cmd, char const *program);
+void           fr_fault_set_cb(fr_fault_cb_t func);
+void           fr_fault_set_log_fd(int fd);
+void           fr_fault_log(char const *msg, ...) CC_HINT(format (printf, 1, 2));
+bool           fr_cond_assert_fail(char const *file, int line, char const *expr);
+
+/** Calls panic_action ifndef NDEBUG, else logs error and evaluates to value of _x
+ *
+ * Should be wrapped in a condition, and if false, should cause function to return
+ * an error code.  This allows control to return to the caller if a precondition is
+ * not satisfied and we're not debugging.
+ *
+ * Example:
+ @verbatim
+   if (!fr_cond_assert(request)) return -1
+ @endverbatim
+ *
+ * @param _x expression to test (should evaluate to true)
+ */
+#define                fr_cond_assert(_x) (bool)((_x) ? true : (fr_cond_assert_fail(__FILE__,  __LINE__, #_x) && false))
+
+void           NEVER_RETURNS _fr_exit(char const *file, int line, int status);
+#  define      fr_exit(_x) _fr_exit(__FILE__,  __LINE__, (_x))
+
+void           NEVER_RETURNS _fr_exit_now(char const *file, int line, int status);
+#  define      fr_exit_now(_x) _fr_exit_now(__FILE__,  __LINE__, (_x))
+#endif /* _FR_DEBUG_H */
index 239a64dc4431bf0e50aa61a0c6c6d9e4a47208ee..ec97fd32427894e9a1d5607d99666b3bb7921dc4 100644 (file)
@@ -84,6 +84,7 @@ RCSIDH(libradius_h, "$Id$")
 #include <freeradius-devel/fr_log.h>
 #include <freeradius-devel/version.h>
 #include <freeradius-devel/value.h>
+#include <freeradius-devel/debug.h>
 
 #ifdef SIZEOF_UNSIGNED_INT
 #  if SIZEOF_UNSIGNED_INT != 4
@@ -232,88 +233,6 @@ void               fr_rand_seed(void const *, size_t ); /* seed the random pool */
 /* crypt wrapper from crypt.c */
 int            fr_crypt_check(char const *password, char const *reference_crypt);
 
-/* cbuff.c */
-
-typedef struct fr_cbuff fr_cbuff_t;
-
-fr_cbuff_t     *fr_cbuff_alloc(TALLOC_CTX *ctx, uint32_t size, bool lock);
-void           fr_cbuff_rp_insert(fr_cbuff_t *cbuff, void *obj);
-void           *fr_cbuff_rp_next(fr_cbuff_t *cbuff, TALLOC_CTX *ctx);
-
-/* debug.c */
-typedef enum {
-       DEBUGGER_STATE_UNKNOWN_NO_PTRACE                = -3,   //!< We don't have ptrace so can't check.
-       DEBUGGER_STATE_UNKNOWN_NO_PTRACE_CAP    = -2,   //!< CAP_SYS_PTRACE not set for the process.
-       DEBUGGER_STATE_UNKNOWN                  = -1,   //!< Unknown, likely fr_get_debug_state() not called yet.
-       DEBUGGER_STATE_NOT_ATTACHED             = 0,    //!< We can attach, so a debugger must not be.
-       DEBUGGER_STATE_ATTACHED                 = 1     //!< We can't attach, it's likely a debugger is already tracing.
-} fr_debug_state_t;
-
-#define FR_FAULT_LOG(fmt, ...) fr_fault_log(fmt "\n", ## __VA_ARGS__)
-typedef void (*fr_fault_log_t)(char const *msg, ...) CC_HINT(format (printf, 1, 2));
-extern fr_debug_state_t fr_debug_state;
-
-/** Optional callback passed to fr_fault_setup
- *
- * Allows optional logic to be run before calling the main fault handler.
- *
- * If the callback returns < 0, the main fault handler will not be called.
- *
- * @param signum signal raised.
- * @return
- *     - 0 on success.
- *     - < 0 on failure.
- */
-typedef int (*fr_fault_cb_t)(int signum);
-typedef struct fr_bt_marker fr_bt_marker_t;
-
-void           fr_debug_state_store(void);
-char const     *fr_debug_state_to_msg(fr_debug_state_t state);
-void           fr_debug_break(bool always);
-void           backtrace_print(fr_cbuff_t *cbuff, void *obj);
-int            fr_backtrace_do(fr_bt_marker_t *marker);
-fr_bt_marker_t *fr_backtrace_attach(fr_cbuff_t **cbuff, TALLOC_CTX *obj);
-
-void           fr_panic_on_free(TALLOC_CTX *ctx);
-int            fr_set_dumpable_init(void);
-int            fr_set_dumpable(bool allow_core_dumps);
-int            fr_reset_dumpable(void);
-int            fr_log_talloc_report(TALLOC_CTX *ctx);
-void           fr_fault(int sig);
-void           fr_talloc_fault_setup(void);
-int            fr_fault_setup(char const *cmd, char const *program);
-void           fr_fault_set_cb(fr_fault_cb_t func);
-void           fr_fault_set_log_fd(int fd);
-void           fr_fault_log(char const *msg, ...) CC_HINT(format (printf, 1, 2));
-
-#  ifdef WITH_VERIFY_PTR
-void           fr_pair_verify(char const *file, int line, VALUE_PAIR const *vp);
-void           fr_pair_list_verify(char const *file, int line, TALLOC_CTX *expected, VALUE_PAIR *vps);
-#  endif
-
-bool           fr_cond_assert_fail(char const *file, int line, char const *expr);
-
-/** Calls panic_action ifndef NDEBUG, else logs error and evaluates to value of _x
- *
- * Should be wrapped in a condition, and if false, should cause function to return
- * an error code.  This allows control to return to the caller if a precondition is
- * not satisfied and we're not debugging.
- *
- * Example:
- @verbatim
-   if (!fr_cond_assert(request)) return -1
- @endverbatim
- *
- * @param _x expression to test (should evaluate to true)
- */
-#define                fr_cond_assert(_x) (bool)((_x) ? true : (fr_cond_assert_fail(__FILE__,  __LINE__, #_x) && false))
-
-void           NEVER_RETURNS _fr_exit(char const *file, int line, int status);
-#  define      fr_exit(_x) _fr_exit(__FILE__,  __LINE__, (_x))
-
-void           NEVER_RETURNS _fr_exit_now(char const *file, int line, int status);
-#  define      fr_exit_now(_x) _fr_exit_now(__FILE__,  __LINE__, (_x))
-
 /*
  *     FIFOs
  */
index 4892e5699c936a662fffb66edc0484981371993b..ac5b4ac6f702ff462af8bab7379ce5030d2a7ab4 100644 (file)
@@ -182,6 +182,11 @@ typedef struct value_pair_raw {
 #define NUM_COUNT              (INT_MIN + 2)
 #define NUM_LAST               (INT_MIN + 3)
 
+#  ifdef WITH_VERIFY_PTR
+void           fr_pair_verify(char const *file, int line, VALUE_PAIR const *vp);
+void           fr_pair_list_verify(char const *file, int line, TALLOC_CTX *expected, VALUE_PAIR *vps);
+#  endif
+
 /* Allocation and management */
 VALUE_PAIR     *fr_pair_alloc(TALLOC_CTX *ctx);
 VALUE_PAIR     *fr_pair_afrom_da(TALLOC_CTX *ctx, fr_dict_attr_t const *da);
index e25b6e77575ef35f3bfc753d2858b2144b34b629..89f063ebeab24e03a99a20786b4ec48897d52342 100644 (file)
@@ -17,6 +17,7 @@
 #define _FR_VALUE_H
 #include <freeradius-devel/inet.h>
 #include <freeradius-devel/types.h>
+#include <freeradius-devel/debug.h>
 
 /*
  *     Avoid circular type references.
@@ -156,35 +157,171 @@ struct value_box {
  *     These macros will in future do type checking in developer builds,
  *     in addition to getting the box value.
  */
-#define fr_unbox_strvalue(_box)                        _box->datum.strvalue
-#define fr_unbox_octets(_box)                  _box->datum.octets
-
-#define fr_unbox_ipv4addr(_box)                        _box->datum.ip
-#define fr_unbox_ipv4prefix(_box)              _box->datum.ip
-#define fr_unbox_ipv6addr(_box)                        _box->datum.ip
-#define fr_unbox_ipv6prefix(_box)              _box->datum.ip
-
-#define fr_unbox_ifid(_box)                    _box->datum.ifid
-#define fr_unbox_ether(_box)                   _box->datum.ether
-
-#define fr_unbox_uint8(_box)                   _box->datum.uint8
-#define fr_unbox_uint16(_box)                  _box->datum.uint16
-#define fr_unbox_uint32(_box)                  _box->datum.uint32
-#define fr_unbox_uint64(_box)                  _box->datum.uint64
-#define fr_unbox_uint128(_box)                 _box->datum.uint128
-
-#define fr_unbox_int8(_box)                    _box->datum.int8
-#define fr_unbox_int16(_box)                   _box->datum.int16
-#define fr_unbox_int32(_box)                   _box->datum.int32
-#define fr_unbox_int64(_box)                   _box->datum.int64
-
-#define fr_unbox_float32(_box)                 _box->datum.float32
-#define fr_unbox_float64(_box)                 _box->datum.float64
-
-#define fr_unbox_date(_val)                    _box->datum.date
-#define fr_unbox_date_milliseconds(_val)       _box->datum.date_milliseconds
-#define fr_unbox_date_microseconds(_val)       _box->datum.date_microseconds
-#define fr_unbox_date_nanoseconds(_val)                _box->datum.date_nanoseconds
+#ifndef NDEBUG
+static inline char const *fr_unbox_strvalue(fr_value_box_t const *value)
+{
+       if (!fr_cond_assert(value->type == FR_TYPE_STRING)) return NULL;
+       return value->datum.strvalue;
+}
+static inline uint8_t const *fr_unbox_octets(fr_value_box_t const *value)
+{
+       if (!fr_cond_assert(value->type == FR_TYPE_OCTETS)) return NULL;
+       return value->datum.octets;
+}
+
+static inline fr_ipaddr_t const *fr_unbox_ipv4addr(fr_value_box_t const *value)
+{
+       if (!fr_cond_assert(value->type == FR_TYPE_IPV4_ADDR)) return NULL;
+       if (!fr_cond_assert(value->datum.ip.af == AF_INET)) return NULL;
+       if (!fr_cond_assert(value->datum.ip.prefix == 32)) return NULL;
+       return &value->datum.ip;
+}
+static inline fr_ipaddr_t const *fr_unbox_ipv4prefix(fr_value_box_t const *value)
+{
+       if (!fr_cond_assert(value->type == FR_TYPE_IPV4_ADDR)) return NULL;
+       if (!fr_cond_assert(value->datum.ip.af == AF_INET)) return NULL;
+       if (!fr_cond_assert(value->datum.ip.prefix <= 32)) return NULL;
+       if (!fr_cond_assert(value->datum.ip.prefix >= 0)) return NULL;
+       return &value->datum.ip;
+}
+static inline fr_ipaddr_t const *fr_unbox_ipv6addr(fr_value_box_t const *value)
+{
+       if (!fr_cond_assert(value->type == FR_TYPE_IPV6_ADDR)) return NULL;
+       if (!fr_cond_assert(value->datum.ip.af == AF_INET6)) return NULL;
+       if (!fr_cond_assert(value->datum.ip.prefix == 128)) return NULL;
+       return &value->datum.ip;
+}
+static inline fr_ipaddr_t const *fr_unbox_ipv6prefix(fr_value_box_t const *value)
+{
+       if (!fr_cond_assert(value->type == FR_TYPE_IPV6_PREFIX)) return NULL;
+       if (!fr_cond_assert(value->datum.ip.af == AF_INET6)) return NULL;
+       if (!fr_cond_assert(value->datum.ip.prefix <= 128)) return NULL;
+       if (!fr_cond_assert(value->datum.ip.prefix >= 0)) return NULL;
+       return &value->datum.ip;
+}
+
+static inline uint8_t const *fr_unbox_ifid(fr_value_box_t const *value)
+{
+       if (!fr_cond_assert(value->type == FR_TYPE_IFID)) return NULL;
+       return value->datum.ifid;
+}
+static inline uint8_t const *fr_unbox_ether(fr_value_box_t const *value)
+{
+       if (!fr_cond_assert(value->type == FR_TYPE_ETHERNET)) return NULL;
+       return value->datum.ether;
+}
+
+static inline uint8_t fr_unbox_uint8(fr_value_box_t const *value)
+{
+       if (!fr_cond_assert(value->type == FR_TYPE_UINT8)) return 0;
+       return value->datum.uint8;
+}
+static inline uint16_t fr_unbox_uint16(fr_value_box_t const *value)
+{
+       if (!fr_cond_assert(value->type == FR_TYPE_UINT16)) return 0;
+       return value->datum.uint16;
+}
+static inline uint32_t fr_unbox_uint32(fr_value_box_t const *value)
+{
+       if (!fr_cond_assert(value->type == FR_TYPE_UINT32)) return 0;
+       return value->datum.uint32;
+}
+static inline uint64_t fr_unbox_uint64(fr_value_box_t const *value)
+{
+       if (!fr_cond_assert(value->type == FR_TYPE_UINT64)) return 0;
+       return value->datum.uint64;
+}
+/*
+static inline uint128_t fr_unbox_uint128(fr_value_box_t const *value)
+{
+       if (!fr_cond_assert(value->type == FR_TYPE_UINT128)) return 0;
+       return value->datum.uint128;
+}
+*/
+
+static inline int8_t fr_unbox_int8(fr_value_box_t const *value)
+{
+       if (!fr_cond_assert(value->type == FR_TYPE_UINT8)) return 0;
+       return value->datum.int8;
+}
+static inline int16_t fr_unbox_int16(fr_value_box_t const *value)
+{
+       if (!fr_cond_assert(value->type == FR_TYPE_UINT16)) return 0;
+       return value->datum.int16;
+}
+static inline int32_t fr_unbox_int32(fr_value_box_t const *value)
+{
+       if (!fr_cond_assert(value->type == FR_TYPE_UINT32)) return 0;
+       return value->datum.int32;
+}
+static inline int64_t fr_unbox_int64(fr_value_box_t const *value)
+{
+       if (!fr_cond_assert(value->type == FR_TYPE_UINT64)) return 0;
+       return value->datum.int64;
+}
+
+static inline float fr_unbox_float32(fr_value_box_t const *value)
+{
+       if (!fr_cond_assert(value->type == FR_TYPE_FLOAT32)) return 0;
+       return value->datum.float32;
+}
+static inline float fr_unbox_float64(fr_value_box_t const *value)
+{
+       if (!fr_cond_assert(value->type == FR_TYPE_FLOAT64)) return 0;
+       return value->datum.float64;
+}
+
+static inline uint32_t fr_unbox_date(fr_value_box_t const *value)
+{
+       if (!fr_cond_assert(value->type == FR_TYPE_DATE)) return 0;
+       return value->datum.date;
+}
+static inline uint64_t fr_unbox_date_milliseconds(fr_value_box_t const *value)
+{
+       if (!fr_cond_assert(value->type == FR_TYPE_DATE_MILLISECONDS)) return 0;
+       return value->datum.date_milliseconds;
+}
+static inline uint64_t fr_unbox_date_microseconds(fr_value_box_t const *value)
+{
+       if (!fr_cond_assert(value->type == FR_TYPE_DATE_MICROSECONDS)) return 0;
+       return value->datum.date_microseconds;
+}
+static inline uint64_t fr_unbox_date_nanoseconds(fr_value_box_t const *value)
+{
+       if (!fr_cond_assert(value->type == FR_TYPE_DATE_NANOSECONDS)) return 0;
+       return value->datum.date_nanoseconds;
+}
+#else
+#  define fr_unbox_strvalue(_box)              _box->datum.strvalue
+#  define fr_unbox_octets(_box)                        _box->datum.octets
+
+#  define fr_unbox_ipv4addr(_box)              &(_box->datum.ip)
+#  define fr_unbox_ipv4prefix(_box)            &(_box->datum.ip)
+#  define fr_unbox_ipv6addr(_box)              &(_box->datum.ip)
+#  define fr_unbox_ipv6prefix(_box)            &(_box->datum.ip)
+
+#  define fr_unbox_ifid(_box)                  _box->datum.ifid
+#  define fr_unbox_ether(_box)                 _box->datum.ether
+
+#  define fr_unbox_uint8(_box)                 _box->datum.uint8
+#  define fr_unbox_uint16(_box)                        _box->datum.uint16
+#  define fr_unbox_uint32(_box)                        _box->datum.uint32
+#  define fr_unbox_uint64(_box)                        _box->datum.uint64
+#  define fr_unbox_uint128(_box)               _box->datum.uint128
+
+#  define fr_unbox_int8(_box)                  _box->datum.int8
+#  define fr_unbox_int16(_box)                 _box->datum.int16
+#  define fr_unbox_int32(_box)                 _box->datum.int32
+#  define fr_unbox_int64(_box)                 _box->datum.int64
+
+#  define fr_unbox_float32(_box)               _box->datum.float32
+#  define fr_unbox_float64(_box)               _box->datum.float64
+
+#  define fr_unbox_date(_val)                  _box->datum.date
+#  define fr_unbox_date_milliseconds(_val)     _box->datum.date_milliseconds
+#  define fr_unbox_date_microseconds(_val)     _box->datum.date_microseconds
+#  define fr_unbox_date_nanoseconds(_val)      _box->datum.date_nanoseconds
+#endif
 
 /*
  *     Allocation