AI Trajectory


Trajectory: (Expand/Collapse All)
Seq Timestamp Type Name Duration
0/0 2026/07/31 19:29 flow patch-triage
0m Args:
null

Results:
{
  "EnableConfigs": [
    "TIPC"
  ],
  "FocusSymbols": [
    "tipc_named_node_up",
    "tipc_named_dist_cluster_scope",
    "tipc_nametbl_publish",
    "tipc_nametbl_withdraw",
    "tipc_node_wakeup"
  ],
  "Reasoning": "The patch introduces a workqueue for bulk distribution of cluster scope publications in TIPC, modifying core protocol logic such as node state management and name table publishing. This is a functional change to the TIPC subsystem, which is reachable in virtualized environments and should be fuzzed.",
  "WorthFuzzing": true
}

1/1 2026/07/31 19:29 action read-patch-diff
0m Args:
null

Results:
{
  "PatchDiff": "commit 9e1faf72116874b361bcddc68448db061279cc30\nAuthor: syz-cluster \u003ctriage@syzkaller.com\u003e\nDate:   Fri Jul 31 19:29:33 2026 +0000\n\n    syz-cluster: applied patch under review\n\ndiff --git a/net/tipc/core.c b/net/tipc/core.c\nindex 315975c3be818..1e1fe78cc4ee4 100644\n--- a/net/tipc/core.c\n+++ b/net/tipc/core.c\n@@ -61,6 +61,8 @@ static int __net_init tipc_init_net(struct net *net)\n \ttn-\u003etrial_addr = 0;\n \ttn-\u003eaddr_trial_end = 0;\n \ttn-\u003ecapabilities = TIPC_NODE_CAPABILITIES;\n+\tatomic_set(\u0026tn-\u003enode_wq_count, 0);\n+\tatomic_set(\u0026tn-\u003efinalized, 0);\n \tINIT_WORK(\u0026tn-\u003ework, tipc_net_finalize_work);\n \tmemset(tn-\u003enode_id, 0, sizeof(tn-\u003enode_id));\n \tmemset(tn-\u003enode_id_string, 0, sizeof(tn-\u003enode_id_string));\n@@ -119,6 +121,7 @@ static void __net_exit tipc_exit_net(struct net *net)\n #ifdef CONFIG_TIPC_CRYPTO\n \ttipc_crypto_stop(\u0026tipc_net(net)-\u003ecrypto_tx);\n #endif\n+\twait_var_event(\u0026tn-\u003enode_wq_count, !atomic_read(\u0026tn-\u003enode_wq_count));\n \twait_var_event(\u0026tn-\u003ewq_count, atomic_read(\u0026tn-\u003ewq_count) == 0);\n }\n \ndiff --git a/net/tipc/core.h b/net/tipc/core.h\nindex 9ce5f9ff6cc03..be335ce83389a 100644\n--- a/net/tipc/core.h\n+++ b/net/tipc/core.h\n@@ -145,6 +145,10 @@ struct tipc_net {\n \tstruct work_struct work;\n \t/* The numbers of work queues in schedule */\n \tatomic_t wq_count;\n+\t/* The numbers of works of created nodes in schedule */\n+\tatomic_t node_wq_count;\n+\t/* flag to wake up scheduled works of created nodes */\n+\tatomic_t finalized;\n };\n \n static inline struct tipc_net *tipc_net(struct net *net)\ndiff --git a/net/tipc/name_distr.c b/net/tipc/name_distr.c\nindex ba4f4906e13b7..c8e28497356ef 100644\n--- a/net/tipc/name_distr.c\n+++ b/net/tipc/name_distr.c\n@@ -147,8 +147,8 @@ struct sk_buff *tipc_named_withdraw(struct net *net, struct publication *p)\n  * @pls: linked list of publication items to be packed into buffer chain\n  * @seqno: sequence number for this message\n  */\n-static void named_distribute(struct net *net, struct sk_buff_head *list,\n-\t\t\t     u32 dnode, struct list_head *pls, u16 seqno)\n+static int named_distribute(struct net *net, struct sk_buff_head *list,\n+\t\t\t    u32 dnode, struct list_head *pls, u16 seqno)\n {\n \tstruct publication *publ;\n \tstruct sk_buff *skb = NULL;\n@@ -164,8 +164,9 @@ static void named_distribute(struct net *net, struct sk_buff_head *list,\n \t\t\tskb = named_prepare_buf(net, PUBLICATION, msg_rem,\n \t\t\t\t\t\tdnode);\n \t\t\tif (!skb) {\n+\t\t\t\t__skb_queue_purge(list);\n \t\t\t\tpr_warn(\"Bulk publication failure\\n\");\n-\t\t\t\treturn;\n+\t\t\t\treturn 1;\n \t\t\t}\n \t\t\thdr = buf_msg(skb);\n \t\t\tmsg_set_bc_ack_invalid(hdr, true);\n@@ -195,15 +196,16 @@ static void named_distribute(struct net *net, struct sk_buff_head *list,\n \thdr = buf_msg(skb_peek_tail(list));\n \tmsg_set_last_bulk(hdr);\n \tmsg_set_named_seqno(hdr, seqno);\n+\n+\treturn 0;\n }\n \n /**\n- * tipc_named_node_up - tell specified node about all publications by this node\n+ * tipc_named_distribute - distribute all publications to specified node\n  * @net: the associated network namespace\n  * @dnode: destination node\n- * @capabilities: peer node's capabilities\n  */\n-void tipc_named_node_up(struct net *net, u32 dnode, u16 capabilities)\n+static int tipc_named_distribute(struct net *net, u32 dnode)\n {\n \tstruct name_table *nt = tipc_name_table(net);\n \tstruct tipc_net *tn = tipc_net(net);\n@@ -212,15 +214,86 @@ void tipc_named_node_up(struct net *net, u32 dnode, u16 capabilities)\n \n \t__skb_queue_head_init(\u0026head);\n \tspin_lock_bh(\u0026tn-\u003enametbl_lock);\n-\tif (!(capabilities \u0026 TIPC_NAMED_BCAST))\n-\t\tnt-\u003erc_dests++;\n \tseqno = nt-\u003esnd_nxt;\n \tspin_unlock_bh(\u0026tn-\u003enametbl_lock);\n \n \tread_lock_bh(\u0026nt-\u003ecluster_scope_lock);\n-\tnamed_distribute(net, \u0026head, dnode, \u0026nt-\u003ecluster_scope, seqno);\n+\tif (named_distribute(net, \u0026head, dnode, \u0026nt-\u003ecluster_scope, seqno)) {\n+\t\tread_unlock_bh(\u0026nt-\u003ecluster_scope_lock);\n+\t\treturn -ENOBUFS;\n+\t}\n \ttipc_node_xmit(net, \u0026head, dnode, 0);\n \tread_unlock_bh(\u0026nt-\u003ecluster_scope_lock);\n+\n+\treturn 0;\n+}\n+\n+/**\n+ * tipc_named_node_up - tell specified node about all publications by this node\n+ * @net: the associated network namespace\n+ * @dnode: destination node\n+ * @capabilities: peer node's capabilities\n+ */\n+int tipc_named_node_up(struct net *net, u32 dnode, u16 capabilities)\n+{\n+\tstruct name_table *nt = tipc_name_table(net);\n+\tstruct tipc_net *tn = tipc_net(net);\n+\n+\tspin_lock_bh(\u0026tn-\u003enametbl_lock);\n+\tif (!(capabilities \u0026 TIPC_NAMED_BCAST))\n+\t\tnt-\u003erc_dests++;\n+\tspin_unlock_bh(\u0026tn-\u003enametbl_lock);\n+\n+\tread_lock_bh(\u0026nt-\u003ecluster_scope_lock);\n+\t/* 1. tipc_net_finalize_work() is not scheduled because of namespace\n+\t *    teardown.\n+\t * 2. Or tipc_net_finalize() ---\u003e tipc_nametbl_publish() has failed\n+\t *    to insert node self address publication into nt-\u003ecluster_scope\n+\t *    due to memory allocation failure.\n+\t * 3. Or tipc_net_finalize() ---\u003e tipc_nametbl_publish() has not\n+\t *    executed yet.\n+\t */\n+\tif (unlikely(list_empty(\u0026nt-\u003ecluster_scope))) {\n+\t\tread_unlock_bh(\u0026nt-\u003ecluster_scope_lock);\n+\t\treturn 1;\n+\t}\n+\tread_unlock_bh(\u0026nt-\u003ecluster_scope_lock);\n+\n+\treturn tipc_named_distribute(net, dnode);\n+}\n+\n+/**\n+ * tipc_named_dist_cluster_scope - distribute all publications to specified node\n+ * @net: the associated network namespace\n+ * @dnode: destination node\n+ */\n+int tipc_named_dist_cluster_scope(struct net *net, u32 dnode)\n+{\n+\tstruct name_table *nt = tipc_name_table(net);\n+\tbool reinsert = false;\n+\n+\tread_lock_bh(\u0026nt-\u003ecluster_scope_lock);\n+\tif (unlikely(list_empty(\u0026nt-\u003ecluster_scope)))\n+\t\treinsert = true;\n+\tread_unlock_bh(\u0026nt-\u003ecluster_scope_lock);\n+\t/* tipc_net_finalize() ---\u003e tipc_nametbl_publish() has failed to insert\n+\t * node self address publication into nt-\u003ecluster_scope due to memory\n+\t * allocation failure. So, reinsert this publication.\n+\t */\n+\tif (reinsert) {\n+\t\tstruct tipc_net *tn = tipc_net(net);\n+\t\tstruct tipc_socket_addr sk;\n+\t\tstruct tipc_uaddr ua;\n+\n+\t\tsk.ref = 0;\n+\t\tsk.node = tn-\u003enode_addr;\n+\t\ttipc_uaddr(\u0026ua, TIPC_SERVICE_RANGE, TIPC_CLUSTER_SCOPE,\n+\t\t\t   TIPC_NODE_STATE, tn-\u003enode_addr, tn-\u003enode_addr);\n+\t\tif (!tipc_nametbl_publish(net, \u0026ua, \u0026sk, tn-\u003enode_addr))\n+\t\t\treturn -ENOBUFS;\n+\t}\n+\n+\treturn tipc_named_distribute(net, dnode);\n }\n \n /**\ndiff --git a/net/tipc/name_distr.h b/net/tipc/name_distr.h\nindex c677f6f082dfb..cadf4e8c3e66c 100644\n--- a/net/tipc/name_distr.h\n+++ b/net/tipc/name_distr.h\n@@ -69,7 +69,8 @@ struct distr_item {\n \n struct sk_buff *tipc_named_publish(struct net *net, struct publication *publ);\n struct sk_buff *tipc_named_withdraw(struct net *net, struct publication *publ);\n-void tipc_named_node_up(struct net *net, u32 dnode, u16 capabilities);\n+int tipc_named_node_up(struct net *net, u32 dnode, u16 capabilities);\n+int tipc_named_dist_cluster_scope(struct net *net, u32 dnode);\n void tipc_named_rcv(struct net *net, struct sk_buff_head *namedq,\n \t\t    u16 *rcv_nxt, bool *open);\n void tipc_named_reinit(struct net *net);\ndiff --git a/net/tipc/name_table.c b/net/tipc/name_table.c\nindex 253c72d1366eb..6fda36ab17669 100644\n--- a/net/tipc/name_table.c\n+++ b/net/tipc/name_table.c\n@@ -763,21 +763,40 @@ struct publication *tipc_nametbl_publish(struct net *net, struct tipc_uaddr *ua,\n \t\t\t\t\t struct tipc_socket_addr *sk, u32 key)\n {\n \tstruct name_table *nt = tipc_name_table(net);\n+\tu32 max_user_pub = TIPC_MAX_PUBL - 1;\n \tstruct tipc_net *tn = tipc_net(net);\n \tstruct publication *p = NULL;\n \tstruct sk_buff *skb = NULL;\n+\tbool protocol_type = false;\n \tu32 rc_dests;\n \n+\tif (ua-\u003esr.type == TIPC_NODE_STATE || ua-\u003esr.type == TIPC_LINK_STATE ||\n+\t    ua-\u003esr.type == TIPC_TOP_SRV)\n+\t\tprotocol_type = true;\n+\n \tspin_lock_bh(\u0026tn-\u003enametbl_lock);\n+\tif (protocol_type)\n+\t\tgoto insert;\n \n-\tif (nt-\u003elocal_publ_count \u003e= TIPC_MAX_PUBL) {\n-\t\tpr_warn(\"Bind failed, max limit %u reached\\n\", TIPC_MAX_PUBL);\n+\t/* Reserve one entry for node state service type because it has cluster\n+\t * scope and it is distributed in bulk. So, the maximum number of user's\n+\t * publications is (TIPC_MAX_PUBL - 1).\n+\t */\n+\tif (nt-\u003elocal_publ_count \u003e= max_user_pub) {\n+\t\tpr_warn(\"Bind failed, max limit %u reached\\n\", max_user_pub);\n \t\tgoto exit;\n \t}\n \n+insert:\n \tp = tipc_nametbl_insert_publ(net, ua, sk, key);\n \tif (p) {\n-\t\tnt-\u003elocal_publ_count++;\n+\t\t/* Not count node state, link state and topology server types\n+\t\t * so that maximum nt-\u003elocal_publ_count does not prevent\n+\t\t * protocol service types from being inserted into the name\n+\t\t * table.\n+\t\t */\n+\t\tif (!protocol_type)\n+\t\t\tnt-\u003elocal_publ_count++;\n \t\tskb = tipc_named_publish(net, p);\n \t}\n \trc_dests = nt-\u003erc_dests;\n@@ -810,7 +829,10 @@ void tipc_nametbl_withdraw(struct net *net, struct tipc_uaddr *ua,\n \n \tp = tipc_nametbl_remove_publ(net, ua, sk, key);\n \tif (p) {\n-\t\tnt-\u003elocal_publ_count--;\n+\t\tif (p-\u003esr.type != TIPC_NODE_STATE \u0026\u0026\n+\t\t    p-\u003esr.type != TIPC_LINK_STATE \u0026\u0026\n+\t\t    p-\u003esr.type != TIPC_TOP_SRV)\n+\t\t\tnt-\u003elocal_publ_count--;\n \t\tskb = tipc_named_withdraw(net, p);\n \t\tlist_del_init(\u0026p-\u003ebinding_sock);\n \t\tkfree_rcu(p, rcu);\ndiff --git a/net/tipc/net.c b/net/tipc/net.c\nindex 7e65d0b0c4a8d..75ac4e3cd01a8 100644\n--- a/net/tipc/net.c\n+++ b/net/tipc/net.c\n@@ -139,6 +139,11 @@ static void tipc_net_finalize(struct net *net, u32 addr)\n \ttipc_sk_reinit(net);\n \ttipc_mon_reinit_self(net);\n \ttipc_nametbl_publish(net, \u0026ua, \u0026sk, addr);\n+\tatomic_set(\u0026tn-\u003efinalized, 1);\n+\t/* Wake up nodes waiting for distributing bulk of publications\n+\t * if applicable.\n+\t */\n+\ttipc_node_wakeup(net);\n }\n \n void tipc_net_finalize_work(struct work_struct *work)\ndiff --git a/net/tipc/node.c b/net/tipc/node.c\nindex 8e4ef2630ae4f..334812bdab765 100644\n--- a/net/tipc/node.c\n+++ b/net/tipc/node.c\n@@ -111,6 +111,9 @@ struct tipc_bclink_entry {\n  * @peer_net: peer's net namespace\n  * @peer_hash_mix: hash for this peer (FIXME)\n  * @crypto_rx: RX crypto handler\n+ * @work: work item for bulk distribution of cluster scope publications\n+ * @work_scheduled: flag to indicate the work has been scheduled\n+ * @finalized: flag to wake up scheduled work\n  */\n struct tipc_node {\n \tu32 addr;\n@@ -145,6 +148,9 @@ struct tipc_node {\n #ifdef CONFIG_TIPC_CRYPTO\n \tstruct tipc_crypto *crypto_rx;\n #endif\n+\tstruct work_struct work;\n+\tatomic_t work_scheduled;\n+\tatomic_t finalized;\n };\n \n /* Node FSM states and events:\n@@ -393,6 +399,59 @@ static void tipc_node_write_unlock_fast(struct tipc_node *n)\n \twrite_unlock_bh(\u0026n-\u003elock);\n }\n \n+static void tipc_node_down(struct tipc_node *n)\n+{\n+\tint bearer_id;\n+\n+\tfor (bearer_id = 0; bearer_id \u003c MAX_BEARERS; bearer_id++)\n+\t\ttipc_node_link_down(n, bearer_id, false);\n+}\n+\n+static void tipc_node_dist_bulk(struct work_struct *work)\n+{\n+\tstruct tipc_node *node = container_of(work, struct tipc_node, work);\n+\tstruct tipc_net *tn = tipc_net(node-\u003enet);\n+\n+\twait_var_event(\u0026node-\u003efinalized, atomic_read(\u0026node-\u003efinalized));\n+\n+\t/* node is down */\n+\tif (!atomic_read(\u0026node-\u003ework_scheduled))\n+\t\tgoto exit;\n+\n+\t/* Stop waking up work in tipc_node_timeout() */\n+\tatomic_set(\u0026node-\u003ework_scheduled, 0);\n+\n+\tif (tipc_named_dist_cluster_scope(node-\u003enet, node-\u003eaddr) \u003c 0)\n+\t\ttipc_node_down(node);\n+\n+exit:\n+\tif (atomic_dec_and_test(\u0026tn-\u003enode_wq_count))\n+\t\twake_up_var(\u0026tn-\u003enode_wq_count);\n+\n+\ttipc_node_put(node);\n+}\n+\n+static void tipc_node_cancel_work(struct tipc_node *node)\n+{\n+\tif (atomic_read(\u0026node-\u003ework_scheduled)) {\n+\t\tstruct tipc_net *tn = tipc_net(node-\u003enet);\n+\n+\t\t/* Wake up scheduled work if it is waiting. */\n+\t\tif (!atomic_read(\u0026node-\u003efinalized)) {\n+\t\t\tatomic_set(\u0026node-\u003ework_scheduled, 0);\n+\t\t\tatomic_set(\u0026node-\u003efinalized, 1);\n+\t\t\twake_up_var(\u0026node-\u003efinalized);\n+\t\t}\n+\n+\t\t/* Work is pending */\n+\t\tif (cancel_work(\u0026node-\u003ework)) {\n+\t\t\tif (atomic_dec_and_test(\u0026tn-\u003enode_wq_count))\n+\t\t\t\twake_up_var(\u0026tn-\u003enode_wq_count);\n+\t\t\ttipc_node_put(node);\n+\t\t}\n+\t}\n+}\n+\n static void tipc_node_write_unlock(struct tipc_node *n)\n \t__releases(n-\u003elock)\n {\n@@ -421,11 +480,32 @@ static void tipc_node_write_unlock(struct tipc_node *n)\n \n \twrite_unlock_bh(\u0026n-\u003elock);\n \n-\tif (flags \u0026 TIPC_NOTIFY_NODE_DOWN)\n+\tif (flags \u0026 TIPC_NOTIFY_NODE_DOWN) {\n \t\ttipc_publ_notify(net, publ_list, node, n-\u003ecapabilities);\n-\n-\tif (flags \u0026 TIPC_NOTIFY_NODE_UP)\n-\t\ttipc_named_node_up(net, node, n-\u003ecapabilities);\n+\t\ttipc_node_cancel_work(n);\n+\t}\n+\n+\tif (flags \u0026 TIPC_NOTIFY_NODE_UP) {\n+\t\tstruct tipc_net *tn = tipc_net(net);\n+\t\tint rc = 0;\n+\n+\t\trc = tipc_named_node_up(net, node, n-\u003ecapabilities);\n+\t\t/* Defer bulk distribution to work queue */\n+\t\tif (rc \u003e 0) {\n+\t\t\tatomic_set(\u0026n-\u003ework_scheduled, 1);\n+\t\t\tatomic_inc(\u0026tn-\u003enode_wq_count);\n+\t\t\ttipc_node_get(n);\n+\t\t\tif (!schedule_work(\u0026n-\u003ework)) {\n+\t\t\t\tatomic_dec(\u0026tn-\u003enode_wq_count);\n+\t\t\t\ttipc_node_put(n);\n+\t\t\t}\n+\t\t} else if (rc \u003c 0) {\n+\t\t\t/* Bring the node down to start over bulk distribution\n+\t\t\t * when the first link is up again.\n+\t\t\t */\n+\t\t\ttipc_node_down(n);\n+\t\t}\n+\t}\n \n \tif (flags \u0026 TIPC_NOTIFY_LINK_UP) {\n \t\ttipc_mon_peer_up(net, node, bearer_id);\n@@ -564,6 +644,9 @@ struct tipc_node *tipc_node_create(struct net *net, u32 addr, u8 *peer_id,\n \tINIT_LIST_HEAD(\u0026n-\u003elist);\n \tINIT_LIST_HEAD(\u0026n-\u003epubl_list);\n \tINIT_LIST_HEAD(\u0026n-\u003econn_sks);\n+\tINIT_WORK(\u0026n-\u003ework, tipc_node_dist_bulk);\n+\tatomic_set(\u0026n-\u003ework_scheduled, 0);\n+\tatomic_set(\u0026n-\u003efinalized, 0);\n \tskb_queue_head_init(\u0026n-\u003ebc_entry.namedq);\n \tskb_queue_head_init(\u0026n-\u003ebc_entry.inputq1);\n \t__skb_queue_head_init(\u0026n-\u003ebc_entry.arrvq);\n@@ -653,6 +736,21 @@ void tipc_node_stop(struct net *net)\n \tspin_unlock_bh(\u0026tn-\u003enode_list_lock);\n }\n \n+void tipc_node_wakeup(struct net *net)\n+{\n+\tstruct tipc_net *tn = tipc_net(net);\n+\tstruct tipc_node *node;\n+\n+\trcu_read_lock();\n+\tlist_for_each_entry_rcu(node, \u0026tn-\u003enode_list, list) {\n+\t\tif (atomic_read(\u0026node-\u003ework_scheduled)) {\n+\t\t\tatomic_set(\u0026node-\u003efinalized, 1);\n+\t\t\twake_up_var(\u0026node-\u003efinalized);\n+\t\t}\n+\t}\n+\trcu_read_unlock();\n+}\n+\n void tipc_node_subscribe(struct net *net, struct list_head *subscr, u32 addr)\n {\n \tstruct tipc_node *n;\n@@ -801,6 +899,7 @@ static bool tipc_node_cleanup(struct tipc_node *peer)\n static void tipc_node_timeout(struct timer_list *t)\n {\n \tstruct tipc_node *n = timer_container_of(n, t, timer);\n+\tstruct tipc_net *tn = tipc_net(n-\u003enet);\n \tstruct tipc_link_entry *le;\n \tstruct sk_buff_head xmitq;\n \tint remains = n-\u003elink_cnt;\n@@ -814,6 +913,11 @@ static void tipc_node_timeout(struct timer_list *t)\n \t\treturn;\n \t}\n \n+\tif (atomic_read(\u0026tn-\u003efinalized) \u0026\u0026 atomic_read(\u0026n-\u003ework_scheduled)) {\n+\t\tatomic_set(\u0026n-\u003efinalized, 1);\n+\t\twake_up_var(\u0026n-\u003efinalized);\n+\t}\n+\n #ifdef CONFIG_TIPC_CRYPTO\n \t/* Take any crypto key related actions first */\n \ttipc_crypto_timeout(n-\u003ecrypto_rx);\ndiff --git a/net/tipc/node.h b/net/tipc/node.h\nindex 154a5bbb0d29d..c7bc3bc053285 100644\n--- a/net/tipc/node.h\n+++ b/net/tipc/node.h\n@@ -75,6 +75,7 @@ enum {\n #define INVALID_BEARER_ID -1\n \n void tipc_node_stop(struct net *net);\n+void tipc_node_wakeup(struct net *net);\n bool tipc_node_get_id(struct net *net, u32 addr, u8 *id);\n u32 tipc_node_get_addr(struct tipc_node *node);\n char *tipc_node_get_id_str(struct tipc_node *node);\n"
}

2/1 2026/07/31 19:29 agent patch-evaluator
0m Model:
best-expensive

Args:
null

Results:
{
  "EnableConfigs": [
    "TIPC"
  ],
  "FocusSymbols": [
    "tipc_named_node_up",
    "tipc_named_dist_cluster_scope",
    "tipc_nametbl_publish",
    "tipc_nametbl_withdraw",
    "tipc_node_wakeup"
  ],
  "Reasoning": "The patch introduces a workqueue for bulk distribution of cluster scope publications in TIPC, modifying core protocol logic such as node state management and name table publishing. This is a functional change to the TIPC subsystem, which is reachable in virtualized environments and should be fuzzed.",
  "WorthFuzzing": true
}

Instruction:
You are an expert Linux kernel maintainer.
Your job is to review a provided patch series and determine
if it makes functional changes to the kernel that should be fuzzed.

IMPORTANT: The changes have ALREADY been applied and committed as the HEAD commit in
your workspace. Do NOT rely on your internal knowledge of the kernel. You must actively
use your code access tools to examine the actual source code and confirm any assumptions.

Return WorthFuzzing=false if the patch only contains:
- Modifications to Documentation/, Kconfig files, or code comments.
- Purely decorative changes, such as logging (e.g., pr_err, printk) or tracepoints.
- Changes to numeric constants or macros that do not functionally alter execution flow.
- Code paths that are impossible to reach in virtualized environments like GCE or QEMU,
  even when utilizing software-emulated hardware (e.g., usb gadget, mac80211_hwsim).
- Code in vendor-specific PCIe switch, SmartNIC, or GPU drivers (e.g., mlxsw, pds_core, qed,
  ionic, amdgpu) that require physical PCIe hardware cards not emulated in standard QEMU.
- Driver .remove, .shutdown, or pci_unregister_driver teardown callbacks (e.g., igb_remove)
  that are executed only during PCI hot-unplug or sysfs driver unbind operations.

If it modifies reachable core kernel logic, drivers, or architectures, use your code search
tools to verify the code can be executed, then return WorthFuzzing=true.

When returning WorthFuzzing=true, you MUST ALSO:
1. Extract any specific kernel functions that should be heavily fuzzed into FocusSymbols.
   Avoid listing generic hot-path functions to prevent skewed test distributions.
   Prefer non-static, non-inlined API entrypoint functions over internal static helper functions
   (which are inlined by the compiler and do not have distinct symbol addresses).
2. Identify any specific CONFIG_ options required to properly test this new/modified feature.
   Go and look into the Kconfig files and check for ifdefs around the code, do not make assumptions.
   Also check "depends on" lines in Kconfig to include any non-standard parent subsystem configs
   needed for Kbuild to compile the code statically into vmlinux. List them in the EnableConfigs
   output array, and DO NOT add a 'CONFIG_' prefix (e.g., return "NET_IPV4" instead of "CONFIG_NET_IPV4").
Prefer calling several tools at the same time to save round-trips.


Use set-results tool to provide results of the analysis.
It must be called exactly once before the final reply.
Ignore results of this tool.

Prompt:
For your convenience, here is the diff of the changes:
commit 9e1faf72116874b361bcddc68448db061279cc30
Author: syz-cluster <triage@syzkaller.com>
Date:   Fri Jul 31 19:29:33 2026 +0000

    syz-cluster: applied patch under review

diff --git a/net/tipc/core.c b/net/tipc/core.c
index 315975c3be818..1e1fe78cc4ee4 100644
--- a/net/tipc/core.c
+++ b/net/tipc/core.c
@@ -61,6 +61,8 @@ static int __net_init tipc_init_net(struct net *net)
 	tn->trial_addr = 0;
 	tn->addr_trial_end = 0;
 	tn->capabilities = TIPC_NODE_CAPABILITIES;
+	atomic_set(&tn->node_wq_count, 0);
+	atomic_set(&tn->finalized, 0);
 	INIT_WORK(&tn->work, tipc_net_finalize_work);
 	memset(tn->node_id, 0, sizeof(tn->node_id));
 	memset(tn->node_id_string, 0, sizeof(tn->node_id_string));
@@ -119,6 +121,7 @@ static void __net_exit tipc_exit_net(struct net *net)
 #ifdef CONFIG_TIPC_CRYPTO
 	tipc_crypto_stop(&tipc_net(net)->crypto_tx);
 #endif
+	wait_var_event(&tn->node_wq_count, !atomic_read(&tn->node_wq_count));
 	wait_var_event(&tn->wq_count, atomic_read(&tn->wq_count) == 0);
 }
 
diff --git a/net/tipc/core.h b/net/tipc/core.h
index 9ce5f9ff6cc03..be335ce83389a 100644
--- a/net/tipc/core.h
+++ b/net/tipc/core.h
@@ -145,6 +145,10 @@ struct tipc_net {
 	struct work_struct work;
 	/* The numbers of work queues in schedule */
 	atomic_t wq_count;
+	/* The numbers of works of created nodes in schedule */
+	atomic_t node_wq_count;
+	/* flag to wake up scheduled works of created nodes */
+	atomic_t finalized;
 };
 
 static inline struct tipc_net *tipc_net(struct net *net)
diff --git a/net/tipc/name_distr.c b/net/tipc/name_distr.c
index ba4f4906e13b7..c8e28497356ef 100644
--- a/net/tipc/name_distr.c
+++ b/net/tipc/name_distr.c
@@ -147,8 +147,8 @@ struct sk_buff *tipc_named_withdraw(struct net *net, struct publication *p)
  * @pls: linked list of publication items to be packed into buffer chain
  * @seqno: sequence number for this message
  */
-static void named_distribute(struct net *net, struct sk_buff_head *list,
-			     u32 dnode, struct list_head *pls, u16 seqno)
+static int named_distribute(struct net *net, struct sk_buff_head *list,
+			    u32 dnode, struct list_head *pls, u16 seqno)
 {
 	struct publication *publ;
 	struct sk_buff *skb = NULL;
@@ -164,8 +164,9 @@ static void named_distribute(struct net *net, struct sk_buff_head *list,
 			skb = named_prepare_buf(net, PUBLICATION, msg_rem,
 						dnode);
 			if (!skb) {
+				__skb_queue_purge(list);
 				pr_warn("Bulk publication failure\n");
-				return;
+				return 1;
 			}
 			hdr = buf_msg(skb);
 			msg_set_bc_ack_invalid(hdr, true);
@@ -195,15 +196,16 @@ static void named_distribute(struct net *net, struct sk_buff_head *list,
 	hdr = buf_msg(skb_peek_tail(list));
 	msg_set_last_bulk(hdr);
 	msg_set_named_seqno(hdr, seqno);
+
+	return 0;
 }
 
 /**
- * tipc_named_node_up - tell specified node about all publications by this node
+ * tipc_named_distribute - distribute all publications to specified node
  * @net: the associated network namespace
  * @dnode: destination node
- * @capabilities: peer node's capabilities
  */
-void tipc_named_node_up(struct net *net, u32 dnode, u16 capabilities)
+static int tipc_named_distribute(struct net *net, u32 dnode)
 {
 	struct name_table *nt = tipc_name_table(net);
 	struct tipc_net *tn = tipc_net(net);
@@ -212,15 +214,86 @@ void tipc_named_node_up(struct net *net, u32 dnode, u16 capabilities)
 
 	__skb_queue_head_init(&head);
 	spin_lock_bh(&tn->nametbl_lock);
-	if (!(capabilities & TIPC_NAMED_BCAST))
-		nt->rc_dests++;
 	seqno = nt->snd_nxt;
 	spin_unlock_bh(&tn->nametbl_lock);
 
 	read_lock_bh(&nt->cluster_scope_lock);
-	named_distribute(net, &head, dnode, &nt->cluster_scope, seqno);
+	if (named_distribute(net, &head, dnode, &nt->cluster_scope, seqno)) {
+		read_unlock_bh(&nt->cluster_scope_lock);
+		return -ENOBUFS;
+	}
 	tipc_node_xmit(net, &head, dnode, 0);
 	read_unlock_bh(&nt->cluster_scope_lock);
+
+	return 0;
+}
+
+/**
+ * tipc_named_node_up - tell specified node about all publications by this node
+ * @net: the associated network namespace
+ * @dnode: destination node
+ * @capabilities: peer node's capabilities
+ */
+int tipc_named_node_up(struct net *net, u32 dnode, u16 capabilities)
+{
+	struct name_table *nt = tipc_name_table(net);
+	struct tipc_net *tn = tipc_net(net);
+
+	spin_lock_bh(&tn->nametbl_lock);
+	if (!(capabilities & TIPC_NAMED_BCAST))
+		nt->rc_dests++;
+	spin_unlock_bh(&tn->nametbl_lock);
+
+	read_lock_bh(&nt->cluster_scope_lock);
+	/* 1. tipc_net_finalize_work() is not scheduled because of namespace
+	 *    teardown.
+	 * 2. Or tipc_net_finalize() ---> tipc_nametbl_publish() has failed
+	 *    to insert node self address publication into nt->cluster_scope
+	 *    due to memory allocation failure.
+	 * 3. Or tipc_net_finalize() ---> tipc_nametbl_publish() has not
+	 *    executed yet.
+	 */
+	if (unlikely(list_empty(&nt->cluster_scope))) {
+		read_unlock_bh(&nt->cluster_scope_lock);
+		return 1;
+	}
+	read_unlock_bh(&nt->cluster_scope_lock);
+
+	return tipc_named_distribute(net, dnode);
+}
+
+/**
+ * tipc_named_dist_cluster_scope - distribute all publications to specified node
+ * @net: the associated network namespace
+ * @dnode: destination node
+ */
+int tipc_named_dist_cluster_scope(struct net *net, u32 dnode)
+{
+	struct name_table *nt = tipc_name_table(net);
+	bool reinsert = false;
+
+	read_lock_bh(&nt->cluster_scope_lock);
+	if (unlikely(list_empty(&nt->cluster_scope)))
+		reinsert = true;
+	read_unlock_bh(&nt->cluster_scope_lock);
+	/* tipc_net_finalize() ---> tipc_nametbl_publish() has failed to insert
+	 * node self address publication into nt->cluster_scope due to memory
+	 * allocation failure. So, reinsert this publication.
+	 */
+	if (reinsert) {
+		struct tipc_net *tn = tipc_net(net);
+		struct tipc_socket_addr sk;
+		struct tipc_uaddr ua;
+
+		sk.ref = 0;
+		sk.node = tn->node_addr;
+		tipc_uaddr(&ua, TIPC_SERVICE_RANGE, TIPC_CLUSTER_SCOPE,
+			   TIPC_NODE_STATE, tn->node_addr, tn->node_addr);
+		if (!tipc_nametbl_publish(net, &ua, &sk, tn->node_addr))
+			return -ENOBUFS;
+	}
+
+	return tipc_named_distribute(net, dnode);
 }
 
 /**
diff --git a/net/tipc/name_distr.h b/net/tipc/name_distr.h
index c677f6f082dfb..cadf4e8c3e66c 100644
--- a/net/tipc/name_distr.h
+++ b/net/tipc/name_distr.h
@@ -69,7 +69,8 @@ struct distr_item {
 
 struct sk_buff *tipc_named_publish(struct net *net, struct publication *publ);
 struct sk_buff *tipc_named_withdraw(struct net *net, struct publication *publ);
-void tipc_named_node_up(struct net *net, u32 dnode, u16 capabilities);
+int tipc_named_node_up(struct net *net, u32 dnode, u16 capabilities);
+int tipc_named_dist_cluster_scope(struct net *net, u32 dnode);
 void tipc_named_rcv(struct net *net, struct sk_buff_head *namedq,
 		    u16 *rcv_nxt, bool *open);
 void tipc_named_reinit(struct net *net);
diff --git a/net/tipc/name_table.c b/net/tipc/name_table.c
index 253c72d1366eb..6fda36ab17669 100644
--- a/net/tipc/name_table.c
+++ b/net/tipc/name_table.c
@@ -763,21 +763,40 @@ struct publication *tipc_nametbl_publish(struct net *net, struct tipc_uaddr *ua,
 					 struct tipc_socket_addr *sk, u32 key)
 {
 	struct name_table *nt = tipc_name_table(net);
+	u32 max_user_pub = TIPC_MAX_PUBL - 1;
 	struct tipc_net *tn = tipc_net(net);
 	struct publication *p = NULL;
 	struct sk_buff *skb = NULL;
+	bool protocol_type = false;
 	u32 rc_dests;
 
+	if (ua->sr.type == TIPC_NODE_STATE || ua->sr.type == TIPC_LINK_STATE ||
+	    ua->sr.type == TIPC_TOP_SRV)
+		protocol_type = true;
+
 	spin_lock_bh(&tn->nametbl_lock);
+	if (protocol_type)
+		goto insert;
 
-	if (nt->local_publ_count >= TIPC_MAX_PUBL) {
-		pr_warn("Bind failed, max limit %u reached\n", TIPC_MAX_PUBL);
+	/* Reserve one entry for node state service type because it has cluster
+	 * scope and it is distributed in bulk. So, the maximum number of user's
+	 * publications is (TIPC_MAX_PUBL - 1).
+	 */
+	if (nt->local_publ_count >= max_user_pub) {
+		pr_warn("Bind failed, max limit %u reached\n", max_user_pub);
 		goto exit;
 	}
 
+insert:
 	p = tipc_nametbl_insert_publ(net, ua, sk, key);
 	if (p) {
-		nt->local_publ_count++;
+		/* Not count node state, link state and topology server types
+		 * so that maximum nt->local_publ_count does not prevent
+		 * protocol service types from being inserted into the name
+		 * table.
+		 */
+		if (!protocol_type)
+			nt->local_publ_count++;
 		skb = tipc_named_publish(net, p);
 	}
 	rc_dests = nt->rc_dests;
@@ -810,7 +829,10 @@ void tipc_nametbl_withdraw(struct net *net, struct tipc_uaddr *ua,
 
 	p = tipc_nametbl_remove_publ(net, ua, sk, key);
 	if (p) {
-		nt->local_publ_count--;
+		if (p->sr.type != TIPC_NODE_STATE &&
+		    p->sr.type != TIPC_LINK_STATE &&
+		    p->sr.type != TIPC_TOP_SRV)
+			nt->local_publ_count--;
 		skb = tipc_named_withdraw(net, p);
 		list_del_init(&p->binding_sock);
 		kfree_rcu(p, rcu);
diff --git a/net/tipc/net.c b/net/tipc/net.c
index 7e65d0b0c4a8d..75ac4e3cd01a8 100644
--- a/net/tipc/net.c
+++ b/net/tipc/net.c
@@ -139,6 +139,11 @@ static void tipc_net_finalize(struct net *net, u32 addr)
 	tipc_sk_reinit(net);
 	tipc_mon_reinit_self(net);
 	tipc_nametbl_publish(net, &ua, &sk, addr);
+	atomic_set(&tn->finalized, 1);
+	/* Wake up nodes waiting for distributing bulk of publications
+	 * if applicable.
+	 */
+	tipc_node_wakeup(net);
 }
 
 void tipc_net_finalize_work(struct work_struct *work)
diff --git a/net/tipc/node.c b/net/tipc/node.c
index 8e4ef2630ae4f..334812bdab765 100644
--- a/net/tipc/node.c
+++ b/net/tipc/node.c
@@ -111,6 +111,9 @@ struct tipc_bclink_entry {
  * @peer_net: peer's net namespace
  * @peer_hash_mix: hash for this peer (FIXME)
  * @crypto_rx: RX crypto handler
+ * @work: work item for bulk distribution of cluster scope publications
+ * @work_scheduled: flag to indicate the work has been scheduled
+ * @finalized: flag to wake up scheduled work
  */
 struct tipc_node {
 	u32 addr;
@@ -145,6 +148,9 @@ struct tipc_node {
 #ifdef CONFIG_TIPC_CRYPTO
 	struct tipc_crypto *crypto_rx;
 #endif
+	struct work_struct work;
+	atomic_t work_scheduled;
+	atomic_t finalized;
 };
 
 /* Node FSM states and events:
@@ -393,6 +399,59 @@ static void tipc_node_write_unlock_fast(struct tipc_node *n)
 	write_unlock_bh(&n->lock);
 }
 
+static void tipc_node_down(struct tipc_node *n)
+{
+	int bearer_id;
+
+	for (bearer_id = 0; bearer_id < MAX_BEARERS; bearer_id++)
+		tipc_node_link_down(n, bearer_id, false);
+}
+
+static void tipc_node_dist_bulk(struct work_struct *work)
+{
+	struct tipc_node *node = container_of(work, struct tipc_node, work);
+	struct tipc_net *tn = tipc_net(node->net);
+
+	wait_var_event(&node->finalized, atomic_read(&node->finalized));
+
+	/* node is down */
+	if (!atomic_read(&node->work_scheduled))
+		goto exit;
+
+	/* Stop waking up work in tipc_node_timeout() */
+	atomic_set(&node->work_scheduled, 0);
+
+	if (tipc_named_dist_cluster_scope(node->net, node->addr) < 0)
+		tipc_node_down(node);
+
+exit:
+	if (atomic_dec_and_test(&tn->node_wq_count))
+		wake_up_var(&tn->node_wq_count);
+
+	tipc_node_put(node);
+}
+
+static void tipc_node_cancel_work(struct tipc_node *node)
+{
+	if (atomic_read(&node->work_scheduled)) {
+		struct tipc_net *tn = tipc_net(node->net);
+
+		/* Wake up scheduled work if it is waiting. */
+		if (!atomic_read(&node->finalized)) {
+			atomic_set(&node->work_scheduled, 0);
+			atomic_set(&node->finalized, 1);
+			wake_up_var(&node->finalized);
+		}
+
+		/* Work is pending */
+		if (cancel_work(&node->work)) {
+			if (atomic_dec_and_test(&tn->node_wq_count))
+				wake_up_var(&tn->node_wq_count);
+			tipc_node_put(node);
+		}
+	}
+}
+
 static void tipc_node_write_unlock(struct tipc_node *n)
 	__releases(n->lock)
 {
@@ -421,11 +480,32 @@ static void tipc_node_write_unlock(struct tipc_node *n)
 
 	write_unlock_bh(&n->lock);
 
-	if (flags & TIPC_NOTIFY_NODE_DOWN)
+	if (flags & TIPC_NOTIFY_NODE_DOWN) {
 		tipc_publ_notify(net, publ_list, node, n->capabilities);
-
-	if (flags & TIPC_NOTIFY_NODE_UP)
-		tipc_named_node_up(net, node, n->capabilities);
+		tipc_node_cancel_work(n);
+	}
+
+	if (flags & TIPC_NOTIFY_NODE_UP) {
+		struct tipc_net *tn = tipc_net(net);
+		int rc = 0;
+
+		rc = tipc_named_node_up(net, node, n->capabilities);
+		/* Defer bulk distribution to work queue */
+		if (rc > 0) {
+			atomic_set(&n->work_scheduled, 1);
+			atomic_inc(&tn->node_wq_count);
+			tipc_node_get(n);
+			if (!schedule_work(&n->work)) {
+				atomic_dec(&tn->node_wq_count);
+				tipc_node_put(n);
+			}
+		} else if (rc < 0) {
+			/* Bring the node down to start over bulk distribution
+			 * when the first link is up again.
+			 */
+			tipc_node_down(n);
+		}
+	}
 
 	if (flags & TIPC_NOTIFY_LINK_UP) {
 		tipc_mon_peer_up(net, node, bearer_id);
@@ -564,6 +644,9 @@ struct tipc_node *tipc_node_create(struct net *net, u32 addr, u8 *peer_id,
 	INIT_LIST_HEAD(&n->list);
 	INIT_LIST_HEAD(&n->publ_list);
 	INIT_LIST_HEAD(&n->conn_sks);
+	INIT_WORK(&n->work, tipc_node_dist_bulk);
+	atomic_set(&n->work_scheduled, 0);
+	atomic_set(&n->finalized, 0);
 	skb_queue_head_init(&n->bc_entry.namedq);
 	skb_queue_head_init(&n->bc_entry.inputq1);
 	__skb_queue_head_init(&n->bc_entry.arrvq);
@@ -653,6 +736,21 @@ void tipc_node_stop(struct net *net)
 	spin_unlock_bh(&tn->node_list_lock);
 }
 
+void tipc_node_wakeup(struct net *net)
+{
+	struct tipc_net *tn = tipc_net(net);
+	struct tipc_node *node;
+
+	rcu_read_lock();
+	list_for_each_entry_rcu(node, &tn->node_list, list) {
+		if (atomic_read(&node->work_scheduled)) {
+			atomic_set(&node->finalized, 1);
+			wake_up_var(&node->finalized);
+		}
+	}
+	rcu_read_unlock();
+}
+
 void tipc_node_subscribe(struct net *net, struct list_head *subscr, u32 addr)
 {
 	struct tipc_node *n;
@@ -801,6 +899,7 @@ static bool tipc_node_cleanup(struct tipc_node *peer)
 static void tipc_node_timeout(struct timer_list *t)
 {
 	struct tipc_node *n = timer_container_of(n, t, timer);
+	struct tipc_net *tn = tipc_net(n->net);
 	struct tipc_link_entry *le;
 	struct sk_buff_head xmitq;
 	int remains = n->link_cnt;
@@ -814,6 +913,11 @@ static void tipc_node_timeout(struct timer_list *t)
 		return;
 	}
 
+	if (atomic_read(&tn->finalized) && atomic_read(&n->work_scheduled)) {
+		atomic_set(&n->finalized, 1);
+		wake_up_var(&n->finalized);
+	}
+
 #ifdef CONFIG_TIPC_CRYPTO
 	/* Take any crypto key related actions first */
 	tipc_crypto_timeout(n->crypto_rx);
diff --git a/net/tipc/node.h b/net/tipc/node.h
index 154a5bbb0d29d..c7bc3bc053285 100644
--- a/net/tipc/node.h
+++ b/net/tipc/node.h
@@ -75,6 +75,7 @@ enum {
 #define INVALID_BEARER_ID -1
 
 void tipc_node_stop(struct net *net);
+void tipc_node_wakeup(struct net *net);
 bool tipc_node_get_id(struct net *net, u32 addr, u8 *id);
 u32 tipc_node_get_addr(struct tipc_node *node);
 char *tipc_node_get_id_str(struct tipc_node *node);

3/2 2026/07/31 19:29 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 7973
							output: 30
							thoughts: 371
						

Thoughts:
**Analyzing a TIPC Patch for the Linux Kernel**

Okay, so I've got this patch here that's poking around in the TIPC subsystem of the Linux kernel. It touches quite a few files: `core.c`, `core.h`, `name_distr.c`, `name_distr.h`, `name_table.c`, `net.c`, `node.c`, and `node.h`. Seems like a pretty significant area of the code.

My initial thought is to dive right in and understand what's actually changing. Right off the bat, it looks like this patch introduces a workqueue specifically for efficiently distributing publications across the cluster scope, which is interesting. It also appears we're adding some atomic variables, `node_wq_count` and `finalized`, to the `tipc_net` structure. The change to `tipc_named_node_up` to return an integer instead of void immediately raises my eyebrows – that's often a signal of a behavioral change or error reporting being added. We have a new function, `tipc_named_dist_cluster_scope`, which could be tied to the workqueue. Also, the modifications to `tipc_nametbl_publish` to manage `protocol_type` and reserve an entry for the node state service type are notable. Plus, a new work function, `tipc_node_dist_bulk`, is being added, also in `node.c`. The changes to `tipc_node_write_unlock` indicate that the workqueue is triggered if `tipc_named_node_up` reports a positive value. And finally, we have a new function, `tipc_node_wakeup`.

Alright, putting it all together, this looks like a functional change to the TIPC implementation. And given the nature of TIPC, which is accessible in virtualized environments, this definitely warrants some serious fuzzing. Security is paramount, and these types of changes are prime targets for vulnerability discovery.

Now, let's nail down those CONFIG options. I remember TIPC is controlled by `CONFIG_TIPC`. Let me just double-check that in `net/tipc/Kconfig` to be sure I have the whole picture before going any further.



4/2 2026/07/31 19:29 tool grepper
0m Args:
{
  "Expression": "config TIPC",
  "PathPrefix": "net/tipc/Kconfig"
}

Results:
{
  "Output": "net/tipc/Kconfig-5-\nnet/tipc/Kconfig:6:menuconfig TIPC\nnet/tipc/Kconfig-7-\ttristate \"The TIPC Protocol\"\n--\nnet/tipc/Kconfig-23-\nnet/tipc/Kconfig:24:config TIPC_MEDIA_IB\nnet/tipc/Kconfig-25-\tbool \"InfiniBand media type support\"\n--\nnet/tipc/Kconfig-29-\t  IP-over-InfiniBand devices.\nnet/tipc/Kconfig:30:config TIPC_MEDIA_UDP\nnet/tipc/Kconfig-31-\tbool \"IP/UDP media type support\"\n--\nnet/tipc/Kconfig-37-\nnet/tipc/Kconfig:38:config TIPC_CRYPTO\nnet/tipc/Kconfig-39-\tbool \"TIPC encryption support\"\n--\nnet/tipc/Kconfig-52-\nnet/tipc/Kconfig:53:config TIPC_DIAG\nnet/tipc/Kconfig-54-\ttristate \"TIPC: socket monitoring interface\"\n"
}

5/2 2026/07/31 19:29 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 9143
							output: 29
							thoughts: 29
						

Thoughts:
Okay, here's my take on those thoughts, framed as my own mental process, given my expertise:

**Checking the TIPC Configuration**

Alright, let's get down to it. `CONFIG_TIPC` is clearly the central configuration option we're dealing with here, that's obvious. Now the crucial step is to quickly determine its dependencies. I need to understand what other kernel features, options, or even other modules need to be enabled or are affected if `CONFIG_TIPC` is enabled or disabled. This is where the efficiency of my workflow comes in, I can’t spend time on the basics – I'm looking for the non-obvious relationships, any potential conflicts, and the broader implications for the system. I need to immediately understand the entire landscape. Time to dig in and see what's actually connected to it.



6/2 2026/07/31 19:29 tool grepper
0m Args:
{
  "Expression": "depends on",
  "PathPrefix": "net/tipc/Kconfig"
}

Results:
{
  "Output": "net/tipc/Kconfig=6=menuconfig TIPC\nnet/tipc/Kconfig-7-\ttristate \"The TIPC Protocol\"\nnet/tipc/Kconfig:8:\tdepends on INET\nnet/tipc/Kconfig-9-\thelp\n--\nnet/tipc/Kconfig=24=config TIPC_MEDIA_IB\nnet/tipc/Kconfig-25-\tbool \"InfiniBand media type support\"\nnet/tipc/Kconfig:26:\tdepends on TIPC \u0026\u0026 INFINIBAND_IPOIB\nnet/tipc/Kconfig-27-\thelp\n--\nnet/tipc/Kconfig=30=config TIPC_MEDIA_UDP\nnet/tipc/Kconfig-31-\tbool \"IP/UDP media type support\"\nnet/tipc/Kconfig:32:\tdepends on TIPC\nnet/tipc/Kconfig-33-\tselect NET_UDP_TUNNEL\n--\nnet/tipc/Kconfig=38=config TIPC_CRYPTO\nnet/tipc/Kconfig-39-\tbool \"TIPC encryption support\"\nnet/tipc/Kconfig:40:\tdepends on TIPC\nnet/tipc/Kconfig-41-\tselect CRYPTO\n--\nnet/tipc/Kconfig=53=config TIPC_DIAG\nnet/tipc/Kconfig-54-\ttristate \"TIPC: socket monitoring interface\"\nnet/tipc/Kconfig:55:\tdepends on TIPC\nnet/tipc/Kconfig-56-\tdefault y\n"
}

7/2 2026/07/31 19:29 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 9767
							output: 69
							thoughts: 428
						

Thoughts:
**Analyzing the TIPC Configuration for Focus Symbols**

Okay, so `TIPC` depends on `INET`, that's our starting point. We need to zero in on the relevant configuration. Looking at the patch, the code modifies a bunch of functions. Now, which ones are key?

The patch seems to be touching `tipc_init_net`, `tipc_exit_net`, `named_distribute`, `tipc_named_distribute`, `tipc_named_node_up`, `tipc_named_dist_cluster_scope`, `tipc_nametbl_publish`, `tipc_nametbl_withdraw`, `tipc_net_finalize`, `tipc_node_down`, `tipc_node_dist_bulk`, `tipc_node_cancel_work`, `tipc_node_write_unlock`, `tipc_node_create`, `tipc_node_wakeup`, and `tipc_node_timeout`. That's a lot, but we can definitely narrow it down.

Let's focus on the functions I suspect are most central to the changes: `tipc_named_node_up`, `tipc_named_dist_cluster_scope`, `tipc_nametbl_publish`, `tipc_nametbl_withdraw`, `tipc_node_dist_bulk`, and `tipc_node_wakeup`.

Now, the important question – are these functions static or exported? Let's check. Aha, `tipc_named_node_up`, `tipc_named_dist_cluster_scope`, `tipc_nametbl_publish`, `tipc_nametbl_withdraw`, and `tipc_node_wakeup` are global, which is what we need to focus on. `tipc_node_dist_bulk` is *static*, so it's not going to be a good symbol.

Now, let's go check the relevant source files: `net/tipc/name_distr.c` and `net/tipc/node.c`.



8/2 2026/07/31 19:29 tool grepper
0m Args:
{
  "Expression": "tipc_named_node_up|tipc_named_dist_cluster_scope|tipc_nametbl_publish|tipc_nametbl_withdraw|tipc_node_wakeup",
  "PathPrefix": "net/tipc/"
}

Results:
{
  "Output": "net/tipc/name_distr.c=208=static int tipc_named_distribute(struct net *net, u32 dnode)\n--\nnet/tipc/name_distr.c-231-/**\nnet/tipc/name_distr.c:232: * tipc_named_node_up - tell specified node about all publications by this node\nnet/tipc/name_distr.c-233- * @net: the associated network namespace\n--\nnet/tipc/name_distr.c-236- */\nnet/tipc/name_distr.c:237:int tipc_named_node_up(struct net *net, u32 dnode, u16 capabilities)\nnet/tipc/name_distr.c-238-{\n--\nnet/tipc/name_distr.c-249-\t *    teardown.\nnet/tipc/name_distr.c:250:\t * 2. Or tipc_net_finalize() ---\u003e tipc_nametbl_publish() has failed\nnet/tipc/name_distr.c-251-\t *    to insert node self address publication into nt-\u003ecluster_scope\nnet/tipc/name_distr.c-252-\t *    due to memory allocation failure.\nnet/tipc/name_distr.c:253:\t * 3. Or tipc_net_finalize() ---\u003e tipc_nametbl_publish() has not\nnet/tipc/name_distr.c-254-\t *    executed yet.\n--\nnet/tipc/name_distr.c-265-/**\nnet/tipc/name_distr.c:266: * tipc_named_dist_cluster_scope - distribute all publications to specified node\nnet/tipc/name_distr.c-267- * @net: the associated network namespace\n--\nnet/tipc/name_distr.c-269- */\nnet/tipc/name_distr.c:270:int tipc_named_dist_cluster_scope(struct net *net, u32 dnode)\nnet/tipc/name_distr.c-271-{\n--\nnet/tipc/name_distr.c-278-\tread_unlock_bh(\u0026nt-\u003ecluster_scope_lock);\nnet/tipc/name_distr.c:279:\t/* tipc_net_finalize() ---\u003e tipc_nametbl_publish() has failed to insert\nnet/tipc/name_distr.c-280-\t * node self address publication into nt-\u003ecluster_scope due to memory\n--\nnet/tipc/name_distr.c-291-\t\t\t   TIPC_NODE_STATE, tn-\u003enode_addr, tn-\u003enode_addr);\nnet/tipc/name_distr.c:292:\t\tif (!tipc_nametbl_publish(net, \u0026ua, \u0026sk, tn-\u003enode_addr))\nnet/tipc/name_distr.c-293-\t\t\treturn -ENOBUFS;\n--\nnet/tipc/name_distr.h=71=struct sk_buff *tipc_named_withdraw(struct net *net, struct publication *publ);\nnet/tipc/name_distr.h:72:int tipc_named_node_up(struct net *net, u32 dnode, u16 capabilities);\nnet/tipc/name_distr.h:73:int tipc_named_dist_cluster_scope(struct net *net, u32 dnode);\nnet/tipc/name_distr.h-74-void tipc_named_rcv(struct net *net, struct sk_buff_head *namedq,\n--\nnet/tipc/name_table.c=732=void tipc_nametbl_build_group(struct net *net, struct tipc_group *grp,\n--\nnet/tipc/name_table.c-759-\nnet/tipc/name_table.c:760:/* tipc_nametbl_publish - add service binding to name table\nnet/tipc/name_table.c-761- */\nnet/tipc/name_table.c:762:struct publication *tipc_nametbl_publish(struct net *net, struct tipc_uaddr *ua,\nnet/tipc/name_table.c-763-\t\t\t\t\t struct tipc_socket_addr *sk, u32 key)\n--\nnet/tipc/name_table.c-812-/**\nnet/tipc/name_table.c:813: * tipc_nametbl_withdraw - withdraw a service binding\nnet/tipc/name_table.c-814- * @net: network namespace\n--\nnet/tipc/name_table.c-818- */\nnet/tipc/name_table.c:819:void tipc_nametbl_withdraw(struct net *net, struct tipc_uaddr *ua,\nnet/tipc/name_table.c-820-\t\t\t   struct tipc_socket_addr *sk, u32 key)\n--\nnet/tipc/name_table.h=126=void tipc_nametbl_build_group(struct net *net, struct tipc_group *grp,\nnet/tipc/name_table.h-127-\t\t\t      struct tipc_uaddr *ua);\nnet/tipc/name_table.h:128:struct publication *tipc_nametbl_publish(struct net *net, struct tipc_uaddr *ua,\nnet/tipc/name_table.h-129-\t\t\t\t\t struct tipc_socket_addr *sk, u32 key);\nnet/tipc/name_table.h:130:void tipc_nametbl_withdraw(struct net *net, struct tipc_uaddr *ua,\nnet/tipc/name_table.h-131-\t\t\t   struct tipc_socket_addr *sk, u32 key);\n--\nnet/tipc/net.c=126=static void tipc_net_finalize(struct net *net, u32 addr)\n--\nnet/tipc/net.c-140-\ttipc_mon_reinit_self(net);\nnet/tipc/net.c:141:\ttipc_nametbl_publish(net, \u0026ua, \u0026sk, addr);\nnet/tipc/net.c-142-\tatomic_set(\u0026tn-\u003efinalized, 1);\n--\nnet/tipc/net.c-145-\t */\nnet/tipc/net.c:146:\ttipc_node_wakeup(net);\nnet/tipc/net.c-147-}\n--\nnet/tipc/node.c=410=static void tipc_node_dist_bulk(struct work_struct *work)\n--\nnet/tipc/node.c-423-\nnet/tipc/node.c:424:\tif (tipc_named_dist_cluster_scope(node-\u003enet, node-\u003eaddr) \u003c 0)\nnet/tipc/node.c-425-\t\ttipc_node_down(node);\n--\nnet/tipc/node.c=455=static void tipc_node_write_unlock(struct tipc_node *n)\n--\nnet/tipc/node.c-491-\nnet/tipc/node.c:492:\t\trc = tipc_named_node_up(net, node, n-\u003ecapabilities);\nnet/tipc/node.c-493-\t\t/* Defer bulk distribution to work queue */\n--\nnet/tipc/node.c-511-\t\ttipc_mon_peer_up(net, node, bearer_id);\nnet/tipc/node.c:512:\t\ttipc_nametbl_publish(net, \u0026ua, \u0026sk, sk.ref);\nnet/tipc/node.c-513-\t}\n--\nnet/tipc/node.c-515-\t\ttipc_mon_peer_down(net, node, bearer_id);\nnet/tipc/node.c:516:\t\ttipc_nametbl_withdraw(net, \u0026ua, \u0026sk, sk.ref);\nnet/tipc/node.c-517-\t}\n--\nnet/tipc/node.c=728=void tipc_node_stop(struct net *net)\n--\nnet/tipc/node.c-738-\nnet/tipc/node.c:739:void tipc_node_wakeup(struct net *net)\nnet/tipc/node.c-740-{\n--\nnet/tipc/node.h=77=void tipc_node_stop(struct net *net);\nnet/tipc/node.h:78:void tipc_node_wakeup(struct net *net);\nnet/tipc/node.h-79-bool tipc_node_get_id(struct net *net, u32 addr, u8 *id);\n--\nnet/tipc/socket.c=2907=static int tipc_sk_publish(struct tipc_sock *tsk, struct tipc_uaddr *ua)\n--\nnet/tipc/socket.c-2921-\tskaddr.node = tipc_own_addr(net);\nnet/tipc/socket.c:2922:\tp = tipc_nametbl_publish(net, ua, \u0026skaddr, key);\nnet/tipc/socket.c-2923-\tif (unlikely(!p))\n--\nnet/tipc/socket.c=2932=static int tipc_sk_withdraw(struct tipc_sock *tsk, struct tipc_uaddr *ua)\n--\nnet/tipc/socket.c-2942-\t\t\t\t   p-\u003esr.type, p-\u003esr.lower, p-\u003esr.upper);\nnet/tipc/socket.c:2943:\t\t\ttipc_nametbl_withdraw(net, \u0026_ua, \u0026p-\u003esk, p-\u003ekey);\nnet/tipc/socket.c-2944-\t\t\tcontinue;\n--\nnet/tipc/socket.c-2954-\t\t\tbreak;\nnet/tipc/socket.c:2955:\t\ttipc_nametbl_withdraw(net, ua, \u0026p-\u003esk, p-\u003ekey);\nnet/tipc/socket.c-2956-\t\trc = 0;\n"
}

9/2 2026/07/31 19:29 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 13318
							output: 145
							thoughts: 227
						

Thoughts:
**Fuzzing Target Assessment: TIPC Functions**

Okay, so I've been looking at this patch and the associated symbols. My initial assessment is that this is definitely something worth pursuing with fuzzing. The key functions to target are: `tipc_named_node_up`, `tipc_named_dist_cluster_scope`, `tipc_nametbl_publish`, `tipc_nametbl_withdraw`, and `tipc_node_wakeup`. They're all exported, so that makes things straightforward from a fuzzing perspective.

I needed to confirm the required configuration and initially I thought it was just `TIPC`, but I wanted to make sure there weren't any other dependencies that I was missing. It looks like `CONFIG_TIPC` is the primary one, and thankfully it can be built-in, which is what we usually want for syzkaller.

I did a second pass through the patch to see if I had missed anything. There's a `#ifdef CONFIG_TIPC_CRYPTO` in the surrounding code, but the patch itself doesn't seem to depend on it. So, yeah, it looks like `TIPC` alone is sufficient for this one.

Alright, with that confirmed, I think we're good to call `set-results` and move forward with this.



10/2 2026/07/31 19:30 tool set-results
0m Args:
{
  "EnableConfigs": [
    "TIPC"
  ],
  "FocusSymbols": [
    "tipc_named_node_up",
    "tipc_named_dist_cluster_scope",
    "tipc_nametbl_publish",
    "tipc_nametbl_withdraw",
    "tipc_node_wakeup"
  ],
  "Reasoning": "The patch introduces a workqueue for bulk distribution of cluster scope publications in TIPC, modifying core protocol logic such as node state management and name table publishing. This is a functional change to the TIPC subsystem, which is reachable in virtualized environments and should be fuzzed.",
  "WorthFuzzing": true
}

Results:
{
  "EnableConfigs": [
    "TIPC"
  ],
  "FocusSymbols": [
    "tipc_named_node_up",
    "tipc_named_dist_cluster_scope",
    "tipc_nametbl_publish",
    "tipc_nametbl_withdraw",
    "tipc_node_wakeup"
  ],
  "Reasoning": "The patch introduces a workqueue for bulk distribution of cluster scope publications in TIPC, modifying core protocol logic such as node state management and name table publishing. This is a functional change to the TIPC subsystem, which is reachable in virtualized environments and should be fuzzed.",
  "WorthFuzzing": true
}

LLM Calls Summary:
Total Calls Total Tokens Avg Tokens Total Duration (Seconds) Avg Duration (Seconds)
Tool Calls Summary:
Total Calls Total Duration (Seconds) Avg Duration (Seconds)