History

batman-adv: Add flex array to struct batadv_tvlv_tt_data

The "struct batadv_tvlv_tt_data" uses a dynamically sized set of trailing elements. Specifically, it uses an array of structures of type "batadv_tvlv_tt_vlan_data". So, use the preferred way in the kernel declaring a flexible array [1]. At the same time, prepare for the coming implementation by GCC and Clang of the __counted_by attribute. Flexible array members annotated with __counted_by can have their accesses bounds-checked at run-time via CONFIG_UBSAN_BOUNDS (for array indexing) and CONFIG_FORTIFY_SOURCE (for strcpy/memcpy-family functions). In this case, it is important to note that the attribute used is specifically __counted_by_be since variable "num_vlan" is of type __be16. The following change to the "batadv_tt_tvlv_ogm_handler_v1" function: - tt_vlan = (struct batadv_tvlv_tt_vlan_data *)(tt_data + 1); - tt_change = (struct batadv_tvlv_tt_change *)(tt_vlan + num_vlan); + tt_change = (struct batadv_tvlv_tt_change *)((void *)tt_data + + flex_size); is intended to prevent the compiler from generating an "out-of-bounds" notification due to the __counted_by attribute. The compiler can do a pointer calculation using the vlan_data flexible array memory, or in other words, this may be calculated as an array offset, since it is the same as: &tt_data->vlan_data[num_vlan] Therefore, we go past the end of the array. In other "multiple trailing flexible array" situations, this has been solved by addressing from the base pointer, since the compiler either knows the full allocation size or it knows nothing about it (this case, since it came from a "void *" function argument). The order in which the structure batadv_tvlv_tt_data and the structure batadv_tvlv_tt_vlan_data are defined must be swap to avoid an incomplete type error. Also, avoid the open-coded arithmetic in memory allocator functions [2] using the "struct_size" macro and use the "flex_array_size" helper to clarify some calculations, when possible. Moreover, the new structure member also allow us to avoid the open-coded arithmetic on pointers in some situations. Take advantage of this. This code was detected with the help of Coccinelle, and audited and modified manually.

Erick Archer committed 2 years ago

Commit 4436df41 parent 0f4e6f92 files · +36 −42Browse files

Showing the changes to include/uapi (1 of 2 files). Show all

Unified · Split

include/uapi/linux/batadv_packet.h+16−13
@@ -9,6 +9,7 @@ · 8 unmodified lines
9 9
10#include <asm/byteorder.h>10#include <asm/byteorder.h>
11#include <linux/if_ether.h>11#include <linux/if_ether.h>
12#include <linux/stddef.h>
12#include <linux/types.h>13#include <linux/types.h>
13 14
14/**15/**
@@ -592,19 +593,6 @@ struct batadv_tvlv_gateway_data { · 577 unmodified lines
592 __be32 bandwidth_up;593 __be32 bandwidth_up;
593};594};
594 595
595/**
596 * struct batadv_tvlv_tt_data - tt data propagated through the tt tvlv container
597 * @flags: translation table flags (see batadv_tt_data_flags)
598 * @ttvn: translation table version number
599 * @num_vlan: number of announced VLANs. In the TVLV this struct is followed by
600 * one batadv_tvlv_tt_vlan_data object per announced vlan
601 */
602struct batadv_tvlv_tt_data {
603 __u8 flags;
604 __u8 ttvn;
605 __be16 num_vlan;
606};
607
608/**596/**
609 * struct batadv_tvlv_tt_vlan_data - vlan specific tt data propagated through597 * struct batadv_tvlv_tt_vlan_data - vlan specific tt data propagated through
610 * the tt tvlv container598 * the tt tvlv container
@@ -618,6 +606,21 @@ struct batadv_tvlv_tt_vlan_data { · 7 unmodified lines
618 __u16 reserved;606 __u16 reserved;
619};607};
620 608
609/**
610 * struct batadv_tvlv_tt_data - tt data propagated through the tt tvlv container
611 * @flags: translation table flags (see batadv_tt_data_flags)
612 * @ttvn: translation table version number
613 * @num_vlan: number of announced VLANs. In the TVLV this struct is followed by
614 * one batadv_tvlv_tt_vlan_data object per announced vlan
615 * @vlan_data: array of batadv_tvlv_tt_vlan_data objects
616 */
617struct batadv_tvlv_tt_data {
618 __u8 flags;
619 __u8 ttvn;
620 __be16 num_vlan;
621 struct batadv_tvlv_tt_vlan_data vlan_data[] __counted_by_be(num_vlan);
622};
623
621/**624/**
622 * struct batadv_tvlv_tt_change - translation table diff data625 * struct batadv_tvlv_tt_change - translation table diff data
623 * @flags: status indicators concerning the non-mesh client (see626 * @flags: status indicators concerning the non-mesh client (see