batman-adv: Check ptr for NULL before reducing its refcnt

commit 6340dcbd619450c1bb55eb999e554e4f0e6dab0a upstream.

The commit b37a46683739 ("netdevice: add the case if dev is NULL") changed
the way how the NULL check for net_devices have to be handled when trying
to reduce its reference counter. Before this commit, it was the
responsibility of the caller to check whether the object is NULL or not.
But it was changed to behave more like kfree. Now the callee has to handle
the NULL-case.

The batman-adv code was scanned via cocinelle for similar places. These
were changed to use the paradigm

  @@
  identifier E, T, R, C;
  identifier put;
  @@
   void put(struct T *E)
   {
  +	if (!E)
  +		return;
  	kref_put(&E->C, R);
   }

Functions which were used in other sources files were moved to the header
to allow the compiler to inline the NULL check and the kref_put call.

Signed-off-by: Sven Eckelmann <sven@narfation.org>
Signed-off-by: Simon Wunderlich <sw@simonwunderlich.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
Sven Eckelmann 2021-08-08 19:56:17 +02:00 committed by Greg Kroah-Hartman
parent f6da750bfa
commit 73f7cbb151
14 changed files with 181 additions and 113 deletions

View File

@ -164,6 +164,9 @@ static void batadv_backbone_gw_release(struct kref *ref)
*/
static void batadv_backbone_gw_put(struct batadv_bla_backbone_gw *backbone_gw)
{
if (!backbone_gw)
return;
kref_put(&backbone_gw->refcount, batadv_backbone_gw_release);
}
@ -199,6 +202,9 @@ static void batadv_claim_release(struct kref *ref)
*/
static void batadv_claim_put(struct batadv_bla_claim *claim)
{
if (!claim)
return;
kref_put(&claim->refcount, batadv_claim_release);
}

View File

@ -128,6 +128,9 @@ static void batadv_dat_entry_release(struct kref *ref)
*/
static void batadv_dat_entry_put(struct batadv_dat_entry *dat_entry)
{
if (!dat_entry)
return;
kref_put(&dat_entry->refcount, batadv_dat_entry_release);
}

View File

@ -60,7 +60,7 @@
* after rcu grace period
* @ref: kref pointer of the gw_node
*/
static void batadv_gw_node_release(struct kref *ref)
void batadv_gw_node_release(struct kref *ref)
{
struct batadv_gw_node *gw_node;
@ -70,16 +70,6 @@ static void batadv_gw_node_release(struct kref *ref)
kfree_rcu(gw_node, rcu);
}
/**
* batadv_gw_node_put() - decrement the gw_node refcounter and possibly release
* it
* @gw_node: gateway node to free
*/
void batadv_gw_node_put(struct batadv_gw_node *gw_node)
{
kref_put(&gw_node->refcount, batadv_gw_node_release);
}
/**
* batadv_gw_get_selected_gw_node() - Get currently selected gateway
* @bat_priv: the bat priv with all the soft interface information

View File

@ -9,6 +9,7 @@
#include "main.h"
#include <linux/kref.h>
#include <linux/netlink.h>
#include <linux/seq_file.h>
#include <linux/skbuff.h>
@ -28,7 +29,7 @@ void batadv_gw_node_update(struct batadv_priv *bat_priv,
void batadv_gw_node_delete(struct batadv_priv *bat_priv,
struct batadv_orig_node *orig_node);
void batadv_gw_node_free(struct batadv_priv *bat_priv);
void batadv_gw_node_put(struct batadv_gw_node *gw_node);
void batadv_gw_node_release(struct kref *ref);
struct batadv_gw_node *
batadv_gw_get_selected_gw_node(struct batadv_priv *bat_priv);
int batadv_gw_client_seq_print_text(struct seq_file *seq, void *offset);
@ -40,4 +41,17 @@ batadv_gw_dhcp_recipient_get(struct sk_buff *skb, unsigned int *header_len,
struct batadv_gw_node *batadv_gw_node_get(struct batadv_priv *bat_priv,
struct batadv_orig_node *orig_node);
/**
* batadv_gw_node_put() - decrement the gw_node refcounter and possibly release
* it
* @gw_node: gateway node to free
*/
static inline void batadv_gw_node_put(struct batadv_gw_node *gw_node)
{
if (!gw_node)
return;
kref_put(&gw_node->refcount, batadv_gw_node_release);
}
#endif /* _NET_BATMAN_ADV_GATEWAY_CLIENT_H_ */

View File

@ -113,6 +113,9 @@ int batadv_hardif_no_broadcast(struct batadv_hard_iface *if_outgoing,
*/
static inline void batadv_hardif_put(struct batadv_hard_iface *hard_iface)
{
if (!hard_iface)
return;
kref_put(&hard_iface->refcount, batadv_hardif_release);
}

View File

@ -222,6 +222,9 @@ static void batadv_nc_node_release(struct kref *ref)
*/
static void batadv_nc_node_put(struct batadv_nc_node *nc_node)
{
if (!nc_node)
return;
kref_put(&nc_node->refcount, batadv_nc_node_release);
}
@ -246,6 +249,9 @@ static void batadv_nc_path_release(struct kref *ref)
*/
static void batadv_nc_path_put(struct batadv_nc_path *nc_path)
{
if (!nc_path)
return;
kref_put(&nc_path->refcount, batadv_nc_path_release);
}

View File

@ -178,7 +178,7 @@ batadv_orig_node_vlan_new(struct batadv_orig_node *orig_node,
* and queue for free after rcu grace period
* @ref: kref pointer of the originator-vlan object
*/
static void batadv_orig_node_vlan_release(struct kref *ref)
void batadv_orig_node_vlan_release(struct kref *ref)
{
struct batadv_orig_node_vlan *orig_vlan;
@ -187,16 +187,6 @@ static void batadv_orig_node_vlan_release(struct kref *ref)
kfree_rcu(orig_vlan, rcu);
}
/**
* batadv_orig_node_vlan_put() - decrement the refcounter and possibly release
* the originator-vlan object
* @orig_vlan: the originator-vlan object to release
*/
void batadv_orig_node_vlan_put(struct batadv_orig_node_vlan *orig_vlan)
{
kref_put(&orig_vlan->refcount, batadv_orig_node_vlan_release);
}
/**
* batadv_originator_init() - Initialize all originator structures
* @bat_priv: the bat priv with all the soft interface information
@ -232,7 +222,7 @@ int batadv_originator_init(struct batadv_priv *bat_priv)
* free after rcu grace period
* @ref: kref pointer of the neigh_ifinfo
*/
static void batadv_neigh_ifinfo_release(struct kref *ref)
void batadv_neigh_ifinfo_release(struct kref *ref)
{
struct batadv_neigh_ifinfo *neigh_ifinfo;
@ -244,22 +234,12 @@ static void batadv_neigh_ifinfo_release(struct kref *ref)
kfree_rcu(neigh_ifinfo, rcu);
}
/**
* batadv_neigh_ifinfo_put() - decrement the refcounter and possibly release
* the neigh_ifinfo
* @neigh_ifinfo: the neigh_ifinfo object to release
*/
void batadv_neigh_ifinfo_put(struct batadv_neigh_ifinfo *neigh_ifinfo)
{
kref_put(&neigh_ifinfo->refcount, batadv_neigh_ifinfo_release);
}
/**
* batadv_hardif_neigh_release() - release hardif neigh node from lists and
* queue for free after rcu grace period
* @ref: kref pointer of the neigh_node
*/
static void batadv_hardif_neigh_release(struct kref *ref)
void batadv_hardif_neigh_release(struct kref *ref)
{
struct batadv_hardif_neigh_node *hardif_neigh;
@ -274,22 +254,12 @@ static void batadv_hardif_neigh_release(struct kref *ref)
kfree_rcu(hardif_neigh, rcu);
}
/**
* batadv_hardif_neigh_put() - decrement the hardif neighbors refcounter
* and possibly release it
* @hardif_neigh: hardif neigh neighbor to free
*/
void batadv_hardif_neigh_put(struct batadv_hardif_neigh_node *hardif_neigh)
{
kref_put(&hardif_neigh->refcount, batadv_hardif_neigh_release);
}
/**
* batadv_neigh_node_release() - release neigh_node from lists and queue for
* free after rcu grace period
* @ref: kref pointer of the neigh_node
*/
static void batadv_neigh_node_release(struct kref *ref)
void batadv_neigh_node_release(struct kref *ref)
{
struct hlist_node *node_tmp;
struct batadv_neigh_node *neigh_node;
@ -309,16 +279,6 @@ static void batadv_neigh_node_release(struct kref *ref)
kfree_rcu(neigh_node, rcu);
}
/**
* batadv_neigh_node_put() - decrement the neighbors refcounter and possibly
* release it
* @neigh_node: neigh neighbor to free
*/
void batadv_neigh_node_put(struct batadv_neigh_node *neigh_node)
{
kref_put(&neigh_node->refcount, batadv_neigh_node_release);
}
/**
* batadv_orig_router_get() - router to the originator depending on iface
* @orig_node: the orig node for the router
@ -851,7 +811,7 @@ int batadv_hardif_neigh_dump(struct sk_buff *msg, struct netlink_callback *cb)
* free after rcu grace period
* @ref: kref pointer of the orig_ifinfo
*/
static void batadv_orig_ifinfo_release(struct kref *ref)
void batadv_orig_ifinfo_release(struct kref *ref)
{
struct batadv_orig_ifinfo *orig_ifinfo;
struct batadv_neigh_node *router;
@ -869,16 +829,6 @@ static void batadv_orig_ifinfo_release(struct kref *ref)
kfree_rcu(orig_ifinfo, rcu);
}
/**
* batadv_orig_ifinfo_put() - decrement the refcounter and possibly release
* the orig_ifinfo
* @orig_ifinfo: the orig_ifinfo object to release
*/
void batadv_orig_ifinfo_put(struct batadv_orig_ifinfo *orig_ifinfo)
{
kref_put(&orig_ifinfo->refcount, batadv_orig_ifinfo_release);
}
/**
* batadv_orig_node_free_rcu() - free the orig_node
* @rcu: rcu pointer of the orig_node
@ -902,7 +852,7 @@ static void batadv_orig_node_free_rcu(struct rcu_head *rcu)
* free after rcu grace period
* @ref: kref pointer of the orig_node
*/
static void batadv_orig_node_release(struct kref *ref)
void batadv_orig_node_release(struct kref *ref)
{
struct hlist_node *node_tmp;
struct batadv_neigh_node *neigh_node;
@ -948,16 +898,6 @@ static void batadv_orig_node_release(struct kref *ref)
call_rcu(&orig_node->rcu, batadv_orig_node_free_rcu);
}
/**
* batadv_orig_node_put() - decrement the orig node refcounter and possibly
* release it
* @orig_node: the orig node to free
*/
void batadv_orig_node_put(struct batadv_orig_node *orig_node)
{
kref_put(&orig_node->refcount, batadv_orig_node_release);
}
/**
* batadv_originator_free() - Free all originator structures
* @bat_priv: the bat priv with all the soft interface information

View File

@ -12,6 +12,7 @@
#include <linux/compiler.h>
#include <linux/if_ether.h>
#include <linux/jhash.h>
#include <linux/kref.h>
#include <linux/netlink.h>
#include <linux/seq_file.h>
#include <linux/skbuff.h>
@ -21,19 +22,18 @@ bool batadv_compare_orig(const struct hlist_node *node, const void *data2);
int batadv_originator_init(struct batadv_priv *bat_priv);
void batadv_originator_free(struct batadv_priv *bat_priv);
void batadv_purge_orig_ref(struct batadv_priv *bat_priv);
void batadv_orig_node_put(struct batadv_orig_node *orig_node);
void batadv_orig_node_release(struct kref *ref);
struct batadv_orig_node *batadv_orig_node_new(struct batadv_priv *bat_priv,
const u8 *addr);
struct batadv_hardif_neigh_node *
batadv_hardif_neigh_get(const struct batadv_hard_iface *hard_iface,
const u8 *neigh_addr);
void
batadv_hardif_neigh_put(struct batadv_hardif_neigh_node *hardif_neigh);
void batadv_hardif_neigh_release(struct kref *ref);
struct batadv_neigh_node *
batadv_neigh_node_get_or_create(struct batadv_orig_node *orig_node,
struct batadv_hard_iface *hard_iface,
const u8 *neigh_addr);
void batadv_neigh_node_put(struct batadv_neigh_node *neigh_node);
void batadv_neigh_node_release(struct kref *ref);
struct batadv_neigh_node *
batadv_orig_router_get(struct batadv_orig_node *orig_node,
const struct batadv_hard_iface *if_outgoing);
@ -43,7 +43,7 @@ batadv_neigh_ifinfo_new(struct batadv_neigh_node *neigh,
struct batadv_neigh_ifinfo *
batadv_neigh_ifinfo_get(struct batadv_neigh_node *neigh,
struct batadv_hard_iface *if_outgoing);
void batadv_neigh_ifinfo_put(struct batadv_neigh_ifinfo *neigh_ifinfo);
void batadv_neigh_ifinfo_release(struct kref *ref);
int batadv_hardif_neigh_dump(struct sk_buff *msg, struct netlink_callback *cb);
int batadv_hardif_neigh_seq_print_text(struct seq_file *seq, void *offset);
@ -54,7 +54,7 @@ batadv_orig_ifinfo_get(struct batadv_orig_node *orig_node,
struct batadv_orig_ifinfo *
batadv_orig_ifinfo_new(struct batadv_orig_node *orig_node,
struct batadv_hard_iface *if_outgoing);
void batadv_orig_ifinfo_put(struct batadv_orig_ifinfo *orig_ifinfo);
void batadv_orig_ifinfo_release(struct kref *ref);
int batadv_orig_seq_print_text(struct seq_file *seq, void *offset);
int batadv_orig_dump(struct sk_buff *msg, struct netlink_callback *cb);
@ -65,7 +65,7 @@ batadv_orig_node_vlan_new(struct batadv_orig_node *orig_node,
struct batadv_orig_node_vlan *
batadv_orig_node_vlan_get(struct batadv_orig_node *orig_node,
unsigned short vid);
void batadv_orig_node_vlan_put(struct batadv_orig_node_vlan *orig_vlan);
void batadv_orig_node_vlan_release(struct kref *ref);
/**
* batadv_choose_orig() - Return the index of the orig entry in the hash table
@ -86,4 +86,86 @@ static inline u32 batadv_choose_orig(const void *data, u32 size)
struct batadv_orig_node *
batadv_orig_hash_find(struct batadv_priv *bat_priv, const void *data);
/**
* batadv_orig_node_vlan_put() - decrement the refcounter and possibly release
* the originator-vlan object
* @orig_vlan: the originator-vlan object to release
*/
static inline void
batadv_orig_node_vlan_put(struct batadv_orig_node_vlan *orig_vlan)
{
if (!orig_vlan)
return;
kref_put(&orig_vlan->refcount, batadv_orig_node_vlan_release);
}
/**
* batadv_neigh_ifinfo_put() - decrement the refcounter and possibly release
* the neigh_ifinfo
* @neigh_ifinfo: the neigh_ifinfo object to release
*/
static inline void
batadv_neigh_ifinfo_put(struct batadv_neigh_ifinfo *neigh_ifinfo)
{
if (!neigh_ifinfo)
return;
kref_put(&neigh_ifinfo->refcount, batadv_neigh_ifinfo_release);
}
/**
* batadv_hardif_neigh_put() - decrement the hardif neighbors refcounter
* and possibly release it
* @hardif_neigh: hardif neigh neighbor to free
*/
static inline void
batadv_hardif_neigh_put(struct batadv_hardif_neigh_node *hardif_neigh)
{
if (!hardif_neigh)
return;
kref_put(&hardif_neigh->refcount, batadv_hardif_neigh_release);
}
/**
* batadv_neigh_node_put() - decrement the neighbors refcounter and possibly
* release it
* @neigh_node: neigh neighbor to free
*/
static inline void batadv_neigh_node_put(struct batadv_neigh_node *neigh_node)
{
if (!neigh_node)
return;
kref_put(&neigh_node->refcount, batadv_neigh_node_release);
}
/**
* batadv_orig_ifinfo_put() - decrement the refcounter and possibly release
* the orig_ifinfo
* @orig_ifinfo: the orig_ifinfo object to release
*/
static inline void
batadv_orig_ifinfo_put(struct batadv_orig_ifinfo *orig_ifinfo)
{
if (!orig_ifinfo)
return;
kref_put(&orig_ifinfo->refcount, batadv_orig_ifinfo_release);
}
/**
* batadv_orig_node_put() - decrement the orig node refcounter and possibly
* release it
* @orig_node: the orig node to free
*/
static inline void batadv_orig_node_put(struct batadv_orig_node *orig_node)
{
if (!orig_node)
return;
kref_put(&orig_node->refcount, batadv_orig_node_release);
}
#endif /* _NET_BATMAN_ADV_ORIGINATOR_H_ */

View File

@ -512,7 +512,7 @@ void batadv_interface_rx(struct net_device *soft_iface,
* after rcu grace period
* @ref: kref pointer of the vlan object
*/
static void batadv_softif_vlan_release(struct kref *ref)
void batadv_softif_vlan_release(struct kref *ref)
{
struct batadv_softif_vlan *vlan;
@ -525,19 +525,6 @@ static void batadv_softif_vlan_release(struct kref *ref)
kfree_rcu(vlan, rcu);
}
/**
* batadv_softif_vlan_put() - decrease the vlan object refcounter and
* possibly release it
* @vlan: the vlan object to release
*/
void batadv_softif_vlan_put(struct batadv_softif_vlan *vlan)
{
if (!vlan)
return;
kref_put(&vlan->refcount, batadv_softif_vlan_release);
}
/**
* batadv_softif_vlan_get() - get the vlan object for a specific vid
* @bat_priv: the bat priv with all the soft interface information

View File

@ -9,6 +9,7 @@
#include "main.h"
#include <linux/kref.h>
#include <linux/netdevice.h>
#include <linux/skbuff.h>
#include <linux/types.h>
@ -24,8 +25,21 @@ void batadv_softif_destroy_sysfs(struct net_device *soft_iface);
bool batadv_softif_is_valid(const struct net_device *net_dev);
extern struct rtnl_link_ops batadv_link_ops;
int batadv_softif_create_vlan(struct batadv_priv *bat_priv, unsigned short vid);
void batadv_softif_vlan_put(struct batadv_softif_vlan *softif_vlan);
void batadv_softif_vlan_release(struct kref *ref);
struct batadv_softif_vlan *batadv_softif_vlan_get(struct batadv_priv *bat_priv,
unsigned short vid);
/**
* batadv_softif_vlan_put() - decrease the vlan object refcounter and
* possibly release it
* @vlan: the vlan object to release
*/
static inline void batadv_softif_vlan_put(struct batadv_softif_vlan *vlan)
{
if (!vlan)
return;
kref_put(&vlan->refcount, batadv_softif_vlan_release);
}
#endif /* _NET_BATMAN_ADV_SOFT_INTERFACE_H_ */

View File

@ -357,6 +357,9 @@ static void batadv_tp_vars_release(struct kref *ref)
*/
static void batadv_tp_vars_put(struct batadv_tp_vars *tp_vars)
{
if (!tp_vars)
return;
kref_put(&tp_vars->refcount, batadv_tp_vars_release);
}

View File

@ -248,6 +248,9 @@ static void batadv_tt_local_entry_release(struct kref *ref)
static void
batadv_tt_local_entry_put(struct batadv_tt_local_entry *tt_local_entry)
{
if (!tt_local_entry)
return;
kref_put(&tt_local_entry->common.refcount,
batadv_tt_local_entry_release);
}
@ -271,7 +274,7 @@ static void batadv_tt_global_entry_free_rcu(struct rcu_head *rcu)
* queue for free after rcu grace period
* @ref: kref pointer of the nc_node
*/
static void batadv_tt_global_entry_release(struct kref *ref)
void batadv_tt_global_entry_release(struct kref *ref)
{
struct batadv_tt_global_entry *tt_global_entry;
@ -283,17 +286,6 @@ static void batadv_tt_global_entry_release(struct kref *ref)
call_rcu(&tt_global_entry->common.rcu, batadv_tt_global_entry_free_rcu);
}
/**
* batadv_tt_global_entry_put() - decrement the tt_global_entry refcounter and
* possibly release it
* @tt_global_entry: tt_global_entry to be free'd
*/
void batadv_tt_global_entry_put(struct batadv_tt_global_entry *tt_global_entry)
{
kref_put(&tt_global_entry->common.refcount,
batadv_tt_global_entry_release);
}
/**
* batadv_tt_global_hash_count() - count the number of orig entries
* @bat_priv: the bat priv with all the soft interface information
@ -453,6 +445,9 @@ static void batadv_tt_orig_list_entry_release(struct kref *ref)
static void
batadv_tt_orig_list_entry_put(struct batadv_tt_orig_list_entry *orig_entry)
{
if (!orig_entry)
return;
kref_put(&orig_entry->refcount, batadv_tt_orig_list_entry_release);
}
@ -2818,6 +2813,9 @@ static void batadv_tt_req_node_release(struct kref *ref)
*/
static void batadv_tt_req_node_put(struct batadv_tt_req_node *tt_req_node)
{
if (!tt_req_node)
return;
kref_put(&tt_req_node->refcount, batadv_tt_req_node_release);
}

View File

@ -9,6 +9,7 @@
#include "main.h"
#include <linux/kref.h>
#include <linux/netdevice.h>
#include <linux/netlink.h>
#include <linux/seq_file.h>
@ -31,7 +32,7 @@ void batadv_tt_global_del_orig(struct batadv_priv *bat_priv,
struct batadv_tt_global_entry *
batadv_tt_global_hash_find(struct batadv_priv *bat_priv, const u8 *addr,
unsigned short vid);
void batadv_tt_global_entry_put(struct batadv_tt_global_entry *tt_global_entry);
void batadv_tt_global_entry_release(struct kref *ref);
int batadv_tt_global_hash_count(struct batadv_priv *bat_priv,
const u8 *addr, unsigned short vid);
struct batadv_orig_node *batadv_transtable_search(struct batadv_priv *bat_priv,
@ -58,4 +59,19 @@ bool batadv_tt_global_is_isolated(struct batadv_priv *bat_priv,
int batadv_tt_cache_init(void);
void batadv_tt_cache_destroy(void);
/**
* batadv_tt_global_entry_put() - decrement the tt_global_entry refcounter and
* possibly release it
* @tt_global_entry: tt_global_entry to be free'd
*/
static inline void
batadv_tt_global_entry_put(struct batadv_tt_global_entry *tt_global_entry)
{
if (!tt_global_entry)
return;
kref_put(&tt_global_entry->common.refcount,
batadv_tt_global_entry_release);
}
#endif /* _NET_BATMAN_ADV_TRANSLATION_TABLE_H_ */

View File

@ -50,6 +50,9 @@ static void batadv_tvlv_handler_release(struct kref *ref)
*/
static void batadv_tvlv_handler_put(struct batadv_tvlv_handler *tvlv_handler)
{
if (!tvlv_handler)
return;
kref_put(&tvlv_handler->refcount, batadv_tvlv_handler_release);
}
@ -106,6 +109,9 @@ static void batadv_tvlv_container_release(struct kref *ref)
*/
static void batadv_tvlv_container_put(struct batadv_tvlv_container *tvlv)
{
if (!tvlv)
return;
kref_put(&tvlv->refcount, batadv_tvlv_container_release);
}