linux
Attempt to call a VLAN-related function with VLAN support disabled
Network driver ocrdma calls vlan_dev_real_dev() unconditionally. But, when !VLAN_8021Q, VLAN functions just go BUG(). The bugfix relies on testing `priv_flags' field for determining if it is a VLAN device. This flag is only set by vlan_setup(), which is not called from anywhere unless VLAN_8021Q is set.
Bug fixed by commit d549f55f2e1
Type | FatalAssertionViolation |
Config | "IPV6 && !VLAN_8021Q" (2nd degree) |
Fix-in | mapping, code |
Location | include/linux/ |
#include <assert.h> #include <stdbool.h> #include <stdlib.h> #ifdef CONFIG_VLAN_8021Q void* vlan_dev_real_dev() { return NULL; } #else void* vlan_dev_real_dev() { assert(false); // (3) ERROR return NULL; } #endif #if defined(CONFIG_IPV6) || defined(CONFIG_VLAN_8021Q) static int ocrdma_inet6addr_event() { vlan_dev_real_dev(); // (2) return 0; } #endif /* IPV6 and VLAN */ int main(int argc, char** argv) { #if defined(CONFIG_IPV6) || defined(CONFIG_VLAN_8021Q) ocrdma_inet6addr_event(); // (1) #endif return 0; }
diff --git a/simple/d549f55.c b/simple/d549f55.c --- a/simple/d549f55.c +++ b/simple/d549f55.c @@ -4,6 +4,12 @@ #include <stdlib.h> #ifdef CONFIG_VLAN_8021Q +#define IFF_802_1Q_VLAN true +#else +#define IFF_802_1Q_VLAN false +#endif + +#ifdef CONFIG_VLAN_8021Q void* vlan_dev_real_dev() { return NULL; @@ -16,10 +22,14 @@ } #endif -#if defined(CONFIG_IPV6) || defined(CONFIG_VLAN_8021Q) +#if defined(CONFIG_IPV6) static int ocrdma_inet6addr_event() { - vlan_dev_real_dev(); // (2) + bool is_vlan = IFF_802_1Q_VLAN; + + if (is_vlan) { + vlan_dev_real_dev(); + } return 0; } @@ -27,7 +37,7 @@ int main(int argc, char** argv) { -#if defined(CONFIG_IPV6) || defined(CONFIG_VLAN_8021Q) +#if defined(CONFIG_IPV6) ocrdma_inet6addr_event(); // (1) #endif return 0;
#include <assert.h> #include <stdbool.h> #include <stdlib.h> int main(int argc, char** argv) { #if defined(CONFIG_IPV6) || defined(CONFIG_VLAN_8021Q) // ocrdma_inet6addr_event(); // vlan_dev_real_dev(); #ifdef CONFIG_VLAN_8021Q return NULL; #else assert(false); // ERROR return NULL; #endif #endif return 0; }
. [IPV6 || VLAN_8021Q] drivers/infiniband/hw/ocrdma/ocrdma_main.c:207:ocrdma_inet6addr_event() . 220: netdev = vlan_dev_real_dev(event_netdev); .. [!VLAN_8021Q] include/linux/if_vlan.h:111:vlan_dev_real_dev() .. ERROR [!VLAN_8021Q] 113: BUG()