Shigeru Yoshida
unread,1:28 PM (2 hours ago) 1:28 PMSign in to reply to author
Sign in to forward
You do not have permission to delete messages in this group
Either email addresses are anonymous for this group or you need the view member email addresses permission to view the original message
to syzbot+5a66db...@syzkaller.appspotmail.com, syzkall...@googlegroups.com
#syz test
diff --git a/include/net/flow_offload.h b/include/net/flow_offload.h
index 596ab9791e4d..ff6d2bcb2cca 100644
--- a/include/net/flow_offload.h
+++ b/include/net/flow_offload.h
@@ -673,6 +673,8 @@ int flow_block_cb_setup_simple(struct flow_block_offload *f,
flow_setup_cb_t *cb,
void *cb_ident, void *cb_priv, bool ingress_only);
+void flow_block_cb_remove_driver(struct flow_block_cb *block_cb);
+
enum flow_cls_command {
FLOW_CLS_REPLACE,
FLOW_CLS_DESTROY,
diff --git a/net/core/flow_offload.c b/net/core/flow_offload.c
index bc5169482710..137a44af5e1c 100644
--- a/net/core/flow_offload.c
+++ b/net/core/flow_offload.c
@@ -334,6 +334,8 @@ bool flow_block_cb_is_busy(flow_setup_cb_t *cb, void *cb_ident,
}
EXPORT_SYMBOL(flow_block_cb_is_busy);
+static DEFINE_MUTEX(flow_block_cb_list_lock);
+
int flow_block_cb_setup_simple(struct flow_block_offload *f,
struct list_head *driver_block_list,
flow_setup_cb_t *cb,
@@ -341,6 +343,7 @@ int flow_block_cb_setup_simple(struct flow_block_offload *f,
bool ingress_only)
{
struct flow_block_cb *block_cb;
+ int err = 0;
if (ingress_only &&
f->binder_type != FLOW_BLOCK_BINDER_TYPE_CLSACT_INGRESS)
@@ -348,32 +351,52 @@ int flow_block_cb_setup_simple(struct flow_block_offload *f,
f->driver_block_list = driver_block_list;
+ mutex_lock(&flow_block_cb_list_lock);
+
switch (f->command) {
case FLOW_BLOCK_BIND:
- if (flow_block_cb_is_busy(cb, cb_ident, driver_block_list))
- return -EBUSY;
+ if (flow_block_cb_is_busy(cb, cb_ident, driver_block_list)) {
+ err = -EBUSY;
+ break;
+ }
block_cb = flow_block_cb_alloc(cb, cb_ident, cb_priv, NULL);
- if (IS_ERR(block_cb))
- return PTR_ERR(block_cb);
+ if (IS_ERR(block_cb)) {
+ err = PTR_ERR(block_cb);
+ break;
+ }
flow_block_cb_add(block_cb, f);
list_add_tail(&block_cb->driver_list, driver_block_list);
- return 0;
+ break;
case FLOW_BLOCK_UNBIND:
block_cb = flow_block_cb_lookup(f->block, cb, cb_ident);
- if (!block_cb)
- return -ENOENT;
+ if (!block_cb) {
+ err = -ENOENT;
+ break;
+ }
flow_block_cb_remove(block_cb, f);
list_del(&block_cb->driver_list);
- return 0;
+ break;
default:
- return -EOPNOTSUPP;
+ err = -EOPNOTSUPP;
+ break;
}
+
+ mutex_unlock(&flow_block_cb_list_lock);
+ return err;
}
EXPORT_SYMBOL(flow_block_cb_setup_simple);
+void flow_block_cb_remove_driver(struct flow_block_cb *block_cb)
+{
+ mutex_lock(&flow_block_cb_list_lock);
+ list_del(&block_cb->driver_list);
+ mutex_unlock(&flow_block_cb_list_lock);
+}
+EXPORT_SYMBOL(flow_block_cb_remove_driver);
+
static DEFINE_MUTEX(flow_indr_block_lock);
static LIST_HEAD(flow_block_indr_list);
static LIST_HEAD(flow_block_indr_dev_list);
diff --git a/net/netfilter/nf_tables_offload.c b/net/netfilter/nf_tables_offload.c
index fd30e205de84..d60838bceafb 100644
--- a/net/netfilter/nf_tables_offload.c
+++ b/net/netfilter/nf_tables_offload.c
@@ -414,7 +414,7 @@ static void nft_indr_block_cleanup(struct flow_block_cb *block_cb)
basechain, &extack);
nft_net = nft_pernet(net);
mutex_lock(&nft_net->commit_mutex);
- list_del(&block_cb->driver_list);
+ flow_block_cb_remove_driver(block_cb);
list_move(&block_cb->list, &bo.cb_list);
nft_flow_offload_unbind(&bo, basechain);
mutex_unlock(&nft_net->commit_mutex);