Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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

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>

authored by

Sven Eckelmann and committed by
Simon Wunderlich
6340dcbd 70eeb75d

+181 -113
+6
net/batman-adv/bridge_loop_avoidance.c
··· 162 162 */ 163 163 static void batadv_backbone_gw_put(struct batadv_bla_backbone_gw *backbone_gw) 164 164 { 165 + if (!backbone_gw) 166 + return; 167 + 165 168 kref_put(&backbone_gw->refcount, batadv_backbone_gw_release); 166 169 } 167 170 ··· 200 197 */ 201 198 static void batadv_claim_put(struct batadv_bla_claim *claim) 202 199 { 200 + if (!claim) 201 + return; 202 + 203 203 kref_put(&claim->refcount, batadv_claim_release); 204 204 } 205 205
+3
net/batman-adv/distributed-arp-table.c
··· 127 127 */ 128 128 static void batadv_dat_entry_put(struct batadv_dat_entry *dat_entry) 129 129 { 130 + if (!dat_entry) 131 + return; 132 + 130 133 kref_put(&dat_entry->refcount, batadv_dat_entry_release); 131 134 } 132 135
+1 -11
net/batman-adv/gateway_client.c
··· 59 59 * after rcu grace period 60 60 * @ref: kref pointer of the gw_node 61 61 */ 62 - static void batadv_gw_node_release(struct kref *ref) 62 + void batadv_gw_node_release(struct kref *ref) 63 63 { 64 64 struct batadv_gw_node *gw_node; 65 65 ··· 67 67 68 68 batadv_orig_node_put(gw_node->orig_node); 69 69 kfree_rcu(gw_node, rcu); 70 - } 71 - 72 - /** 73 - * batadv_gw_node_put() - decrement the gw_node refcounter and possibly release 74 - * it 75 - * @gw_node: gateway node to free 76 - */ 77 - void batadv_gw_node_put(struct batadv_gw_node *gw_node) 78 - { 79 - kref_put(&gw_node->refcount, batadv_gw_node_release); 80 70 } 81 71 82 72 /**
+15 -1
net/batman-adv/gateway_client.h
··· 9 9 10 10 #include "main.h" 11 11 12 + #include <linux/kref.h> 12 13 #include <linux/netlink.h> 13 14 #include <linux/skbuff.h> 14 15 #include <linux/types.h> ··· 28 27 void batadv_gw_node_delete(struct batadv_priv *bat_priv, 29 28 struct batadv_orig_node *orig_node); 30 29 void batadv_gw_node_free(struct batadv_priv *bat_priv); 31 - void batadv_gw_node_put(struct batadv_gw_node *gw_node); 30 + void batadv_gw_node_release(struct kref *ref); 32 31 struct batadv_gw_node * 33 32 batadv_gw_get_selected_gw_node(struct batadv_priv *bat_priv); 34 33 int batadv_gw_dump(struct sk_buff *msg, struct netlink_callback *cb); ··· 38 37 u8 *chaddr); 39 38 struct batadv_gw_node *batadv_gw_node_get(struct batadv_priv *bat_priv, 40 39 struct batadv_orig_node *orig_node); 40 + 41 + /** 42 + * batadv_gw_node_put() - decrement the gw_node refcounter and possibly release 43 + * it 44 + * @gw_node: gateway node to free 45 + */ 46 + static inline void batadv_gw_node_put(struct batadv_gw_node *gw_node) 47 + { 48 + if (!gw_node) 49 + return; 50 + 51 + kref_put(&gw_node->refcount, batadv_gw_node_release); 52 + } 41 53 42 54 #endif /* _NET_BATMAN_ADV_GATEWAY_CLIENT_H_ */
+3
net/batman-adv/hard-interface.h
··· 89 89 */ 90 90 static inline void batadv_hardif_put(struct batadv_hard_iface *hard_iface) 91 91 { 92 + if (!hard_iface) 93 + return; 94 + 92 95 kref_put(&hard_iface->refcount, batadv_hardif_release); 93 96 } 94 97
+6
net/batman-adv/network-coding.c
··· 217 217 */ 218 218 static void batadv_nc_node_put(struct batadv_nc_node *nc_node) 219 219 { 220 + if (!nc_node) 221 + return; 222 + 220 223 kref_put(&nc_node->refcount, batadv_nc_node_release); 221 224 } 222 225 ··· 244 241 */ 245 242 static void batadv_nc_path_put(struct batadv_nc_path *nc_path) 246 243 { 244 + if (!nc_path) 245 + return; 246 + 247 247 kref_put(&nc_path->refcount, batadv_nc_path_release); 248 248 } 249 249
+6 -66
net/batman-adv/originator.c
··· 177 177 * and queue for free after rcu grace period 178 178 * @ref: kref pointer of the originator-vlan object 179 179 */ 180 - static void batadv_orig_node_vlan_release(struct kref *ref) 180 + void batadv_orig_node_vlan_release(struct kref *ref) 181 181 { 182 182 struct batadv_orig_node_vlan *orig_vlan; 183 183 184 184 orig_vlan = container_of(ref, struct batadv_orig_node_vlan, refcount); 185 185 186 186 kfree_rcu(orig_vlan, rcu); 187 - } 188 - 189 - /** 190 - * batadv_orig_node_vlan_put() - decrement the refcounter and possibly release 191 - * the originator-vlan object 192 - * @orig_vlan: the originator-vlan object to release 193 - */ 194 - void batadv_orig_node_vlan_put(struct batadv_orig_node_vlan *orig_vlan) 195 - { 196 - kref_put(&orig_vlan->refcount, batadv_orig_node_vlan_release); 197 187 } 198 188 199 189 /** ··· 221 231 * free after rcu grace period 222 232 * @ref: kref pointer of the neigh_ifinfo 223 233 */ 224 - static void batadv_neigh_ifinfo_release(struct kref *ref) 234 + void batadv_neigh_ifinfo_release(struct kref *ref) 225 235 { 226 236 struct batadv_neigh_ifinfo *neigh_ifinfo; 227 237 ··· 234 244 } 235 245 236 246 /** 237 - * batadv_neigh_ifinfo_put() - decrement the refcounter and possibly release 238 - * the neigh_ifinfo 239 - * @neigh_ifinfo: the neigh_ifinfo object to release 240 - */ 241 - void batadv_neigh_ifinfo_put(struct batadv_neigh_ifinfo *neigh_ifinfo) 242 - { 243 - kref_put(&neigh_ifinfo->refcount, batadv_neigh_ifinfo_release); 244 - } 245 - 246 - /** 247 247 * batadv_hardif_neigh_release() - release hardif neigh node from lists and 248 248 * queue for free after rcu grace period 249 249 * @ref: kref pointer of the neigh_node 250 250 */ 251 - static void batadv_hardif_neigh_release(struct kref *ref) 251 + void batadv_hardif_neigh_release(struct kref *ref) 252 252 { 253 253 struct batadv_hardif_neigh_node *hardif_neigh; 254 254 ··· 254 274 } 255 275 256 276 /** 257 - * batadv_hardif_neigh_put() - decrement the hardif neighbors refcounter 258 - * and possibly release it 259 - * @hardif_neigh: hardif neigh neighbor to free 260 - */ 261 - void batadv_hardif_neigh_put(struct batadv_hardif_neigh_node *hardif_neigh) 262 - { 263 - kref_put(&hardif_neigh->refcount, batadv_hardif_neigh_release); 264 - } 265 - 266 - /** 267 277 * batadv_neigh_node_release() - release neigh_node from lists and queue for 268 278 * free after rcu grace period 269 279 * @ref: kref pointer of the neigh_node 270 280 */ 271 - static void batadv_neigh_node_release(struct kref *ref) 281 + void batadv_neigh_node_release(struct kref *ref) 272 282 { 273 283 struct hlist_node *node_tmp; 274 284 struct batadv_neigh_node *neigh_node; ··· 276 306 batadv_hardif_put(neigh_node->if_incoming); 277 307 278 308 kfree_rcu(neigh_node, rcu); 279 - } 280 - 281 - /** 282 - * batadv_neigh_node_put() - decrement the neighbors refcounter and possibly 283 - * release it 284 - * @neigh_node: neigh neighbor to free 285 - */ 286 - void batadv_neigh_node_put(struct batadv_neigh_node *neigh_node) 287 - { 288 - kref_put(&neigh_node->refcount, batadv_neigh_node_release); 289 309 } 290 310 291 311 /** ··· 772 812 * free after rcu grace period 773 813 * @ref: kref pointer of the orig_ifinfo 774 814 */ 775 - static void batadv_orig_ifinfo_release(struct kref *ref) 815 + void batadv_orig_ifinfo_release(struct kref *ref) 776 816 { 777 817 struct batadv_orig_ifinfo *orig_ifinfo; 778 818 struct batadv_neigh_node *router; ··· 788 828 batadv_neigh_node_put(router); 789 829 790 830 kfree_rcu(orig_ifinfo, rcu); 791 - } 792 - 793 - /** 794 - * batadv_orig_ifinfo_put() - decrement the refcounter and possibly release 795 - * the orig_ifinfo 796 - * @orig_ifinfo: the orig_ifinfo object to release 797 - */ 798 - void batadv_orig_ifinfo_put(struct batadv_orig_ifinfo *orig_ifinfo) 799 - { 800 - kref_put(&orig_ifinfo->refcount, batadv_orig_ifinfo_release); 801 831 } 802 832 803 833 /** ··· 813 863 * free after rcu grace period 814 864 * @ref: kref pointer of the orig_node 815 865 */ 816 - static void batadv_orig_node_release(struct kref *ref) 866 + void batadv_orig_node_release(struct kref *ref) 817 867 { 818 868 struct hlist_node *node_tmp; 819 869 struct batadv_neigh_node *neigh_node; ··· 857 907 batadv_nc_purge_orig(orig_node->bat_priv, orig_node, NULL); 858 908 859 909 call_rcu(&orig_node->rcu, batadv_orig_node_free_rcu); 860 - } 861 - 862 - /** 863 - * batadv_orig_node_put() - decrement the orig node refcounter and possibly 864 - * release it 865 - * @orig_node: the orig node to free 866 - */ 867 - void batadv_orig_node_put(struct batadv_orig_node *orig_node) 868 - { 869 - kref_put(&orig_node->refcount, batadv_orig_node_release); 870 910 } 871 911 872 912 /**
+89 -7
net/batman-adv/originator.h
··· 12 12 #include <linux/compiler.h> 13 13 #include <linux/if_ether.h> 14 14 #include <linux/jhash.h> 15 + #include <linux/kref.h> 15 16 #include <linux/netlink.h> 16 17 #include <linux/skbuff.h> 17 18 #include <linux/types.h> ··· 21 20 int batadv_originator_init(struct batadv_priv *bat_priv); 22 21 void batadv_originator_free(struct batadv_priv *bat_priv); 23 22 void batadv_purge_orig_ref(struct batadv_priv *bat_priv); 24 - void batadv_orig_node_put(struct batadv_orig_node *orig_node); 23 + void batadv_orig_node_release(struct kref *ref); 25 24 struct batadv_orig_node *batadv_orig_node_new(struct batadv_priv *bat_priv, 26 25 const u8 *addr); 27 26 struct batadv_hardif_neigh_node * 28 27 batadv_hardif_neigh_get(const struct batadv_hard_iface *hard_iface, 29 28 const u8 *neigh_addr); 30 - void 31 - batadv_hardif_neigh_put(struct batadv_hardif_neigh_node *hardif_neigh); 29 + void batadv_hardif_neigh_release(struct kref *ref); 32 30 struct batadv_neigh_node * 33 31 batadv_neigh_node_get_or_create(struct batadv_orig_node *orig_node, 34 32 struct batadv_hard_iface *hard_iface, 35 33 const u8 *neigh_addr); 36 - void batadv_neigh_node_put(struct batadv_neigh_node *neigh_node); 34 + void batadv_neigh_node_release(struct kref *ref); 37 35 struct batadv_neigh_node * 38 36 batadv_orig_router_get(struct batadv_orig_node *orig_node, 39 37 const struct batadv_hard_iface *if_outgoing); ··· 42 42 struct batadv_neigh_ifinfo * 43 43 batadv_neigh_ifinfo_get(struct batadv_neigh_node *neigh, 44 44 struct batadv_hard_iface *if_outgoing); 45 - void batadv_neigh_ifinfo_put(struct batadv_neigh_ifinfo *neigh_ifinfo); 45 + void batadv_neigh_ifinfo_release(struct kref *ref); 46 46 47 47 int batadv_hardif_neigh_dump(struct sk_buff *msg, struct netlink_callback *cb); 48 48 ··· 52 52 struct batadv_orig_ifinfo * 53 53 batadv_orig_ifinfo_new(struct batadv_orig_node *orig_node, 54 54 struct batadv_hard_iface *if_outgoing); 55 - void batadv_orig_ifinfo_put(struct batadv_orig_ifinfo *orig_ifinfo); 55 + void batadv_orig_ifinfo_release(struct kref *ref); 56 56 57 57 int batadv_orig_dump(struct sk_buff *msg, struct netlink_callback *cb); 58 58 struct batadv_orig_node_vlan * ··· 61 61 struct batadv_orig_node_vlan * 62 62 batadv_orig_node_vlan_get(struct batadv_orig_node *orig_node, 63 63 unsigned short vid); 64 - void batadv_orig_node_vlan_put(struct batadv_orig_node_vlan *orig_vlan); 64 + void batadv_orig_node_vlan_release(struct kref *ref); 65 65 66 66 /** 67 67 * batadv_choose_orig() - Return the index of the orig entry in the hash table ··· 81 81 82 82 struct batadv_orig_node * 83 83 batadv_orig_hash_find(struct batadv_priv *bat_priv, const void *data); 84 + 85 + /** 86 + * batadv_orig_node_vlan_put() - decrement the refcounter and possibly release 87 + * the originator-vlan object 88 + * @orig_vlan: the originator-vlan object to release 89 + */ 90 + static inline void 91 + batadv_orig_node_vlan_put(struct batadv_orig_node_vlan *orig_vlan) 92 + { 93 + if (!orig_vlan) 94 + return; 95 + 96 + kref_put(&orig_vlan->refcount, batadv_orig_node_vlan_release); 97 + } 98 + 99 + /** 100 + * batadv_neigh_ifinfo_put() - decrement the refcounter and possibly release 101 + * the neigh_ifinfo 102 + * @neigh_ifinfo: the neigh_ifinfo object to release 103 + */ 104 + static inline void 105 + batadv_neigh_ifinfo_put(struct batadv_neigh_ifinfo *neigh_ifinfo) 106 + { 107 + if (!neigh_ifinfo) 108 + return; 109 + 110 + kref_put(&neigh_ifinfo->refcount, batadv_neigh_ifinfo_release); 111 + } 112 + 113 + /** 114 + * batadv_hardif_neigh_put() - decrement the hardif neighbors refcounter 115 + * and possibly release it 116 + * @hardif_neigh: hardif neigh neighbor to free 117 + */ 118 + static inline void 119 + batadv_hardif_neigh_put(struct batadv_hardif_neigh_node *hardif_neigh) 120 + { 121 + if (!hardif_neigh) 122 + return; 123 + 124 + kref_put(&hardif_neigh->refcount, batadv_hardif_neigh_release); 125 + } 126 + 127 + /** 128 + * batadv_neigh_node_put() - decrement the neighbors refcounter and possibly 129 + * release it 130 + * @neigh_node: neigh neighbor to free 131 + */ 132 + static inline void batadv_neigh_node_put(struct batadv_neigh_node *neigh_node) 133 + { 134 + if (!neigh_node) 135 + return; 136 + 137 + kref_put(&neigh_node->refcount, batadv_neigh_node_release); 138 + } 139 + 140 + /** 141 + * batadv_orig_ifinfo_put() - decrement the refcounter and possibly release 142 + * the orig_ifinfo 143 + * @orig_ifinfo: the orig_ifinfo object to release 144 + */ 145 + static inline void 146 + batadv_orig_ifinfo_put(struct batadv_orig_ifinfo *orig_ifinfo) 147 + { 148 + if (!orig_ifinfo) 149 + return; 150 + 151 + kref_put(&orig_ifinfo->refcount, batadv_orig_ifinfo_release); 152 + } 153 + 154 + /** 155 + * batadv_orig_node_put() - decrement the orig node refcounter and possibly 156 + * release it 157 + * @orig_node: the orig node to free 158 + */ 159 + static inline void batadv_orig_node_put(struct batadv_orig_node *orig_node) 160 + { 161 + if (!orig_node) 162 + return; 163 + 164 + kref_put(&orig_node->refcount, batadv_orig_node_release); 165 + } 84 166 85 167 #endif /* _NET_BATMAN_ADV_ORIGINATOR_H_ */
+1 -14
net/batman-adv/soft-interface.c
··· 501 501 * after rcu grace period 502 502 * @ref: kref pointer of the vlan object 503 503 */ 504 - static void batadv_softif_vlan_release(struct kref *ref) 504 + void batadv_softif_vlan_release(struct kref *ref) 505 505 { 506 506 struct batadv_softif_vlan *vlan; 507 507 ··· 512 512 spin_unlock_bh(&vlan->bat_priv->softif_vlan_list_lock); 513 513 514 514 kfree_rcu(vlan, rcu); 515 - } 516 - 517 - /** 518 - * batadv_softif_vlan_put() - decrease the vlan object refcounter and 519 - * possibly release it 520 - * @vlan: the vlan object to release 521 - */ 522 - void batadv_softif_vlan_put(struct batadv_softif_vlan *vlan) 523 - { 524 - if (!vlan) 525 - return; 526 - 527 - kref_put(&vlan->refcount, batadv_softif_vlan_release); 528 515 } 529 516 530 517 /**
+15 -1
net/batman-adv/soft-interface.h
··· 9 9 10 10 #include "main.h" 11 11 12 + #include <linux/kref.h> 12 13 #include <linux/netdevice.h> 13 14 #include <linux/skbuff.h> 14 15 #include <linux/types.h> ··· 22 21 bool batadv_softif_is_valid(const struct net_device *net_dev); 23 22 extern struct rtnl_link_ops batadv_link_ops; 24 23 int batadv_softif_create_vlan(struct batadv_priv *bat_priv, unsigned short vid); 25 - void batadv_softif_vlan_put(struct batadv_softif_vlan *softif_vlan); 24 + void batadv_softif_vlan_release(struct kref *ref); 26 25 struct batadv_softif_vlan *batadv_softif_vlan_get(struct batadv_priv *bat_priv, 27 26 unsigned short vid); 27 + 28 + /** 29 + * batadv_softif_vlan_put() - decrease the vlan object refcounter and 30 + * possibly release it 31 + * @vlan: the vlan object to release 32 + */ 33 + static inline void batadv_softif_vlan_put(struct batadv_softif_vlan *vlan) 34 + { 35 + if (!vlan) 36 + return; 37 + 38 + kref_put(&vlan->refcount, batadv_softif_vlan_release); 39 + } 28 40 29 41 #endif /* _NET_BATMAN_ADV_SOFT_INTERFACE_H_ */
+3
net/batman-adv/tp_meter.c
··· 358 358 */ 359 359 static void batadv_tp_vars_put(struct batadv_tp_vars *tp_vars) 360 360 { 361 + if (!tp_vars) 362 + return; 363 + 361 364 kref_put(&tp_vars->refcount, batadv_tp_vars_release); 362 365 } 363 366
+10 -12
net/batman-adv/translation-table.c
··· 247 247 static void 248 248 batadv_tt_local_entry_put(struct batadv_tt_local_entry *tt_local_entry) 249 249 { 250 + if (!tt_local_entry) 251 + return; 252 + 250 253 kref_put(&tt_local_entry->common.refcount, 251 254 batadv_tt_local_entry_release); 252 255 } ··· 273 270 * queue for free after rcu grace period 274 271 * @ref: kref pointer of the nc_node 275 272 */ 276 - static void batadv_tt_global_entry_release(struct kref *ref) 273 + void batadv_tt_global_entry_release(struct kref *ref) 277 274 { 278 275 struct batadv_tt_global_entry *tt_global_entry; 279 276 ··· 283 280 batadv_tt_global_del_orig_list(tt_global_entry); 284 281 285 282 call_rcu(&tt_global_entry->common.rcu, batadv_tt_global_entry_free_rcu); 286 - } 287 - 288 - /** 289 - * batadv_tt_global_entry_put() - decrement the tt_global_entry refcounter and 290 - * possibly release it 291 - * @tt_global_entry: tt_global_entry to be free'd 292 - */ 293 - void batadv_tt_global_entry_put(struct batadv_tt_global_entry *tt_global_entry) 294 - { 295 - kref_put(&tt_global_entry->common.refcount, 296 - batadv_tt_global_entry_release); 297 283 } 298 284 299 285 /** ··· 444 452 static void 445 453 batadv_tt_orig_list_entry_put(struct batadv_tt_orig_list_entry *orig_entry) 446 454 { 455 + if (!orig_entry) 456 + return; 457 + 447 458 kref_put(&orig_entry->refcount, batadv_tt_orig_list_entry_release); 448 459 } 449 460 ··· 2598 2603 */ 2599 2604 static void batadv_tt_req_node_put(struct batadv_tt_req_node *tt_req_node) 2600 2605 { 2606 + if (!tt_req_node) 2607 + return; 2608 + 2601 2609 kref_put(&tt_req_node->refcount, batadv_tt_req_node_release); 2602 2610 } 2603 2611
+17 -1
net/batman-adv/translation-table.h
··· 9 9 10 10 #include "main.h" 11 11 12 + #include <linux/kref.h> 12 13 #include <linux/netdevice.h> 13 14 #include <linux/netlink.h> 14 15 #include <linux/skbuff.h> ··· 29 28 struct batadv_tt_global_entry * 30 29 batadv_tt_global_hash_find(struct batadv_priv *bat_priv, const u8 *addr, 31 30 unsigned short vid); 32 - void batadv_tt_global_entry_put(struct batadv_tt_global_entry *tt_global_entry); 31 + void batadv_tt_global_entry_release(struct kref *ref); 33 32 int batadv_tt_global_hash_count(struct batadv_priv *bat_priv, 34 33 const u8 *addr, unsigned short vid); 35 34 struct batadv_orig_node *batadv_transtable_search(struct batadv_priv *bat_priv, ··· 55 54 56 55 int batadv_tt_cache_init(void); 57 56 void batadv_tt_cache_destroy(void); 57 + 58 + /** 59 + * batadv_tt_global_entry_put() - decrement the tt_global_entry refcounter and 60 + * possibly release it 61 + * @tt_global_entry: tt_global_entry to be free'd 62 + */ 63 + static inline void 64 + batadv_tt_global_entry_put(struct batadv_tt_global_entry *tt_global_entry) 65 + { 66 + if (!tt_global_entry) 67 + return; 68 + 69 + kref_put(&tt_global_entry->common.refcount, 70 + batadv_tt_global_entry_release); 71 + } 58 72 59 73 #endif /* _NET_BATMAN_ADV_TRANSLATION_TABLE_H_ */
+6
net/batman-adv/tvlv.c
··· 50 50 */ 51 51 static void batadv_tvlv_handler_put(struct batadv_tvlv_handler *tvlv_handler) 52 52 { 53 + if (!tvlv_handler) 54 + return; 55 + 53 56 kref_put(&tvlv_handler->refcount, batadv_tvlv_handler_release); 54 57 } 55 58 ··· 109 106 */ 110 107 static void batadv_tvlv_container_put(struct batadv_tvlv_container *tvlv) 111 108 { 109 + if (!tvlv) 110 + return; 111 + 112 112 kref_put(&tvlv->refcount, batadv_tvlv_container_release); 113 113 } 114 114