Commit c4bf05d3 authored by Simon Wunderlich's avatar Simon Wunderlich Committed by Greg Kroah-Hartman

Staging: batman-adv: check all kmalloc()s

there are some kmallocs left which are not checked whether they succeeds or
not, which might lead to corrupted data structures if the system memory is
full. This patch should clean up the remaining unchecked kmalloc()s.
Signed-off-by: default avatarSimon Wunderlich <siwu@hrz.tu-chemnitz.de>
Signed-off-by: default avatarAndrew Lunn <andrew@lunn.ch>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent e9b76450
...@@ -77,6 +77,9 @@ create_neighbor(struct orig_node *orig_node, struct orig_node *orig_neigh_node, ...@@ -77,6 +77,9 @@ create_neighbor(struct orig_node *orig_node, struct orig_node *orig_neigh_node,
bat_dbg(DBG_BATMAN, "Creating new last-hop neighbor of originator\n"); bat_dbg(DBG_BATMAN, "Creating new last-hop neighbor of originator\n");
neigh_node = kmalloc(sizeof(struct neigh_node), GFP_ATOMIC); neigh_node = kmalloc(sizeof(struct neigh_node), GFP_ATOMIC);
if (!neigh_node)
return NULL;
memset(neigh_node, 0, sizeof(struct neigh_node)); memset(neigh_node, 0, sizeof(struct neigh_node));
INIT_LIST_HEAD(&neigh_node->list); INIT_LIST_HEAD(&neigh_node->list);
...@@ -127,6 +130,9 @@ struct orig_node *get_orig_node(uint8_t *addr) ...@@ -127,6 +130,9 @@ struct orig_node *get_orig_node(uint8_t *addr)
bat_dbg(DBG_BATMAN, "Creating new originator: %s \n", orig_str); bat_dbg(DBG_BATMAN, "Creating new originator: %s \n", orig_str);
orig_node = kmalloc(sizeof(struct orig_node), GFP_ATOMIC); orig_node = kmalloc(sizeof(struct orig_node), GFP_ATOMIC);
if (!orig_node)
return NULL;
memset(orig_node, 0, sizeof(struct orig_node)); memset(orig_node, 0, sizeof(struct orig_node));
INIT_LIST_HEAD(&orig_node->neigh_list); INIT_LIST_HEAD(&orig_node->neigh_list);
...@@ -138,13 +144,20 @@ struct orig_node *get_orig_node(uint8_t *addr) ...@@ -138,13 +144,20 @@ struct orig_node *get_orig_node(uint8_t *addr)
size = num_ifs * sizeof(TYPE_OF_WORD) * NUM_WORDS; size = num_ifs * sizeof(TYPE_OF_WORD) * NUM_WORDS;
orig_node->bcast_own = kmalloc(size, GFP_ATOMIC); orig_node->bcast_own = kmalloc(size, GFP_ATOMIC);
if (!orig_node->bcast_own)
goto free_orig_node;
memset(orig_node->bcast_own, 0, size); memset(orig_node->bcast_own, 0, size);
size = num_ifs * sizeof(uint8_t); size = num_ifs * sizeof(uint8_t);
orig_node->bcast_own_sum = kmalloc(size, GFP_ATOMIC); orig_node->bcast_own_sum = kmalloc(size, GFP_ATOMIC);
if (!orig_node->bcast_own_sum)
goto free_bcast_own;
memset(orig_node->bcast_own_sum, 0, size); memset(orig_node->bcast_own_sum, 0, size);
hash_add(orig_hash, orig_node); if (hash_add(orig_hash, orig_node) < 0)
goto free_bcast_own_sum;
if (orig_hash->elements * 4 > orig_hash->size) { if (orig_hash->elements * 4 > orig_hash->size) {
swaphash = hash_resize(orig_hash, orig_hash->size * 2); swaphash = hash_resize(orig_hash, orig_hash->size * 2);
...@@ -157,6 +170,13 @@ struct orig_node *get_orig_node(uint8_t *addr) ...@@ -157,6 +170,13 @@ struct orig_node *get_orig_node(uint8_t *addr)
} }
return orig_node; return orig_node;
free_bcast_own_sum:
kfree(orig_node->bcast_own_sum);
free_bcast_own:
kfree(orig_node->bcast_own);
free_orig_node:
kfree(orig_node);
return NULL;
} }
static bool purge_orig_neighbors(struct orig_node *orig_node, static bool purge_orig_neighbors(struct orig_node *orig_node,
......
...@@ -154,11 +154,14 @@ static int isBidirectionalNeigh(struct orig_node *orig_node, ...@@ -154,11 +154,14 @@ static int isBidirectionalNeigh(struct orig_node *orig_node,
neigh_node = tmp_neigh_node; neigh_node = tmp_neigh_node;
} }
if (neigh_node == NULL) if (!neigh_node)
neigh_node = create_neighbor(orig_node, neigh_node = create_neighbor(orig_node,
orig_neigh_node, orig_neigh_node,
orig_neigh_node->orig, orig_neigh_node->orig,
if_incoming); if_incoming);
/* create_neighbor failed, return 0 */
if (!neigh_node)
return 0;
neigh_node->last_valid = jiffies; neigh_node->last_valid = jiffies;
} else { } else {
...@@ -172,11 +175,14 @@ static int isBidirectionalNeigh(struct orig_node *orig_node, ...@@ -172,11 +175,14 @@ static int isBidirectionalNeigh(struct orig_node *orig_node,
neigh_node = tmp_neigh_node; neigh_node = tmp_neigh_node;
} }
if (neigh_node == NULL) if (!neigh_node)
neigh_node = create_neighbor(orig_neigh_node, neigh_node = create_neighbor(orig_neigh_node,
orig_neigh_node, orig_neigh_node,
orig_neigh_node->orig, orig_neigh_node->orig,
if_incoming); if_incoming);
/* create_neighbor failed, return 0 */
if (!neigh_node)
return 0;
} }
orig_node->last_valid = jiffies; orig_node->last_valid = jiffies;
...@@ -260,11 +266,19 @@ static void update_orig(struct orig_node *orig_node, struct ethhdr *ethhdr, ...@@ -260,11 +266,19 @@ static void update_orig(struct orig_node *orig_node, struct ethhdr *ethhdr,
ring_buffer_avg(tmp_neigh_node->tq_recv); ring_buffer_avg(tmp_neigh_node->tq_recv);
} }
if (neigh_node == NULL) if (!neigh_node) {
struct orig_node *orig_tmp;
orig_tmp = get_orig_node(ethhdr->h_source);
if (!orig_tmp)
return;
neigh_node = create_neighbor(orig_node, neigh_node = create_neighbor(orig_node,
get_orig_node(ethhdr->h_source), orig_tmp,
ethhdr->h_source, if_incoming); ethhdr->h_source, if_incoming);
else if (!neigh_node)
return;
} else
bat_dbg(DBG_BATMAN, bat_dbg(DBG_BATMAN,
"Updating existing last-hop neighbor of originator\n"); "Updating existing last-hop neighbor of originator\n");
...@@ -444,6 +458,9 @@ void receive_bat_packet(struct ethhdr *ethhdr, ...@@ -444,6 +458,9 @@ void receive_bat_packet(struct ethhdr *ethhdr,
orig_neigh_node = get_orig_node(ethhdr->h_source); orig_neigh_node = get_orig_node(ethhdr->h_source);
if (!orig_neigh_node)
return;
/* neighbor has to indicate direct link and it has to /* neighbor has to indicate direct link and it has to
* come via the corresponding interface */ * come via the corresponding interface */
/* if received seqno equals last send seqno save new /* if received seqno equals last send seqno save new
......
...@@ -317,14 +317,16 @@ void hna_global_add_orig(struct orig_node *orig_node, ...@@ -317,14 +317,16 @@ void hna_global_add_orig(struct orig_node *orig_node,
hna_buff_count++; hna_buff_count++;
} }
orig_node->hna_buff_len = hna_buff_len; /* initialize, and overwrite if malloc succeeds */
orig_node->hna_buff = NULL;
if (orig_node->hna_buff_len > 0) { orig_node->hna_buff_len = 0;
orig_node->hna_buff = kmalloc(orig_node->hna_buff_len,
GFP_ATOMIC); if (hna_buff_len > 0) {
memcpy(orig_node->hna_buff, hna_buff, orig_node->hna_buff_len); orig_node->hna_buff = kmalloc(hna_buff_len, GFP_ATOMIC);
} else { if (orig_node->hna_buff) {
orig_node->hna_buff = NULL; memcpy(orig_node->hna_buff, hna_buff, hna_buff_len);
orig_node->hna_buff_len = hna_buff_len;
}
} }
spin_lock_irqsave(&hna_global_hash_lock, flags); spin_lock_irqsave(&hna_global_hash_lock, flags);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment