linux
Debugging code may derefence a NULL pointer
Pointer `dst' may be NULL and, if SCTP_DEBUG_PRINTK is enabled, is dereferenced by a call to printk.
Bug fixed by commit ee3f34e8572
Type | NullDereference |
Config | "IP_SCTP && IPV6 && SCTP_DBG_MSG" (3rd degree) |
C-features | PointerAliasing |
Fix-in | code |
Location | net/sctp/ |
#include <stdbool.h> #include <stdlib.h> #ifndef SCTP_DEBUG #ifdef CONFIG_SCTP_DBG_MSG #define SCTP_DEBUG 1 #else #define SCTP_DEBUG 0 #endif /* CONFIG_SCTP_DBG */ #endif /* SCTP_DEBUG */ bool IS_ERR(const void *ptr) { return (ptr == (void *)-1); } bool IS_ERR_OR_NULL(const void *ptr) { return !ptr || IS_ERR(ptr); } #if SCTP_DEBUG #define SCTP_DEBUG_PRINTK(ptr) ((*ptr)++) #else #define SCTP_DEBUG_PRINTK(ptr) #endif #if defined(CONFIG_IP_SCTP) && defined(CONFIG_IPV6) static int some_int = 1; int *ip6_dst_lookup_flow() { return &some_int; } void sctp_v6_get_dst() { int *dst = NULL; dst = ip6_dst_lookup_flow(); if (!IS_ERR(dst)) { dst = NULL; // (2) } if (!IS_ERR(dst)) { char *rt =(char *) dst; // (3) SCTP_DEBUG_PRINTK(rt); // (4) ERROR } } #endif int main() { #if defined(CONFIG_IP_SCTP) && defined(CONFIG_IPV6) sctp_v6_get_dst(); // (1) #endif return 0; }
diff --git a/simple/ee3f34e.c b/simple/ee3f34e.c --- a/simple/ee3f34e.c +++ b/simple/ee3f34e.c @@ -41,7 +41,7 @@ if (!IS_ERR(dst)) { dst = NULL; } - if (!IS_ERR(dst)) { + if (!IS_ERR_OR_NULL(dst)) { char *rt =(char *) dst; SCTP_DEBUG_PRINTK(rt); // ERROR }
#include <stdbool.h> #include <stdlib.h> #ifndef SCTP_DEBUG #ifdef CONFIG_SCTP_DBG_MSG #define SCTP_DEBUG 1 #else #define SCTP_DEBUG 0 #endif /* CONFIG_SCTP_DBG */ #endif /* SCTP_DEBUG */ #if defined(CONFIG_IP_SCTP) && defined(CONFIG_IPV6) static int some_int = 1; #endif int main() { #if defined(CONFIG_IP_SCTP) && defined(CONFIG_IPV6) // sctp_v6_get_dst(); int *dst = NULL; dst = &some_int; if (!(dst == (void *)-1)) { dst = NULL; } if (!(dst == (void *)-1)) { char *rt =(char *) dst; // SCTP_DEBUG_PRINTK(rt); // ERROR #if SCTP_DEBUG ((*rt)++); #else #endif } #endif return 0; }
. call net/sctp/ipv6.c:257:sctp_v6_get_dst() . 265: union sctp_addr *baddr = NULL; . 290: dst = ip6_dst_lookup_flow(sk, fl6, NULL, false); . 299: if (!IS_ERR(dst)) . 321: dst = NULL; // somehow `baddr' is still pointing to NULL // or maybe `dst' becomes NULL at 344 . 348: if (!IS_ERR(dst)) . 350: rt = (struct rt6_info *)dst; // `rt' is an alias for `dst' . [SCTP_DBG_MSG] 352: SCTP_DEBUG_PRINTK("rt6_dst:%pI6 rt6_src:%pI6\n", . ERROR 353: &rt->rt6i_dst.addr, &fl6->saddr);