Received: by 2002:ac0:a5b6:0:0:0:0:0 with SMTP id m51-v6csp2223930imm; Thu, 7 Jun 2018 07:19:17 -0700 (PDT) X-Google-Smtp-Source: ADUXVKJcYjsFCM0pwTyqGBuCrCuo/V8Un/EIKmAR4QO7PTJPZCjzvOFdHyrMgSWXLNx2R9weqsvK X-Received: by 2002:a63:67c4:: with SMTP id b187-v6mr1749397pgc.86.1528381157408; Thu, 07 Jun 2018 07:19:17 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1528381157; cv=none; d=google.com; s=arc-20160816; b=gD3pPoGG6IP1GUZI1pMEyCTaveAFrLuU7UMdJrqwj4ipzXUqsBHfzH4ZX86r7LmQ81 fwXK+itq4mvVbwEEn7J/RTB7OQanDe0c9lWcM2i0VuDNUWgWrNdeGLsF7r21wDp1PH5t Qgw6OxI8TkRGR4KQqJ9Lm1UR8xn+cCVb22FDOdBYhg8DjcEfe68nwgaTyRvk7B1+1VEm sLZWZLFG17S1DpbqRbebcNR8GlRF7+StPFJijQNMJv6Ugaec3YhAYfBataxy3fPwwU4W gK5I4wOdprdelfIgkW6Iw7I3rxLKkdzm8OD2Axg7L0WybmRkOU2HIY+oN1Ye1bk3znS9 vrNQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:in-reply-to:subject:message-id:date:cc:to :from:mime-version:content-transfer-encoding:content-disposition :arc-authentication-results; bh=LUGuQ6QsPZZNYHRVamWvbcM8L0nNPmM3OZohQJNJr8M=; b=eKXVytXIQyunw6EZM+w/hUYgHWDgTadcL2fFrxgWgcXFZvJHgl+aCvlanMZ7rjm6ob /p1xImd3/bhK0YO6xvB713AxsnofSxmLtMBXSqL3kON5HuTczDMvh23auVe7loTNTFb7 v2UVDWqVWRz/zhlaa3VfwsoUcwgys6LTHH4/6NMYTYcJF/+1K5i8N+BEOy/hYLE+9n7S sDA0LH7BU3VfUTq8nsJKAnLIzh5Zj0obRksVu8BCr1WcacDRiyZ5qoGbqwuQytAGDUhr u/zlNvHIaL+UV/KsoplRpSDmIGXj8cGX9NCVyYKzXCb4NbF6VuXkfvZPLdsNq8X4VwCl B7lg== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id f8-v6si28645042pgr.35.2018.06.07.07.19.02; Thu, 07 Jun 2018 07:19:17 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933402AbeFGORz (ORCPT + 99 others); Thu, 7 Jun 2018 10:17:55 -0400 Received: from shadbolt.e.decadent.org.uk ([88.96.1.126]:39527 "EHLO shadbolt.e.decadent.org.uk" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S933095AbeFGOJN (ORCPT ); Thu, 7 Jun 2018 10:09:13 -0400 Received: from [148.252.241.226] (helo=deadeye) by shadbolt.decadent.org.uk with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.84_2) (envelope-from ) id 1fQvbD-0005Zj-DY; Thu, 07 Jun 2018 15:09:11 +0100 Received: from ben by deadeye with local (Exim 4.91) (envelope-from ) id 1fQvb9-00038T-RH; Thu, 07 Jun 2018 15:09:07 +0100 Content-Type: text/plain; charset="UTF-8" Content-Disposition: inline Content-Transfer-Encoding: 8bit MIME-Version: 1.0 From: Ben Hutchings To: linux-kernel@vger.kernel.org, stable@vger.kernel.org CC: akpm@linux-foundation.org, "Sven Eckelmann" , "Simon Wunderlich" Date: Thu, 07 Jun 2018 15:05:21 +0100 Message-ID: X-Mailer: LinuxStableQueue (scripts by bwh) Subject: [PATCH 3.16 285/410] batman-adv: Fix internal interface indices types In-Reply-To: X-SA-Exim-Connect-IP: 148.252.241.226 X-SA-Exim-Mail-From: ben@decadent.org.uk X-SA-Exim-Scanned: No (on shadbolt.decadent.org.uk); SAEximRunCond expanded to false Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 3.16.57-rc1 review patch. If anyone has any objections, please let me know. ------------------ From: Sven Eckelmann commit f22e08932c2960f29b5e828e745c9f3fb7c1bb86 upstream. 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: c6c8fea29769 ("net: Add batman-adv meshing protocol") Signed-off-by: Sven Eckelmann Signed-off-by: Simon Wunderlich [bwh: Backported to 3.16: - Drop changes in batadv_iv_ogm_{drop_bcast_{own,sum}_entry,orig_get}() - Adjust context] Signed-off-by: Ben Hutchings --- --- a/net/batman-adv/bat_iv_ogm.c +++ b/net/batman-adv/bat_iv_ogm.c @@ -105,7 +105,7 @@ static void batadv_iv_ogm_orig_free(stru * Returns 0 on success, a negative error code otherwise. */ static int batadv_iv_ogm_orig_add_if(struct batadv_orig_node *orig_node, - int max_if_num) + unsigned int max_if_num) { void *data_ptr; size_t data_size, old_size; @@ -150,7 +150,8 @@ unlock: * Returns 0 on success, a negative error code otherwise. */ static int batadv_iv_ogm_orig_del_if(struct batadv_orig_node *orig_node, - int max_if_num, int del_if_num) + unsigned int max_if_num, + unsigned int del_if_num) { int chunk_size, ret = -ENOMEM, if_offset; void *data_ptr = NULL; @@ -867,7 +868,7 @@ batadv_iv_ogm_slide_own_bcast_window(str uint32_t i; size_t word_index; uint8_t *w; - int if_num; + unsigned int if_num; for (i = 0; i < hash->size; i++) { head = &hash->table[i]; @@ -977,7 +978,7 @@ batadv_iv_ogm_orig_update(struct batadv_ struct batadv_neigh_node *neigh_node = NULL, *tmp_neigh_node = NULL; struct batadv_neigh_node *router = NULL; struct batadv_orig_node *orig_node_tmp; - int if_num; + unsigned int if_num; uint8_t sum_orig, sum_neigh; uint8_t *neigh_addr; uint8_t tq_avg; @@ -1134,7 +1135,8 @@ static int batadv_iv_ogm_calc_tq(struct uint8_t total_count; uint8_t orig_eq_count, neigh_rq_count, neigh_rq_inv, tq_own; unsigned int neigh_rq_inv_cube, neigh_rq_max_cube; - int if_num, ret = 0; + unsigned int if_num; + int ret = 0; unsigned int tq_asym_penalty, inv_asym_penalty; unsigned int combined_tq; unsigned int tq_iface_penalty; @@ -1641,9 +1643,9 @@ static void batadv_iv_ogm_process(const if (is_my_orig) { unsigned long *word; - int offset; + size_t offset; int32_t bit_pos; - int16_t if_num; + unsigned int if_num; uint8_t *weight; orig_neigh_node = batadv_iv_ogm_orig_get(bat_priv, --- a/net/batman-adv/hard-interface.c +++ b/net/batman-adv/hard-interface.c @@ -411,6 +411,11 @@ int batadv_hardif_enable_interface(struc hard_iface->soft_iface = soft_iface; bat_priv = netdev_priv(hard_iface->soft_iface); + if (bat_priv->num_ifaces >= UINT_MAX) { + ret = -ENOSPC; + goto err_dev; + } + ret = netdev_master_upper_dev_link(hard_iface->net_dev, soft_iface); if (ret) goto err_dev; @@ -514,7 +519,7 @@ void batadv_hardif_disable_interface(str dev_put(hard_iface->soft_iface); /* nobody uses this interface anymore */ - if (!bat_priv->num_ifaces) { + if (bat_priv->num_ifaces == 0) { batadv_gw_check_client_stop(bat_priv); if (autodel == BATADV_IF_CLEANUP_AUTO) @@ -571,7 +576,7 @@ batadv_hardif_add_interface(struct net_d if (ret) goto free_if; - hard_iface->if_num = -1; + hard_iface->if_num = 0; hard_iface->net_dev = net_dev; hard_iface->soft_iface = NULL; hard_iface->if_status = BATADV_IF_NOT_IN_USE; --- a/net/batman-adv/originator.c +++ b/net/batman-adv/originator.c @@ -1069,7 +1069,7 @@ out: } int batadv_orig_hash_add_if(struct batadv_hard_iface *hard_iface, - int max_if_num) + unsigned int max_if_num) { struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface); struct batadv_algo_ops *bao = bat_priv->bat_algo_ops; @@ -1105,7 +1105,7 @@ err: } int batadv_orig_hash_del_if(struct batadv_hard_iface *hard_iface, - int max_if_num) + unsigned int max_if_num) { struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface); struct batadv_hashtable *hash = bat_priv->orig_hash; --- a/net/batman-adv/originator.h +++ b/net/batman-adv/originator.h @@ -58,9 +58,9 @@ void batadv_orig_ifinfo_free_ref(struct int batadv_orig_seq_print_text(struct seq_file *seq, void *offset); int batadv_orig_hardif_seq_print_text(struct seq_file *seq, void *offset); int batadv_orig_hash_add_if(struct batadv_hard_iface *hard_iface, - int max_if_num); + unsigned int max_if_num); int batadv_orig_hash_del_if(struct batadv_hard_iface *hard_iface, - int max_if_num); + unsigned int max_if_num); struct batadv_orig_node_vlan * batadv_orig_node_vlan_new(struct batadv_orig_node *orig_node, unsigned short vid); --- a/net/batman-adv/types.h +++ b/net/batman-adv/types.h @@ -89,7 +89,7 @@ struct batadv_hard_iface_bat_iv { */ struct batadv_hard_iface { struct list_head list; - int16_t if_num; + unsigned int if_num; char if_status; struct net_device *net_dev; uint8_t num_bcasts; @@ -795,7 +795,7 @@ struct batadv_priv { atomic_t bcast_seqno; atomic_t bcast_queue_left; atomic_t batman_queue_left; - char num_ifaces; + unsigned int num_ifaces; struct kobject *mesh_obj; struct dentry *debug_dir; struct hlist_head forw_bat_list; @@ -1166,9 +1166,10 @@ struct batadv_algo_ops { struct batadv_hard_iface *hard_iface); void (*bat_orig_free)(struct batadv_orig_node *orig_node); int (*bat_orig_add_if)(struct batadv_orig_node *orig_node, - int max_if_num); + unsigned int max_if_num); int (*bat_orig_del_if)(struct batadv_orig_node *orig_node, - int max_if_num, int del_if_num); + unsigned int max_if_num, + unsigned int del_if_num); }; /**