All of lore.kernel.org
 help / color / mirror / Atom feed
From: Dan Carpenter <dan.carpenter@oracle.com>
To: Martin Kaiser <martin@kaiser.cx>
Cc: Larry Finger <Larry.Finger@lwfinger.net>,
	Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	Guenter Roeck <linux@roeck-us.net>,
	linux-staging@lists.linux.dev, kernel-janitors@vger.kernel.org,
	linux-kernel@vger.kernel.org
Subject: Re: [PATCH 1/6] staging: rtl8188eu: use safe iterator in rtw_free_network_queue
Date: Wed, 19 May 2021 17:16:35 +0300	[thread overview]
Message-ID: <20210519141635.GE32682@kadam> (raw)
In-Reply-To: <20210518082855.GB32682@kadam>

On Tue, May 18, 2021 at 11:28:55AM +0300, Dan Carpenter wrote:
> On Mon, May 17, 2021 at 06:57:33PM +0300, Dan Carpenter wrote:
> > Thanks for catching these...  I've created a new Smatch static checker
> > warning for this but it only works for list_for_each_entry().
> > Eventually someone would have run the coccinelle script to convert these
> > list_for_each loops into list_for_each_entry().  Otherwise you have to
> > parse container_of() and I've been meaning to do that for a while but I
> > haven't yet.
> > 
> > Anyway, I'm going to test it out overnight and see what it finds.  It's
> > sort a new use for the modification_hook(), before I had only ever used
> > it to silence warnings but this check uses it to trigger warnings.  So
> > perhaps it will generate a lot of false positives.  We'll see.
> > 
> > It sets the state of the iterator to &start at the start of the loop
> > and if it's not &start state at the end then it prints a warning.
> > 
> > regards,
> > dan carpenter
> > 
> 
> That Smatch check didn't work at all.  :P  Back to the drawing board.
> 
> regards,
> dan carpenter

It's sort of working now.  I just had to get some ordering issues fixed.
Also I had to fix a bug in smatch_conditions.c...

The check itself works very well, but the heuristic is a bit off.  It
turns out we some times mess with the list iterator very intentionally.
For example, one thing people do is add a new item directly after the
current item.

About 8 out of the 32 warnings listed below are real issues.  I'm going
to send some patches and bug fixes for them.  A couple are too ancient
for and complicated to bother with.

regards,
dan carpenter

kernel/exit.c:1397 do_wait_thread() warn: iterator 'p->sibling.next' changed during iteration
kernel/exit.c:1411 ptrace_do_wait() warn: iterator 'p->ptrace_entry.next' changed during iteration
kernel/events/core.c:3220 perf_event_modify_attr() warn: iterator 'child->child_list.next' changed during iteration
kernel/events/core.c:5451 perf_event_for_each_child() warn: iterator 'child->child_list.next' changed during iteration
kernel/locking/locktorture.c:420 torture_ww_mutex_lock() warn: iterator 'll->link.next' changed during iteration
kernel/locking/test-ww_mutex.c:464 stress_reorder_work() warn: iterator 'll->link.next' changed during iteration
arch/x86/kvm/../../../virt/kvm/kvm_main.c:4866 vm_stat_clear() warn: iterator 'kvm->vm_list.next' changed during iteration
fs/btrfs/extent-tree.c:4230 find_free_extent() warn: iterator 'block_group->list.next' changed during iteration
fs/nilfs2/segment.c:1565 nilfs_segctor_update_payload_blocknr() warn: iterator 'bh->b_assoc_buffers.next' changed during iteration
fs/super.c:657 __iterate_supers() warn: iterator 'sb->s_list.next' changed during iteration
drivers/spi/spi-fsi.c:469 fsi_spi_transfer_one_message() warn: iterator 'transfer->transfer_list.next' changed during iteration
drivers/spi/spi-tegra210-quad.c:990 tegra_qspi_transfer_one_message() warn: iterator 'transfer->transfer_list.next' changed during iteration
drivers/spi/spi.c:3299 spi_split_transfers_maxsize() warn: iterator 'xfer->transfer_list.next' changed during iteration
drivers/staging/emxx_udc/emxx_udc.c:2079 _nbu2ss_nuke() warn: iterator 'req->queue.next' changed during iteration
drivers/pnp/quirks.c:59 quirk_awe32_resources() warn: iterator 'option->list.next' changed during iteration
drivers/usb/dwc3/gadget.c:1298 dwc3_prepare_trbs() warn: iterator 'req->list.next' changed during iteration
drivers/gpu/drm/ttm/ttm_device.c:145 ttm_device_swapout() warn: iterator 'bo->lru.next' changed during iteration
drivers/gpu/drm/ttm/ttm_execbuf_util.c:91 ttm_eu_reserve_buffers() warn: iterator 'entry->head.next' changed during iteration
drivers/gpu/drm/i915/gt/intel_reset.c:901 __intel_gt_unset_wedged() warn: iterator 'tl->link.next' changed during iteration
drivers/target/target_core_user.c:1264 tcmu_tmr_notify() warn: iterator 'se_cmd->state_list.next' changed during iteration
drivers/w1/w1.c:1265 w1_fini() warn: iterator 'dev->w1_master_entry.next' changed during iteration
drivers/scsi/libsas/sas_port.c:47 sas_resume_port() warn: iterator 'dev->dev_list_node.next' changed during iteration
drivers/scsi/lpfc/lpfc_hbadisc.c:993 lpfc_linkup_cleanup_nodes() warn: iterator 'ndlp->nlp_listp.next' changed during iteration
drivers/scsi/lpfc/lpfc_hbadisc.c:4983 lpfc_unreg_hba_rpis() warn: iterator 'ndlp->nlp_listp.next' changed during iteration
drivers/block/drbd/drbd_debugfs.c:311 seq_print_resource_transfer_log_summary() warn: iterator 'req->tl_requests.next' changed during iteration
drivers/infiniband/hw/mlx5/main.c:3285 mlx5_ib_init_multiport_master() warn: iterator 'mpi->list.next' changed during iteration
drivers/infiniband/core/verbs.c:1112 __ib_shared_qp_event_handler() warn: iterator 'event->element.qp->open_list.next' changed during iteration
net/core/devlink.c:10589 devlink_pernet_pre_exit() warn: iterator 'devlink->list.next' changed during iteration
net/bluetooth/l2cap_core.c:1726 l2cap_conn_ready() warn: iterator 'chan->list.next' changed during iteration
net/bluetooth/l2cap_core.c:6265 l2cap_ecred_reconf_rsp() warn: iterator 'chan->list.next' changed during iteration
net/bluetooth/l2cap_core.c:8209 l2cap_security_cfm() warn: iterator 'chan->list.next' changed during iteration
security/landlock/fs.c:347 hook_sb_delete() warn: iterator 'inode->i_sb_list.next' changed during iteration

/*
 * Copyright (C) 2021 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(start);
STATE(watch);

static struct statement *iterator_stmt, *pre_stmt, *post_stmt;

static bool stmt_matches(struct expression *expr, struct statement *stmt)
{
	struct expression *tmp;
	struct statement *parent;

	if (!stmt)
		return false;
	while ((tmp = expr_get_parent_expr(expr)))
		expr = tmp;

	parent = expr_get_parent_stmt(expr);
	return parent == stmt;
}

static void set_watch(struct sm_state *sm, struct expression *mod_expr)
{
	if (mod_expr && stmt_matches(mod_expr, post_stmt))
		return;
	set_state(my_id, sm->name, sm->sym, &watch);
}

static bool is_list_macro(const char *macro)
{
	if (strcmp(macro, "list_for_each_entry") == 0)
		return true;
	return false;
}

static void match_iterator_statement(struct statement *stmt)
{
	const char *macro;

	if (stmt->type != STMT_ITERATOR ||
	    !stmt->iterator_pre_statement ||
	    !stmt->iterator_post_statement)
		return;

	macro = get_macro_name(stmt->pos);
	if (!macro)
		return;
	if (!is_list_macro(macro))
		return;

	iterator_stmt = stmt;
	pre_stmt = stmt->iterator_pre_statement;
	post_stmt = stmt->iterator_post_statement;
}

static char *get_iterator_member(void)
{
	struct expression *expr;

	if (!iterator_stmt ||
	    !iterator_stmt->iterator_pre_condition)
		return NULL;

	expr = iterator_stmt->iterator_pre_condition;
	if (expr->type != EXPR_PREOP || expr->op != '!')
		return NULL;
	expr = strip_parens(expr->unop);
	if (expr->type != EXPR_COMPARE)
		return NULL;
	expr = strip_parens(expr->left);
	if (expr->type != EXPR_PREOP || expr->op != '&')
		return NULL;
	expr = strip_expr(expr->unop);
	if (expr->type != EXPR_DEREF || !expr->member)
		return NULL;
	return expr->member->name;
}

static void match_pre_statement(struct expression *expr)
{
	char *name, *member;
	struct symbol *sym;
	char buf[64];

	if (!stmt_matches(expr, pre_stmt))
		return;

	name = expr_to_var_sym(expr->left, &sym);
	if (!name)
		return;
	member = get_iterator_member();

	snprintf(buf, sizeof(buf), "%s->%s.next", name, member);
	set_state(my_id, buf, sym, &start);
}

static void match_post_statement(struct expression *expr)
{
	struct smatch_state *state;
	char *name, *member;
	struct symbol *sym;
	char buf[64];

	if (!stmt_matches(expr, post_stmt))
		return;

	name = expr_to_var_sym(expr->left, &sym);
	if (!name)
		return;
	member = get_iterator_member();

	snprintf(buf, sizeof(buf), "%s->%s.next", name, member);
	state = get_state(my_id, buf, sym);
	if (!state || state == &start)
		return;

	sm_warning("iterator '%s' changed during iteration", buf);
}

void check_list_set_inside(int id)
{
	my_id = id;

	if (option_project != PROJ_KERNEL)
		return;

	add_hook(match_iterator_statement, STMT_HOOK);
	add_hook(match_pre_statement, ASSIGNMENT_HOOK_AFTER);
	add_hook(match_post_statement, ASSIGNMENT_HOOK);

	add_modification_hook(my_id, &set_watch);
}



  reply	other threads:[~2021-05-19 14:16 UTC|newest]

Thread overview: 39+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-05-16 16:06 [PATCH 1/6] staging: rtl8188eu: use safe iterator in rtw_free_network_queue Martin Kaiser
2021-05-16 16:06 ` [PATCH 2/6] staging: rtl8188eu: use safe iterator in rtw_free_all_stainfo Martin Kaiser
2021-05-16 19:24   ` Guenter Roeck
2021-05-16 16:06 ` [PATCH 3/6] staging: rtl8188eu: use safe iterator in expire_timeout_chk Martin Kaiser
2021-05-16 19:24   ` Guenter Roeck
2021-05-16 16:06 ` [PATCH 4/6] staging: rtl8188eu: use safe iterator in rtw_acl_remove_sta Martin Kaiser
2021-05-16 19:24   ` Guenter Roeck
2021-05-16 16:06 ` [PATCH 5/6] staging: rtl8188eu: use safe iterator in rtw_sta_flush Martin Kaiser
2021-05-16 19:24   ` Guenter Roeck
2021-05-16 16:06 ` [PATCH 6/6] staging: rtl8188eu: use safe iterator in rtw_free_xmitframe_queue Martin Kaiser
2021-05-16 19:24   ` Guenter Roeck
2021-05-16 19:24 ` [PATCH 1/6] staging: rtl8188eu: use safe iterator in rtw_free_network_queue Guenter Roeck
2021-05-16 20:03 ` Christophe JAILLET
2021-05-17 20:21   ` Martin Kaiser
2021-05-17 15:57 ` Dan Carpenter
2021-05-18  8:28   ` Dan Carpenter
2021-05-19 14:16     ` Dan Carpenter [this message]
2021-05-19 14:16     ` [PATCH] staging: emxx_udc: fix loop in _nbu2ss_nuke() Dan Carpenter
2021-05-19 14:17     ` [PATCH] w1: fix loop in w1_fini() Dan Carpenter
2023-05-08  8:59       ` (subset) " Krzysztof Kozlowski
2021-05-19 14:18     ` [bug report] {net, IB}/mlx5: Manage port association for multiport RoCE Dan Carpenter
2021-05-20  8:09       ` Leon Romanovsky
2021-05-19 14:19     ` [bug report] Bluetooth: L2CAP: Add initial code for Enhanced Credit Based Mode Dan Carpenter
2021-05-19 14:20     ` [PATCH] scsi: libsas: use _safe() loop in sas_resume_port() Dan Carpenter
2021-05-19 14:48       ` John Garry
2021-05-22  4:40       ` Martin K. Petersen
2021-05-17 20:18 ` [PATCH v2 1/6] staging: rtl8188eu: use safe iterator in rtw_free_network_queue Martin Kaiser
2021-05-17 20:18   ` [PATCH v2 2/6] staging: rtl8188eu: use safe iterator in rtw_free_all_stainfo Martin Kaiser
2021-05-17 20:32     ` Guenter Roeck
2021-05-17 20:18   ` [PATCH v2 3/6] staging: rtl8188eu: use safe iterator in expire_timeout_chk Martin Kaiser
2021-05-17 20:33     ` Guenter Roeck
2021-05-17 20:18   ` [PATCH v2 4/6] staging: rtl8188eu: use safe iterator in rtw_acl_remove_sta Martin Kaiser
2021-05-17 20:34     ` Guenter Roeck
2021-05-17 20:18   ` [PATCH v2 5/6] staging: rtl8188eu: use safe iterator in rtw_sta_flush Martin Kaiser
2021-05-17 20:34     ` Guenter Roeck
2021-05-17 20:18   ` [PATCH v2 6/6] staging: rtl8188eu: use safe iterator in rtw_free_xmitframe_queue Martin Kaiser
2021-05-17 20:35     ` Guenter Roeck
2021-05-17 20:30   ` [PATCH v2 1/6] staging: rtl8188eu: use safe iterator in rtw_free_network_queue Guenter Roeck
2021-05-18  7:44   ` Dan Carpenter

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210519141635.GE32682@kadam \
    --to=dan.carpenter@oracle.com \
    --cc=Larry.Finger@lwfinger.net \
    --cc=gregkh@linuxfoundation.org \
    --cc=kernel-janitors@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-staging@lists.linux.dev \
    --cc=linux@roeck-us.net \
    --cc=martin@kaiser.cx \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.