Skip to content

Commit f22e089

Browse files
ecsvsimonwunderlich
authored andcommitted
batman-adv: Fix internal interface indices types
batman-adv uses internal indices for each enabled and active interface. It is currently used by the B.A.T.M.A.N. IV algorithm to identifify the correct position in the ogm_cnt bitmaps. The type for the number of enabled interfaces (which defines the next interface index) was set to char. This type can be (depending on the architecture) either signed (limiting batman-adv to 127 active slave interfaces) or unsigned (limiting batman-adv to 255 active slave interfaces). This limit was not correctly checked when an interface was enabled and thus an overflow happened. This was only catched on systems with the signed char type when the B.A.T.M.A.N. IV code tried to resize its counter arrays with a negative size. The if_num interface index was only a s16 and therefore significantly smaller than the ifindex (int) used by the code net code. Both &batadv_hard_iface->if_num and &batadv_priv->num_ifaces must be (unsigned) int to support the same number of slave interfaces as the net core code. And the interface activation code must check the number of active slave interfaces to avoid integer overflows. Fixes: c6c8fea ("net: Add batman-adv meshing protocol") Signed-off-by: Sven Eckelmann <[email protected]> Signed-off-by: Simon Wunderlich <[email protected]>
1 parent fce672d commit f22e089

File tree

5 files changed

+31
-21
lines changed

5 files changed

+31
-21
lines changed

net/batman-adv/bat_iv_ogm.c

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ static void batadv_iv_ogm_orig_free(struct batadv_orig_node *orig_node)
157157
* Return: 0 on success, a negative error code otherwise.
158158
*/
159159
static int batadv_iv_ogm_orig_add_if(struct batadv_orig_node *orig_node,
160-
int max_if_num)
160+
unsigned int max_if_num)
161161
{
162162
void *data_ptr;
163163
size_t old_size;
@@ -201,7 +201,8 @@ static int batadv_iv_ogm_orig_add_if(struct batadv_orig_node *orig_node,
201201
*/
202202
static void
203203
batadv_iv_ogm_drop_bcast_own_entry(struct batadv_orig_node *orig_node,
204-
int max_if_num, int del_if_num)
204+
unsigned int max_if_num,
205+
unsigned int del_if_num)
205206
{
206207
size_t chunk_size;
207208
size_t if_offset;
@@ -239,7 +240,8 @@ batadv_iv_ogm_drop_bcast_own_entry(struct batadv_orig_node *orig_node,
239240
*/
240241
static void
241242
batadv_iv_ogm_drop_bcast_own_sum_entry(struct batadv_orig_node *orig_node,
242-
int max_if_num, int del_if_num)
243+
unsigned int max_if_num,
244+
unsigned int del_if_num)
243245
{
244246
size_t if_offset;
245247
void *data_ptr;
@@ -276,7 +278,8 @@ batadv_iv_ogm_drop_bcast_own_sum_entry(struct batadv_orig_node *orig_node,
276278
* Return: 0 on success, a negative error code otherwise.
277279
*/
278280
static int batadv_iv_ogm_orig_del_if(struct batadv_orig_node *orig_node,
279-
int max_if_num, int del_if_num)
281+
unsigned int max_if_num,
282+
unsigned int del_if_num)
280283
{
281284
spin_lock_bh(&orig_node->bat_iv.ogm_cnt_lock);
282285

@@ -311,7 +314,8 @@ static struct batadv_orig_node *
311314
batadv_iv_ogm_orig_get(struct batadv_priv *bat_priv, const u8 *addr)
312315
{
313316
struct batadv_orig_node *orig_node;
314-
int size, hash_added;
317+
int hash_added;
318+
size_t size;
315319

316320
orig_node = batadv_orig_hash_find(bat_priv, addr);
317321
if (orig_node)
@@ -893,7 +897,7 @@ batadv_iv_ogm_slide_own_bcast_window(struct batadv_hard_iface *hard_iface)
893897
u32 i;
894898
size_t word_index;
895899
u8 *w;
896-
int if_num;
900+
unsigned int if_num;
897901

898902
for (i = 0; i < hash->size; i++) {
899903
head = &hash->table[i];
@@ -1023,7 +1027,7 @@ batadv_iv_ogm_orig_update(struct batadv_priv *bat_priv,
10231027
struct batadv_neigh_node *tmp_neigh_node = NULL;
10241028
struct batadv_neigh_node *router = NULL;
10251029
struct batadv_orig_node *orig_node_tmp;
1026-
int if_num;
1030+
unsigned int if_num;
10271031
u8 sum_orig, sum_neigh;
10281032
u8 *neigh_addr;
10291033
u8 tq_avg;
@@ -1182,7 +1186,7 @@ static bool batadv_iv_ogm_calc_tq(struct batadv_orig_node *orig_node,
11821186
u8 total_count;
11831187
u8 orig_eq_count, neigh_rq_count, neigh_rq_inv, tq_own;
11841188
unsigned int neigh_rq_inv_cube, neigh_rq_max_cube;
1185-
int if_num;
1189+
unsigned int if_num;
11861190
unsigned int tq_asym_penalty, inv_asym_penalty;
11871191
unsigned int combined_tq;
11881192
unsigned int tq_iface_penalty;
@@ -1702,9 +1706,9 @@ static void batadv_iv_ogm_process(const struct sk_buff *skb, int ogm_offset,
17021706

17031707
if (is_my_orig) {
17041708
unsigned long *word;
1705-
int offset;
1709+
size_t offset;
17061710
s32 bit_pos;
1707-
s16 if_num;
1711+
unsigned int if_num;
17081712
u8 *weight;
17091713

17101714
orig_neigh_node = batadv_iv_ogm_orig_get(bat_priv,

net/batman-adv/hard-interface.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -763,6 +763,11 @@ int batadv_hardif_enable_interface(struct batadv_hard_iface *hard_iface,
763763
hard_iface->soft_iface = soft_iface;
764764
bat_priv = netdev_priv(hard_iface->soft_iface);
765765

766+
if (bat_priv->num_ifaces >= UINT_MAX) {
767+
ret = -ENOSPC;
768+
goto err_dev;
769+
}
770+
766771
ret = netdev_master_upper_dev_link(hard_iface->net_dev,
767772
soft_iface, NULL, NULL, NULL);
768773
if (ret)
@@ -876,7 +881,7 @@ void batadv_hardif_disable_interface(struct batadv_hard_iface *hard_iface,
876881
batadv_hardif_recalc_extra_skbroom(hard_iface->soft_iface);
877882

878883
/* nobody uses this interface anymore */
879-
if (!bat_priv->num_ifaces) {
884+
if (bat_priv->num_ifaces == 0) {
880885
batadv_gw_check_client_stop(bat_priv);
881886

882887
if (autodel == BATADV_IF_CLEANUP_AUTO)
@@ -912,7 +917,7 @@ batadv_hardif_add_interface(struct net_device *net_dev)
912917
if (ret)
913918
goto free_if;
914919

915-
hard_iface->if_num = -1;
920+
hard_iface->if_num = 0;
916921
hard_iface->net_dev = net_dev;
917922
hard_iface->soft_iface = NULL;
918923
hard_iface->if_status = BATADV_IF_NOT_IN_USE;

net/batman-adv/originator.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1569,7 +1569,7 @@ int batadv_orig_dump(struct sk_buff *msg, struct netlink_callback *cb)
15691569
* Return: 0 on success or negative error number in case of failure
15701570
*/
15711571
int batadv_orig_hash_add_if(struct batadv_hard_iface *hard_iface,
1572-
int max_if_num)
1572+
unsigned int max_if_num)
15731573
{
15741574
struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface);
15751575
struct batadv_algo_ops *bao = bat_priv->algo_ops;
@@ -1611,7 +1611,7 @@ int batadv_orig_hash_add_if(struct batadv_hard_iface *hard_iface,
16111611
* Return: 0 on success or negative error number in case of failure
16121612
*/
16131613
int batadv_orig_hash_del_if(struct batadv_hard_iface *hard_iface,
1614-
int max_if_num)
1614+
unsigned int max_if_num)
16151615
{
16161616
struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface);
16171617
struct batadv_hashtable *hash = bat_priv->orig_hash;

net/batman-adv/originator.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,9 +73,9 @@ int batadv_orig_seq_print_text(struct seq_file *seq, void *offset);
7373
int batadv_orig_dump(struct sk_buff *msg, struct netlink_callback *cb);
7474
int batadv_orig_hardif_seq_print_text(struct seq_file *seq, void *offset);
7575
int batadv_orig_hash_add_if(struct batadv_hard_iface *hard_iface,
76-
int max_if_num);
76+
unsigned int max_if_num);
7777
int batadv_orig_hash_del_if(struct batadv_hard_iface *hard_iface,
78-
int max_if_num);
78+
unsigned int max_if_num);
7979
struct batadv_orig_node_vlan *
8080
batadv_orig_node_vlan_new(struct batadv_orig_node *orig_node,
8181
unsigned short vid);

net/batman-adv/types.h

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ struct batadv_hard_iface {
167167
struct list_head list;
168168

169169
/** @if_num: identificator of the interface */
170-
s16 if_num;
170+
unsigned int if_num;
171171

172172
/** @if_status: status of the interface for batman-adv */
173173
char if_status;
@@ -1596,7 +1596,7 @@ struct batadv_priv {
15961596
atomic_t batman_queue_left;
15971597

15981598
/** @num_ifaces: number of interfaces assigned to this mesh interface */
1599-
char num_ifaces;
1599+
unsigned int num_ifaces;
16001600

16011601
/** @mesh_obj: kobject for sysfs mesh subdirectory */
16021602
struct kobject *mesh_obj;
@@ -2186,15 +2186,16 @@ struct batadv_algo_orig_ops {
21862186
* orig_node due to a new hard-interface being added into the mesh
21872187
* (optional)
21882188
*/
2189-
int (*add_if)(struct batadv_orig_node *orig_node, int max_if_num);
2189+
int (*add_if)(struct batadv_orig_node *orig_node,
2190+
unsigned int max_if_num);
21902191

21912192
/**
21922193
* @del_if: ask the routing algorithm to apply the needed changes to the
21932194
* orig_node due to an hard-interface being removed from the mesh
21942195
* (optional)
21952196
*/
2196-
int (*del_if)(struct batadv_orig_node *orig_node, int max_if_num,
2197-
int del_if_num);
2197+
int (*del_if)(struct batadv_orig_node *orig_node,
2198+
unsigned int max_if_num, unsigned int del_if_num);
21982199

21992200
#ifdef CONFIG_BATMAN_ADV_DEBUGFS
22002201
/** @print: print the originator table (optional) */

0 commit comments

Comments
 (0)