Motivation: https://lore.kernel.org/all/2026021413-CVE-2026-23149-8329@gregkh/
When user controlled data can pass start values < 0 to idr_alloc() kernel hits a WARN_ON in run time. This check is to catch that using static analysis. Signed-off-by: Harshit Mogalapalli <[email protected]> --- check_idr_alloc.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ check_list.h | 1 + 2 files changed, 47 insertions(+) create mode 100644 check_idr_alloc.c diff --git a/check_idr_alloc.c b/check_idr_alloc.c new file mode 100644 index 000000000000..ecd6a808e8ab --- /dev/null +++ b/check_idr_alloc.c @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2026 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 "parse.h" +#include "smatch.h" +#include "smatch_extra.h" + +static int my_id; + +static void match_idr_alloc(struct expression *expr) +{ + struct range_list *rl; + + if (!get_user_rl(expr, &rl)) + return; + + rl = cast_rl(&int_ctype, rl); + if (!sval_is_negative(rl_min(rl))) + return; + + sm_warning("idr_alloc start value from user can be < 0"); +} + +void check_idr_alloc(int id) +{ + if (option_project != PROJ_KERNEL) + return; + + my_id = id; + + add_param_key_expr_hook("idr_alloc", &match_idr_alloc, 2, "$", NULL); +} diff --git a/check_list.h b/check_list.h index 799aa76c98cf..77d596a7c350 100644 --- a/check_list.h +++ b/check_list.h @@ -223,6 +223,7 @@ CK(check_no_increment) /* kernel specific */ CK(check_kernel_printf) +CK(check_idr_alloc) CK(check_inconsistent_locking) CK(check_puts_argument) CK(check_err_ptr) -- 2.47.3
