diff --git a/fs/dlm/config.c b/fs/dlm/config.c index 6c5c3f049b33..6ebc0fa9a2fa 100644 --- a/fs/dlm/config.c +++ b/fs/dlm/config.c @@ -857,10 +857,17 @@ static ssize_t node_weight_show(struct config_item *item, char *buf) static ssize_t node_weight_store(struct config_item *item, const char *buf, size_t len) { - int rc = kstrtoint(buf, 0, &config_item_to_node(item)->weight); + struct dlm_node *node = config_item_to_node(item); + int weight; + int rc; + rc = kstrtoint(buf, 0, &weight); if (rc) return rc; + if (weight < 0) + return -EINVAL; + + node->weight = weight; return len; } diff --git a/fs/dlm/member.c b/fs/dlm/member.c index f84233a0fe4a..3a1c558ce9f6 100644 --- a/fs/dlm/member.c +++ b/fs/dlm/member.c @@ -402,7 +402,7 @@ void dlm_clear_members_gone(struct dlm_ls *ls) clear_memb_list(&ls->ls_nodes_gone, NULL); } -static void make_member_array(struct dlm_ls *ls) +static int make_member_array(struct dlm_ls *ls) { struct dlm_member *memb; int i, w, x = 0, total = 0, all_zero = 0, *array; @@ -411,8 +411,8 @@ static void make_member_array(struct dlm_ls *ls) ls->ls_node_array = NULL; list_for_each_entry(memb, &ls->ls_nodes, list) { - if (memb->weight) - total += memb->weight; + if (check_add_overflow(total, memb->weight, &total)) + return -EOVERFLOW; } /* all nodes revert to weight of 1 if all have weight 0 */ @@ -422,10 +422,9 @@ static void make_member_array(struct dlm_ls *ls) all_zero = 1; } - ls->ls_total_weight = total; array = kmalloc_objs(*array, total, GFP_NOFS); if (!array) - return; + return -ENOMEM; list_for_each_entry(memb, &ls->ls_nodes, list) { if (!all_zero && !memb->weight) @@ -442,7 +441,10 @@ static void make_member_array(struct dlm_ls *ls) array[x++] = memb->nodeid; } + ls->ls_total_weight = total; ls->ls_node_array = array; + + return 0; } /* send a status request to all members just to establish comms connections */ @@ -617,7 +619,10 @@ int dlm_recover_members(struct dlm_ls *ls, struct dlm_recover *rv, int *neg_out) } ls->ls_low_nodeid = low; - make_member_array(ls); + error = make_member_array(ls); + if (error) + return error; + *neg_out = neg; error = ping_members(ls, rv->seq);