This check complains when we reach kobject_put() or kobject_get() with kobject->state_initialized unset. This will eventually trigger a runtime WARN(). Signed-off-by: Harshit Mogalapalli <harshit.m.mogalapalli@xxxxxxxxxx> --- check_list.h | 1 + check_uninitialized_kobj.c | 51 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+) create mode 100644 check_uninitialized_kobj.c diff --git a/check_list.h b/check_list.h index a8ef0ddf..c726c521 100644 --- a/check_list.h +++ b/check_list.h @@ -247,6 +247,7 @@ CK(check_uaf_netdev_priv) //CK(check_host_input) CK(check_direct_return_instead_of_goto) CK(check_negative_error_code_type_promoted) +CK(check_uninitialized_kobj) /* wine specific stuff */ CK(check_wine_filehandles) diff --git a/check_uninitialized_kobj.c b/check_uninitialized_kobj.c new file mode 100644 index 00000000..aff36d69 --- /dev/null +++ b/check_uninitialized_kobj.c @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2023 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_slist.h" +#include "smatch_extra.h" + +static int my_id; + +static void match_kobject_function(struct expression *expr, const char *name, + struct symbol *sym, void *data) +{ + struct sm_state *sm, *tmp; + + sm = get_sm_state(SMATCH_EXTRA, name, sym); + if (!sm) + return; + + FOR_EACH_PTR(sm->possible, tmp) { + if (rl_max(estate_rl(tmp->state)).value == 0) + sm_warning("Calling kobject_put|get with state->initialized unset from line: %d", + tmp->line); + } END_FOR_EACH_PTR(tmp); +} + +void check_uninitialized_kobj(int id) +{ + my_id = id; + + if (option_project != PROJ_KERNEL) + return; + + add_function_param_key_hook("kobject_put", &match_kobject_function, 0, + "$->state_initialized", NULL); + add_function_param_key_hook("kobject_get", &match_kobject_function, 0, + "$->state_initialized", NULL); +} -- 2.39.3