On Thu, Jul 21, 2022 at 11:02:22AM +0200, Christophe JAILLET wrote: > find_first_zero_bit() returns MAX_COPPS_PER_PORT at max here. > So 'idx' should be tested with ">=" or the test can't match. > > Fixes: 7b20b2be51e1 ("ASoC: qdsp6: q6adm: Add q6adm driver") > Signed-off-by: Christophe JAILLET <christophe.jaillet@xxxxxxxxxx> > --- > sound/soc/qcom/qdsp6/q6adm.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/sound/soc/qcom/qdsp6/q6adm.c b/sound/soc/qcom/qdsp6/q6adm.c > index 01f383888b62..1530e98df165 100644 > --- a/sound/soc/qcom/qdsp6/q6adm.c > +++ b/sound/soc/qcom/qdsp6/q6adm.c > @@ -217,7 +217,7 @@ static struct q6copp *q6adm_alloc_copp(struct q6adm *adm, int port_idx) > idx = find_first_zero_bit(&adm->copp_bitmap[port_idx], > MAX_COPPS_PER_PORT); > > - if (idx > MAX_COPPS_PER_PORT) > + if (idx >= MAX_COPPS_PER_PORT) > return ERR_PTR(-EBUSY); Harshit asked me to write a Smatch check to prevent this bug in the future. I got his email before I got your patch. :P Attached. sound/soc/qcom/qdsp6/q6adm.c:220 q6adm_alloc_copp() warn: impossible find_next_bit condition I'll probably try to make this check more generic, but even the simple find_first_zero_bit() version will probably find bugs in the future and it was pretty simple to write. regards, dan carpenter
/* * Copyright (C) 2022 Oracle. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see http://www.gnu.org/copyleft/gpl.txt */ #include "smatch.h" #include "smatch_extra.h" static int my_id; STATE(next); static void match_next_bit(struct expression *expr, const char *name, struct symbol *sym, void *data) { set_state(my_id, name, sym, &next); } static void match_condition(struct expression *expr) { sval_t sval; if (expr->type != EXPR_COMPARE) return; if (expr->op != '>' && expr->op != SPECIAL_UNSIGNED_GT) return; if (!get_state_expr(my_id, expr->left)) return; if (!get_implied_value(expr, &sval) || sval.value != 0) return; sm_warning("impossible find_next_bit condition"); } void check_find_next_bit_off_by_one(int id) { my_id = id; if (option_project != PROJ_KERNEL) return; add_function_param_key_hook("find_first_bit", match_next_bit, -1, "$", NULL); add_function_param_key_hook("find_next_bit", match_next_bit, -1, "$", NULL); add_function_param_key_hook("find_next_zero_bit", match_next_bit, -1, "$", NULL); add_function_param_key_hook("find_first_zero_bit", match_next_bit, -1, "$", NULL); add_hook(&match_condition, CONDITION_HOOK); }