| Seq | Timestamp | Type | Name | Duration |
|---|---|---|---|---|
| 0/0 | 2026/07/25 21:17 | flow | patch-triage |
1mArgs:null Results: {
"EnableConfigs": [
"NETCONSOLE",
"NETCONSOLE_DYNAMIC",
"CONFIGFS_FS",
"IPV6"
],
"FocusSymbols": [
"netcons_netpoll_setup",
"netcons_take_ipv4",
"netcons_take_ipv6",
"enabled_store",
"local_ip_store",
"remote_ip_store",
"alloc_param_target",
"netconsole_parser_cmdline",
"netpoll_send_udp"
],
"Reasoning": "The patch refactors netconsole and netpoll by moving IP address configuration and setup logic from the generic netpoll structure to the netconsole target. It introduces new functions like `netcons_netpoll_setup`, `netcons_take_ipv4`, and `netcons_take_ipv6`. These changes are functional and reachable via configfs (dynamic netconsole) and module parameters, making them suitable for fuzzing.",
"WorthFuzzing": true
} |
| 1/1 | 2026/07/25 21:17 | action | read-patch-diff |
0mArgs:null Results: {
"PatchDiff": "commit e4812b784fd541acde4b6399949b064364b4c43f\nAuthor: syz-cluster \u003ctriage@syzkaller.com\u003e\nDate: Sat Jul 25 21:17:16 2026 +0000\n\n syz-cluster: applied patch under review\n\ndiff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c\nindex 7f8851a734fcd0..03913302328ccd 100644\n--- a/drivers/net/netconsole.c\n+++ b/drivers/net/netconsole.c\n@@ -37,8 +37,10 @@\n #include \u003clinux/udp.h\u003e\n #include \u003clinux/netpoll.h\u003e\n #include \u003clinux/inet.h\u003e\n+#include \u003clinux/inetdevice.h\u003e\n #include \u003clinux/unaligned.h\u003e\n #include \u003cnet/ip6_checksum.h\u003e\n+#include \u003cnet/addrconf.h\u003e\n #include \u003clinux/configfs.h\u003e\n #include \u003clinux/etherdevice.h\u003e\n #include \u003clinux/hex.h\u003e\n@@ -46,6 +48,7 @@\n #include \u003clinux/utsname.h\u003e\n #include \u003clinux/rtnetlink.h\u003e\n #include \u003clinux/workqueue.h\u003e\n+#include \u003clinux/delay.h\u003e\n \n MODULE_AUTHOR(\"Matt Mackall \u003cmpm@selenic.com\u003e\");\n MODULE_DESCRIPTION(\"Console driver for network interfaces\");\n@@ -175,9 +178,10 @@ enum target_state {\n * @np:\t\tThe netpoll structure for this target.\n *\t\tContains the other userspace visible parameters:\n *\t\tdev_name\t(read-write)\n- *\t\tlocal_ip\t(read-write)\n- *\t\tremote_ip\t(read-write)\n *\t\tlocal_mac\t(read-only)\n+ * @local_ip:\tSource IP address of the target (read-write).\n+ * @remote_ip:\tDestination IP address of the target (read-write).\n+ * @ipv6:\tWhether the target addresses are IPv6 (read-write).\n * @local_port:\tSource UDP port of the target (read-write).\n * @remote_port: Destination UDP port of the target (read-write).\n * @remote_mac:\tDestination ethernet address of the target (read-write).\n@@ -208,6 +212,8 @@ struct netconsole_target {\n \tbool\t\t\textended;\n \tbool\t\t\trelease;\n \tstruct netpoll\t\tnp;\n+\tunion inet_addr\t\tlocal_ip, remote_ip;\n+\tbool\t\t\tipv6;\n \tu16\t\t\tlocal_port, remote_port;\n \tu8\t\t\tremote_mac[ETH_ALEN];\n \t/* protected by target_list_lock; +1 gives scnprintf() room for its\n@@ -351,6 +357,208 @@ static void netconsole_skb_pool_flush(struct netconsole_target *nt)\n \tskb_queue_purge_reason(\u0026nt-\u003eskb_pool, SKB_CONSUMED);\n }\n \n+static void netcons_wait_carrier(struct netpoll *np, struct net_device *ndev)\n+{\n+\tunsigned long atmost;\n+\n+\tatmost = jiffies + netpoll_get_carrier_timeout() * HZ;\n+\twhile (!netif_carrier_ok(ndev)) {\n+\t\tif (time_after(jiffies, atmost)) {\n+\t\t\tnp_notice(np, \"timeout waiting for carrier\\n\");\n+\t\t\tbreak;\n+\t\t}\n+\t\tmsleep(1);\n+\t}\n+}\n+\n+/*\n+ * Returns a pointer to a string representation of the identifier used\n+ * to select the egress interface for the given netpoll instance. buf\n+ * is used to format np-\u003edev_mac when np-\u003edev_name is empty; bufsz must\n+ * be at least MAC_ADDR_STR_LEN + 1 to fit the formatted MAC address\n+ * and its NUL terminator.\n+ */\n+static char *netcons_egress_dev(struct netpoll *np, char *buf, size_t bufsz)\n+{\n+\tif (np-\u003edev_name[0])\n+\t\treturn np-\u003edev_name;\n+\n+\tsnprintf(buf, bufsz, \"%pM\", np-\u003edev_mac);\n+\treturn buf;\n+}\n+\n+/*\n+ * Populate the target's local_ip with the IPv6 address from ndev.\n+ */\n+static int netcons_take_ipv6(struct netconsole_target *nt,\n+\t\t\t struct net_device *ndev)\n+{\n+\tchar buf[MAC_ADDR_STR_LEN + 1];\n+\tstruct netpoll *np = \u0026nt-\u003enp;\n+\tint err = -EDESTADDRREQ;\n+\tstruct inet6_dev *idev;\n+\n+\tif (!IS_ENABLED(CONFIG_IPV6)) {\n+\t\tnp_err(np, \"IPv6 is not supported %s, aborting\\n\",\n+\t\t netcons_egress_dev(np, buf, sizeof(buf)));\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tidev = __in6_dev_get(ndev);\n+\tif (idev) {\n+\t\tstruct inet6_ifaddr *ifp;\n+\n+\t\tread_lock_bh(\u0026idev-\u003elock);\n+\t\tlist_for_each_entry(ifp, \u0026idev-\u003eaddr_list, if_list) {\n+\t\t\tif (!!(ipv6_addr_type(\u0026ifp-\u003eaddr) \u0026 IPV6_ADDR_LINKLOCAL) !=\n+\t\t\t\t!!(ipv6_addr_type(\u0026nt-\u003eremote_ip.in6) \u0026 IPV6_ADDR_LINKLOCAL))\n+\t\t\t\tcontinue;\n+\t\t\t/* Got the IP, let's return */\n+\t\t\tnt-\u003elocal_ip.in6 = ifp-\u003eaddr;\n+\t\t\terr = 0;\n+\t\t\tbreak;\n+\t\t}\n+\t\tread_unlock_bh(\u0026idev-\u003elock);\n+\t}\n+\tif (err) {\n+\t\tnp_err(np, \"no IPv6 address for %s, aborting\\n\",\n+\t\t netcons_egress_dev(np, buf, sizeof(buf)));\n+\t\treturn err;\n+\t}\n+\n+\tnp_info(np, \"local IPv6 %pI6c\\n\", \u0026nt-\u003elocal_ip.in6);\n+\treturn 0;\n+}\n+\n+/*\n+ * Populate the target's local_ip with the IPv4 address from ndev.\n+ */\n+static int netcons_take_ipv4(struct netconsole_target *nt,\n+\t\t\t struct net_device *ndev)\n+{\n+\tchar buf[MAC_ADDR_STR_LEN + 1];\n+\tstruct netpoll *np = \u0026nt-\u003enp;\n+\tconst struct in_ifaddr *ifa;\n+\tstruct in_device *in_dev;\n+\n+\tin_dev = __in_dev_get_rtnl(ndev);\n+\tif (!in_dev) {\n+\t\tnp_err(np, \"no IP address for %s, aborting\\n\",\n+\t\t netcons_egress_dev(np, buf, sizeof(buf)));\n+\t\treturn -EDESTADDRREQ;\n+\t}\n+\n+\tifa = rtnl_dereference(in_dev-\u003eifa_list);\n+\tif (!ifa) {\n+\t\tnp_err(np, \"no IP address for %s, aborting\\n\",\n+\t\t netcons_egress_dev(np, buf, sizeof(buf)));\n+\t\treturn -EDESTADDRREQ;\n+\t}\n+\n+\tnt-\u003elocal_ip.ip = ifa-\u003eifa_local;\n+\tnp_info(np, \"local IP %pI4\\n\", \u0026nt-\u003elocal_ip.ip);\n+\n+\treturn 0;\n+}\n+\n+/*\n+ * Test whether the caller left nt-\u003elocal_ip unset, so that\n+ * netcons_netpoll_setup() should auto-populate it from the egress device.\n+ *\n+ * nt-\u003elocal_ip is a union of __be32 (IPv4) and struct in6_addr (IPv6),\n+ * so an IPv6 address whose first 4 bytes are zero (e.g. ::1, ::2,\n+ * IPv4-mapped ::ffff:a.b.c.d) must not be tested via the IPv4 arm —\n+ * doing so would misclassify a caller-supplied address as unset and\n+ * silently overwrite it with whatever address the device exposes.\n+ */\n+static bool netcons_local_ip_unset(const struct netconsole_target *nt)\n+{\n+\tif (nt-\u003eipv6)\n+\t\treturn ipv6_addr_any(\u0026nt-\u003elocal_ip.in6);\n+\treturn !nt-\u003elocal_ip.ip;\n+}\n+\n+static int netcons_netpoll_setup(struct netconsole_target *nt)\n+{\n+\tstruct net *net = current-\u003ensproxy-\u003enet_ns;\n+\tchar buf[MAC_ADDR_STR_LEN + 1];\n+\tstruct net_device *ndev = NULL;\n+\tstruct netpoll *np = \u0026nt-\u003enp;\n+\tbool ip_overwritten = false;\n+\tint err;\n+\n+\trtnl_lock();\n+\tif (np-\u003edev_name[0])\n+\t\tndev = __dev_get_by_name(net, np-\u003edev_name);\n+\telse if (is_valid_ether_addr(np-\u003edev_mac))\n+\t\tndev = dev_getbyhwaddr(net, ARPHRD_ETHER, np-\u003edev_mac);\n+\n+\tif (!ndev) {\n+\t\tnp_err(np, \"%s doesn't exist, aborting\\n\",\n+\t\t netcons_egress_dev(np, buf, sizeof(buf)));\n+\t\terr = -ENODEV;\n+\t\tgoto unlock;\n+\t}\n+\tnetdev_hold(ndev, \u0026np-\u003edev_tracker, GFP_KERNEL);\n+\n+\tif (netdev_master_upper_dev_get(ndev)) {\n+\t\tnp_err(np, \"%s is a slave device, aborting\\n\",\n+\t\t netcons_egress_dev(np, buf, sizeof(buf)));\n+\t\terr = -EBUSY;\n+\t\tgoto put;\n+\t}\n+\n+\tif (!netif_running(ndev)) {\n+\t\tnp_info(np, \"device %s not up yet, forcing it\\n\",\n+\t\t\tnetcons_egress_dev(np, buf, sizeof(buf)));\n+\n+\t\terr = dev_open(ndev, NULL);\n+\t\tif (err) {\n+\t\t\tnp_err(np, \"failed to open %s\\n\", ndev-\u003ename);\n+\t\t\tgoto put;\n+\t\t}\n+\n+\t\trtnl_unlock();\n+\t\tnetcons_wait_carrier(np, ndev);\n+\t\trtnl_lock();\n+\t}\n+\n+\tif (netcons_local_ip_unset(nt)) {\n+\t\tif (!nt-\u003eipv6) {\n+\t\t\terr = netcons_take_ipv4(nt, ndev);\n+\t\t\tif (err)\n+\t\t\t\tgoto put;\n+\t\t} else {\n+\t\t\terr = netcons_take_ipv6(nt, ndev);\n+\t\t\tif (err)\n+\t\t\t\tgoto put;\n+\t\t}\n+\t\tip_overwritten = true;\n+\t}\n+\n+\terr = __netpoll_setup(np, ndev);\n+\tif (err)\n+\t\tgoto put;\n+\trtnl_unlock();\n+\n+\t/* Make sure all NAPI polls which started before dev-\u003enpinfo\n+\t * was visible have exited before we start calling NAPI poll.\n+\t * NAPI skips locking if dev-\u003enpinfo is NULL.\n+\t */\n+\tsynchronize_rcu();\n+\n+\treturn 0;\n+\n+put:\n+\tDEBUG_NET_WARN_ON_ONCE(np-\u003edev);\n+\tif (ip_overwritten)\n+\t\tmemset(\u0026nt-\u003elocal_ip, 0, sizeof(nt-\u003elocal_ip));\n+\tnetdev_put(ndev, \u0026np-\u003edev_tracker);\n+unlock:\n+\trtnl_unlock();\n+\treturn err;\n+}\n+\n /* Attempts to resume logging to a deactivated target. */\n static void resume_target(struct netconsole_target *nt)\n {\n@@ -361,7 +569,7 @@ static void resume_target(struct netconsole_target *nt)\n \t */\n \tnetconsole_skb_pool_init(nt);\n \n-\tif (netpoll_setup(\u0026nt-\u003enp)) {\n+\tif (netcons_netpoll_setup(nt)) {\n \t\t/* netpoll fails setup once, do not try again. */\n \t\tnetconsole_skb_pool_flush(nt);\n \t\tnt-\u003estate = STATE_DISABLED;\n@@ -506,17 +714,17 @@ static void netconsole_print_banner(struct netconsole_target *nt)\n \tstruct netpoll *np = \u0026nt-\u003enp;\n \n \tnp_info(np, \"local port %d\\n\", nt-\u003elocal_port);\n-\tif (np-\u003eipv6)\n-\t\tnp_info(np, \"local IPv6 address %pI6c\\n\", \u0026np-\u003elocal_ip.in6);\n+\tif (nt-\u003eipv6)\n+\t\tnp_info(np, \"local IPv6 address %pI6c\\n\", \u0026nt-\u003elocal_ip.in6);\n \telse\n-\t\tnp_info(np, \"local IPv4 address %pI4\\n\", \u0026np-\u003elocal_ip.ip);\n+\t\tnp_info(np, \"local IPv4 address %pI4\\n\", \u0026nt-\u003elocal_ip.ip);\n \tnp_info(np, \"interface name '%s'\\n\", np-\u003edev_name);\n \tnp_info(np, \"local ethernet address '%pM'\\n\", np-\u003edev_mac);\n \tnp_info(np, \"remote port %d\\n\", nt-\u003eremote_port);\n-\tif (np-\u003eipv6)\n-\t\tnp_info(np, \"remote IPv6 address %pI6c\\n\", \u0026np-\u003eremote_ip.in6);\n+\tif (nt-\u003eipv6)\n+\t\tnp_info(np, \"remote IPv6 address %pI6c\\n\", \u0026nt-\u003eremote_ip.in6);\n \telse\n-\t\tnp_info(np, \"remote IPv4 address %pI4\\n\", \u0026np-\u003eremote_ip.ip);\n+\t\tnp_info(np, \"remote IPv4 address %pI4\\n\", \u0026nt-\u003eremote_ip.ip);\n \tnp_info(np, \"remote ethernet address %pM\\n\", nt-\u003eremote_mac);\n }\n \n@@ -647,20 +855,20 @@ static ssize_t local_ip_show(struct config_item *item, char *buf)\n {\n \tstruct netconsole_target *nt = to_target(item);\n \n-\tif (nt-\u003enp.ipv6)\n-\t\treturn sysfs_emit(buf, \"%pI6c\\n\", \u0026nt-\u003enp.local_ip.in6);\n+\tif (nt-\u003eipv6)\n+\t\treturn sysfs_emit(buf, \"%pI6c\\n\", \u0026nt-\u003elocal_ip.in6);\n \telse\n-\t\treturn sysfs_emit(buf, \"%pI4\\n\", \u0026nt-\u003enp.local_ip);\n+\t\treturn sysfs_emit(buf, \"%pI4\\n\", \u0026nt-\u003elocal_ip);\n }\n \n static ssize_t remote_ip_show(struct config_item *item, char *buf)\n {\n \tstruct netconsole_target *nt = to_target(item);\n \n-\tif (nt-\u003enp.ipv6)\n-\t\treturn sysfs_emit(buf, \"%pI6c\\n\", \u0026nt-\u003enp.remote_ip.in6);\n+\tif (nt-\u003eipv6)\n+\t\treturn sysfs_emit(buf, \"%pI6c\\n\", \u0026nt-\u003eremote_ip.in6);\n \telse\n-\t\treturn sysfs_emit(buf, \"%pI4\\n\", \u0026nt-\u003enp.remote_ip);\n+\t\treturn sysfs_emit(buf, \"%pI4\\n\", \u0026nt-\u003eremote_ip);\n }\n \n static ssize_t local_mac_show(struct config_item *item, char *buf)\n@@ -840,7 +1048,7 @@ static ssize_t enabled_store(struct config_item *item,\n \t\t */\n \t\tnetconsole_skb_pool_init(nt);\n \n-\t\tret = netpoll_setup(\u0026nt-\u003enp);\n+\t\tret = netcons_netpoll_setup(nt);\n \t\tif (ret) {\n \t\t\tnetconsole_skb_pool_flush(nt);\n \t\t\tgoto out_unlock;\n@@ -1014,10 +1222,10 @@ static ssize_t local_ip_store(struct config_item *item, const char *buf,\n \t\tgoto out_unlock;\n \t}\n \n-\tipv6 = netpoll_parse_ip_addr(buf, \u0026nt-\u003enp.local_ip);\n+\tipv6 = netpoll_parse_ip_addr(buf, \u0026nt-\u003elocal_ip);\n \tif (ipv6 == -1)\n \t\tgoto out_unlock;\n-\tnt-\u003enp.ipv6 = !!ipv6;\n+\tnt-\u003eipv6 = !!ipv6;\n \n \tret = count;\n out_unlock:\n@@ -1039,10 +1247,10 @@ static ssize_t remote_ip_store(struct config_item *item, const char *buf,\n \t\tgoto out_unlock;\n \t}\n \n-\tipv6 = netpoll_parse_ip_addr(buf, \u0026nt-\u003enp.remote_ip);\n+\tipv6 = netpoll_parse_ip_addr(buf, \u0026nt-\u003eremote_ip);\n \tif (ipv6 == -1)\n \t\tgoto out_unlock;\n-\tnt-\u003enp.ipv6 = !!ipv6;\n+\tnt-\u003eipv6 = !!ipv6;\n \n \tret = count;\n out_unlock:\n@@ -1842,8 +2050,8 @@ static struct sk_buff *find_skb(struct netconsole_target *nt, int len,\n \treturn skb;\n }\n \n-static void netpoll_udp_checksum(struct netpoll *np, struct sk_buff *skb,\n-\t\t\t\t int len)\n+static void netpoll_udp_checksum(struct netconsole_target *nt,\n+\t\t\t\t struct sk_buff *skb, int len)\n {\n \tstruct udphdr *udph;\n \tint udp_len;\n@@ -1853,14 +2061,14 @@ static void netpoll_udp_checksum(struct netpoll *np, struct sk_buff *skb,\n \n \t/* check needs to be set, since it will be consumed in csum_partial */\n \tudph-\u003echeck = 0;\n-\tif (np-\u003eipv6)\n-\t\tudph-\u003echeck = csum_ipv6_magic(\u0026np-\u003elocal_ip.in6,\n-\t\t\t\t\t \u0026np-\u003eremote_ip.in6,\n+\tif (nt-\u003eipv6)\n+\t\tudph-\u003echeck = csum_ipv6_magic(\u0026nt-\u003elocal_ip.in6,\n+\t\t\t\t\t \u0026nt-\u003eremote_ip.in6,\n \t\t\t\t\t udp_len, IPPROTO_UDP,\n \t\t\t\t\t csum_partial(udph, udp_len, 0));\n \telse\n-\t\tudph-\u003echeck = csum_tcpudp_magic(np-\u003elocal_ip.ip,\n-\t\t\t\t\t\tnp-\u003eremote_ip.ip,\n+\t\tudph-\u003echeck = csum_tcpudp_magic(nt-\u003elocal_ip.ip,\n+\t\t\t\t\t\tnt-\u003eremote_ip.ip,\n \t\t\t\t\t\tudp_len, IPPROTO_UDP,\n \t\t\t\t\t\tcsum_partial(udph, udp_len, 0));\n \tif (udph-\u003echeck == 0)\n@@ -1869,7 +2077,6 @@ static void netpoll_udp_checksum(struct netpoll *np, struct sk_buff *skb,\n \n static void push_udp(struct netconsole_target *nt, struct sk_buff *skb, int len)\n {\n-\tstruct netpoll *np = \u0026nt-\u003enp;\n \tstruct udphdr *udph;\n \tint udp_len;\n \n@@ -1883,7 +2090,7 @@ static void push_udp(struct netconsole_target *nt, struct sk_buff *skb, int len)\n \tudph-\u003edest = htons(nt-\u003eremote_port);\n \tudp_set_len_short(udph, udp_len);\n \n-\tnetpoll_udp_checksum(np, skb, len);\n+\tnetpoll_udp_checksum(nt, skb, len);\n }\n \n static void push_eth(struct netconsole_target *nt, struct sk_buff *skb)\n@@ -1895,13 +2102,14 @@ static void push_eth(struct netconsole_target *nt, struct sk_buff *skb)\n \tskb_reset_mac_header(skb);\n \tether_addr_copy(eth-\u003eh_source, np-\u003edev-\u003edev_addr);\n \tether_addr_copy(eth-\u003eh_dest, nt-\u003eremote_mac);\n-\tif (np-\u003eipv6)\n+\tif (nt-\u003eipv6)\n \t\teth-\u003eh_proto = htons(ETH_P_IPV6);\n \telse\n \t\teth-\u003eh_proto = htons(ETH_P_IP);\n }\n \n-static void push_ipv4(struct netpoll *np, struct sk_buff *skb, int len)\n+static void push_ipv4(struct netconsole_target *nt, struct sk_buff *skb,\n+\t\t int len)\n {\n \tstatic atomic_t ip_ident;\n \tstruct iphdr *iph;\n@@ -1922,13 +2130,14 @@ static void push_ipv4(struct netpoll *np, struct sk_buff *skb, int len)\n \tiph-\u003ettl = 64;\n \tiph-\u003eprotocol = IPPROTO_UDP;\n \tiph-\u003echeck = 0;\n-\tput_unaligned(np-\u003elocal_ip.ip, \u0026iph-\u003esaddr);\n-\tput_unaligned(np-\u003eremote_ip.ip, \u0026iph-\u003edaddr);\n+\tput_unaligned(nt-\u003elocal_ip.ip, \u0026iph-\u003esaddr);\n+\tput_unaligned(nt-\u003eremote_ip.ip, \u0026iph-\u003edaddr);\n \tiph-\u003echeck = ip_fast_csum((unsigned char *)iph, iph-\u003eihl);\n \tskb-\u003eprotocol = htons(ETH_P_IP);\n }\n \n-static void push_ipv6(struct netpoll *np, struct sk_buff *skb, int len)\n+static void push_ipv6(struct netconsole_target *nt, struct sk_buff *skb,\n+\t\t int len)\n {\n \tstruct ipv6hdr *ip6h;\n \n@@ -1945,8 +2154,8 @@ static void push_ipv6(struct netpoll *np, struct sk_buff *skb, int len)\n \tip6h-\u003epayload_len = htons(sizeof(struct udphdr) + len);\n \tip6h-\u003enexthdr = IPPROTO_UDP;\n \tip6h-\u003ehop_limit = 32;\n-\tip6h-\u003esaddr = np-\u003elocal_ip.in6;\n-\tip6h-\u003edaddr = np-\u003eremote_ip.in6;\n+\tip6h-\u003esaddr = nt-\u003elocal_ip.in6;\n+\tip6h-\u003edaddr = nt-\u003eremote_ip.in6;\n \n \tskb-\u003eprotocol = htons(ETH_P_IPV6);\n }\n@@ -1962,7 +2171,7 @@ static int netpoll_send_udp(struct netconsole_target *nt, const char *msg,\n \t\tWARN_ON_ONCE(!irqs_disabled());\n \n \tudp_len = len + sizeof(struct udphdr);\n-\tif (np-\u003eipv6)\n+\tif (nt-\u003eipv6)\n \t\tip_len = udp_len + sizeof(struct ipv6hdr);\n \telse\n \t\tip_len = udp_len + sizeof(struct iphdr);\n@@ -1978,10 +2187,10 @@ static int netpoll_send_udp(struct netconsole_target *nt, const char *msg,\n \tskb_put(skb, len);\n \n \tpush_udp(nt, skb, len);\n-\tif (np-\u003eipv6)\n-\t\tpush_ipv6(np, skb, len);\n+\tif (nt-\u003eipv6)\n+\t\tpush_ipv6(nt, skb, len);\n \telse\n-\t\tpush_ipv4(np, skb, len);\n+\t\tpush_ipv4(nt, skb, len);\n \tpush_eth(nt, skb);\n \tskb-\u003edev = np-\u003edev;\n \n@@ -2320,11 +2529,11 @@ static int netconsole_parser_cmdline(struct netconsole_target *nt, char *opt)\n \t\tif (!delim)\n \t\t\tgoto parse_failed;\n \t\t*delim = 0;\n-\t\tipv6 = netpoll_parse_ip_addr(cur, \u0026np-\u003elocal_ip);\n+\t\tipv6 = netpoll_parse_ip_addr(cur, \u0026nt-\u003elocal_ip);\n \t\tif (ipv6 \u003c 0)\n \t\t\tgoto parse_failed;\n \t\telse\n-\t\t\tnp-\u003eipv6 = (bool)ipv6;\n+\t\t\tnt-\u003eipv6 = (bool)ipv6;\n \t\tcur = delim;\n \t}\n \tcur++;\n@@ -2366,13 +2575,13 @@ static int netconsole_parser_cmdline(struct netconsole_target *nt, char *opt)\n \tif (!delim)\n \t\tgoto parse_failed;\n \t*delim = 0;\n-\tipv6 = netpoll_parse_ip_addr(cur, \u0026np-\u003eremote_ip);\n+\tipv6 = netpoll_parse_ip_addr(cur, \u0026nt-\u003eremote_ip);\n \tif (ipv6 \u003c 0)\n \t\tgoto parse_failed;\n-\telse if (ipversion_set \u0026\u0026 np-\u003eipv6 != (bool)ipv6)\n+\telse if (ipversion_set \u0026\u0026 nt-\u003eipv6 != (bool)ipv6)\n \t\tgoto parse_failed;\n \telse\n-\t\tnp-\u003eipv6 = (bool)ipv6;\n+\t\tnt-\u003eipv6 = (bool)ipv6;\n \tcur = delim + 1;\n \n \tif (*cur != 0) {\n@@ -2430,7 +2639,7 @@ static struct netconsole_target *alloc_param_target(char *target_config,\n \t */\n \tnetconsole_skb_pool_init(nt);\n \n-\terr = netpoll_setup(\u0026nt-\u003enp);\n+\terr = netcons_netpoll_setup(nt);\n \tif (err) {\n \t\tpr_err(\"Not enabling netconsole for %s%d. Netpoll setup failed\\n\",\n \t\t NETCONSOLE_PARAM_TARGET_PREFIX, cmdline_count);\ndiff --git a/include/linux/netpoll.h b/include/linux/netpoll.h\nindex 79315461a7b1e0..1c6b1eec5efd68 100644\n--- a/include/linux/netpoll.h\n+++ b/include/linux/netpoll.h\n@@ -32,9 +32,6 @@ struct netpoll {\n \tchar dev_name[IFNAMSIZ];\n \tu8 dev_mac[ETH_ALEN];\n \tconst char *name;\n-\n-\tunion inet_addr local_ip, remote_ip;\n-\tbool ipv6;\n };\n \n #define np_info(np, fmt, ...)\t\t\t\t\\\n@@ -66,12 +63,12 @@ static inline void netpoll_poll_enable(struct net_device *dev) { return; }\n #endif\n \n int __netpoll_setup(struct netpoll *np, struct net_device *ndev);\n-int netpoll_setup(struct netpoll *np);\n void __netpoll_free(struct netpoll *np);\n void netpoll_cleanup(struct netpoll *np);\n void do_netpoll_cleanup(struct netpoll *np);\n netdev_tx_t netpoll_send_skb(struct netpoll *np, struct sk_buff *skb);\n void netpoll_zap_completion_queue(void);\n+unsigned int netpoll_get_carrier_timeout(void);\n \n #ifdef CONFIG_NETPOLL\n static inline void *netpoll_poll_lock(struct napi_struct *napi)\ndiff --git a/net/core/netpoll.c b/net/core/netpoll.c\nindex f8da1048ea3ab0..fe1e0cda5d6bfc 100644\n--- a/net/core/netpoll.c\n+++ b/net/core/netpoll.c\n@@ -38,9 +38,20 @@\n \n #define USEC_PER_POLL\t50\n \n+/*\n+ * carrier_timeout is netconsole-specific and only kept here to preserve the\n+ * netpoll.carrier_timeout module-parameter ABI. Its value is exposed to\n+ * netconsole through netpoll_get_carrier_timeout().\n+ */\n static unsigned int carrier_timeout = 4;\n module_param(carrier_timeout, uint, 0644);\n \n+unsigned int netpoll_get_carrier_timeout(void)\n+{\n+\treturn carrier_timeout;\n+}\n+EXPORT_SYMBOL_GPL(netpoll_get_carrier_timeout);\n+\n static netdev_tx_t netpoll_start_xmit(struct sk_buff *skb,\n \t\t\t\t struct net_device *dev,\n \t\t\t\t struct netdev_queue *txq)\n@@ -381,205 +392,6 @@ int __netpoll_setup(struct netpoll *np, struct net_device *ndev)\n }\n EXPORT_SYMBOL_GPL(__netpoll_setup);\n \n-/*\n- * Returns a pointer to a string representation of the identifier used\n- * to select the egress interface for the given netpoll instance. buf\n- * is used to format np-\u003edev_mac when np-\u003edev_name is empty; bufsz must\n- * be at least MAC_ADDR_STR_LEN + 1 to fit the formatted MAC address\n- * and its NUL terminator.\n- */\n-static char *egress_dev(struct netpoll *np, char *buf, size_t bufsz)\n-{\n-\tif (np-\u003edev_name[0])\n-\t\treturn np-\u003edev_name;\n-\n-\tsnprintf(buf, bufsz, \"%pM\", np-\u003edev_mac);\n-\treturn buf;\n-}\n-\n-static void netpoll_wait_carrier(struct netpoll *np, struct net_device *ndev,\n-\t\t\t\t unsigned int timeout)\n-{\n-\tunsigned long atmost;\n-\n-\tatmost = jiffies + timeout * HZ;\n-\twhile (!netif_carrier_ok(ndev)) {\n-\t\tif (time_after(jiffies, atmost)) {\n-\t\t\tnp_notice(np, \"timeout waiting for carrier\\n\");\n-\t\t\tbreak;\n-\t\t}\n-\t\tmsleep(1);\n-\t}\n-}\n-\n-/*\n- * Take the IPv6 from ndev and populate local_ip structure in netpoll\n- */\n-static int netpoll_take_ipv6(struct netpoll *np, struct net_device *ndev)\n-{\n-\tchar buf[MAC_ADDR_STR_LEN + 1];\n-\tint err = -EDESTADDRREQ;\n-\tstruct inet6_dev *idev;\n-\n-\tif (!IS_ENABLED(CONFIG_IPV6)) {\n-\t\tnp_err(np, \"IPv6 is not supported %s, aborting\\n\",\n-\t\t egress_dev(np, buf, sizeof(buf)));\n-\t\treturn -EINVAL;\n-\t}\n-\n-\tidev = __in6_dev_get(ndev);\n-\tif (idev) {\n-\t\tstruct inet6_ifaddr *ifp;\n-\n-\t\tread_lock_bh(\u0026idev-\u003elock);\n-\t\tlist_for_each_entry(ifp, \u0026idev-\u003eaddr_list, if_list) {\n-\t\t\tif (!!(ipv6_addr_type(\u0026ifp-\u003eaddr) \u0026 IPV6_ADDR_LINKLOCAL) !=\n-\t\t\t\t!!(ipv6_addr_type(\u0026np-\u003eremote_ip.in6) \u0026 IPV6_ADDR_LINKLOCAL))\n-\t\t\t\tcontinue;\n-\t\t\t/* Got the IP, let's return */\n-\t\t\tnp-\u003elocal_ip.in6 = ifp-\u003eaddr;\n-\t\t\terr = 0;\n-\t\t\tbreak;\n-\t\t}\n-\t\tread_unlock_bh(\u0026idev-\u003elock);\n-\t}\n-\tif (err) {\n-\t\tnp_err(np, \"no IPv6 address for %s, aborting\\n\",\n-\t\t egress_dev(np, buf, sizeof(buf)));\n-\t\treturn err;\n-\t}\n-\n-\tnp_info(np, \"local IPv6 %pI6c\\n\", \u0026np-\u003elocal_ip.in6);\n-\treturn 0;\n-}\n-\n-/*\n- * Take the IPv4 from ndev and populate local_ip structure in netpoll\n- */\n-static int netpoll_take_ipv4(struct netpoll *np, struct net_device *ndev)\n-{\n-\tchar buf[MAC_ADDR_STR_LEN + 1];\n-\tconst struct in_ifaddr *ifa;\n-\tstruct in_device *in_dev;\n-\n-\tin_dev = __in_dev_get_rtnl(ndev);\n-\tif (!in_dev) {\n-\t\tnp_err(np, \"no IP address for %s, aborting\\n\",\n-\t\t egress_dev(np, buf, sizeof(buf)));\n-\t\treturn -EDESTADDRREQ;\n-\t}\n-\n-\tifa = rtnl_dereference(in_dev-\u003eifa_list);\n-\tif (!ifa) {\n-\t\tnp_err(np, \"no IP address for %s, aborting\\n\",\n-\t\t egress_dev(np, buf, sizeof(buf)));\n-\t\treturn -EDESTADDRREQ;\n-\t}\n-\n-\tnp-\u003elocal_ip.ip = ifa-\u003eifa_local;\n-\tnp_info(np, \"local IP %pI4\\n\", \u0026np-\u003elocal_ip.ip);\n-\n-\treturn 0;\n-}\n-\n-/*\n- * Test whether the caller left np-\u003elocal_ip unset, so that\n- * netpoll_setup() should auto-populate it from the egress device.\n- *\n- * np-\u003elocal_ip is a union of __be32 (IPv4) and struct in6_addr (IPv6),\n- * so an IPv6 address whose first 4 bytes are zero (e.g. ::1, ::2,\n- * IPv4-mapped ::ffff:a.b.c.d) must not be tested via the IPv4 arm —\n- * doing so would misclassify a caller-supplied address as unset and\n- * silently overwrite it with whatever address the device exposes.\n- */\n-static bool netpoll_local_ip_unset(const struct netpoll *np)\n-{\n-\tif (np-\u003eipv6)\n-\t\treturn ipv6_addr_any(\u0026np-\u003elocal_ip.in6);\n-\treturn !np-\u003elocal_ip.ip;\n-}\n-\n-int netpoll_setup(struct netpoll *np)\n-{\n-\tstruct net *net = current-\u003ensproxy-\u003enet_ns;\n-\tchar buf[MAC_ADDR_STR_LEN + 1];\n-\tstruct net_device *ndev = NULL;\n-\tbool ip_overwritten = false;\n-\tint err;\n-\n-\trtnl_lock();\n-\tif (np-\u003edev_name[0])\n-\t\tndev = __dev_get_by_name(net, np-\u003edev_name);\n-\telse if (is_valid_ether_addr(np-\u003edev_mac))\n-\t\tndev = dev_getbyhwaddr(net, ARPHRD_ETHER, np-\u003edev_mac);\n-\n-\tif (!ndev) {\n-\t\tnp_err(np, \"%s doesn't exist, aborting\\n\",\n-\t\t egress_dev(np, buf, sizeof(buf)));\n-\t\terr = -ENODEV;\n-\t\tgoto unlock;\n-\t}\n-\tnetdev_hold(ndev, \u0026np-\u003edev_tracker, GFP_KERNEL);\n-\n-\tif (netdev_master_upper_dev_get(ndev)) {\n-\t\tnp_err(np, \"%s is a slave device, aborting\\n\",\n-\t\t egress_dev(np, buf, sizeof(buf)));\n-\t\terr = -EBUSY;\n-\t\tgoto put;\n-\t}\n-\n-\tif (!netif_running(ndev)) {\n-\t\tnp_info(np, \"device %s not up yet, forcing it\\n\",\n-\t\t\tegress_dev(np, buf, sizeof(buf)));\n-\n-\t\terr = dev_open(ndev, NULL);\n-\t\tif (err) {\n-\t\t\tnp_err(np, \"failed to open %s\\n\", ndev-\u003ename);\n-\t\t\tgoto put;\n-\t\t}\n-\n-\t\trtnl_unlock();\n-\t\tnetpoll_wait_carrier(np, ndev, carrier_timeout);\n-\t\trtnl_lock();\n-\t}\n-\n-\tif (netpoll_local_ip_unset(np)) {\n-\t\tif (!np-\u003eipv6) {\n-\t\t\terr = netpoll_take_ipv4(np, ndev);\n-\t\t\tif (err)\n-\t\t\t\tgoto put;\n-\t\t} else {\n-\t\t\terr = netpoll_take_ipv6(np, ndev);\n-\t\t\tif (err)\n-\t\t\t\tgoto put;\n-\t\t}\n-\t\tip_overwritten = true;\n-\t}\n-\n-\terr = __netpoll_setup(np, ndev);\n-\tif (err)\n-\t\tgoto put;\n-\trtnl_unlock();\n-\n-\t/* Make sure all NAPI polls which started before dev-\u003enpinfo\n-\t * was visible have exited before we start calling NAPI poll.\n-\t * NAPI skips locking if dev-\u003enpinfo is NULL.\n-\t */\n-\tsynchronize_rcu();\n-\n-\treturn 0;\n-\n-put:\n-\tDEBUG_NET_WARN_ON_ONCE(np-\u003edev);\n-\tif (ip_overwritten)\n-\t\tmemset(\u0026np-\u003elocal_ip, 0, sizeof(np-\u003elocal_ip));\n-\tnetdev_put(ndev, \u0026np-\u003edev_tracker);\n-unlock:\n-\trtnl_unlock();\n-\treturn err;\n-}\n-EXPORT_SYMBOL(netpoll_setup);\n-\n static void rcu_cleanup_netpoll_info(struct rcu_head *rcu_head)\n {\n \tstruct netpoll_info *npinfo =\n"
} |
| 2/1 | 2026/07/25 21:17 | agent | patch-evaluator |
1mModel:best-expensive Args: null Results: {
"EnableConfigs": [
"NETCONSOLE",
"NETCONSOLE_DYNAMIC",
"CONFIGFS_FS",
"IPV6"
],
"FocusSymbols": [
"netcons_netpoll_setup",
"netcons_take_ipv4",
"netcons_take_ipv6",
"enabled_store",
"local_ip_store",
"remote_ip_store",
"alloc_param_target",
"netconsole_parser_cmdline",
"netpoll_send_udp"
],
"Reasoning": "The patch refactors netconsole and netpoll by moving IP address configuration and setup logic from the generic netpoll structure to the netconsole target. It introduces new functions like `netcons_netpoll_setup`, `netcons_take_ipv4`, and `netcons_take_ipv6`. These changes are functional and reachable via configfs (dynamic netconsole) and module parameters, making them suitable for fuzzing.",
"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 e4812b784fd541acde4b6399949b064364b4c43f
Author: syz-cluster <triage@syzkaller.com>
Date: Sat Jul 25 21:17:16 2026 +0000
syz-cluster: applied patch under review
diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c
index 7f8851a734fcd0..03913302328ccd 100644
--- a/drivers/net/netconsole.c
+++ b/drivers/net/netconsole.c
@@ -37,8 +37,10 @@
#include <linux/udp.h>
#include <linux/netpoll.h>
#include <linux/inet.h>
+#include <linux/inetdevice.h>
#include <linux/unaligned.h>
#include <net/ip6_checksum.h>
+#include <net/addrconf.h>
#include <linux/configfs.h>
#include <linux/etherdevice.h>
#include <linux/hex.h>
@@ -46,6 +48,7 @@
#include <linux/utsname.h>
#include <linux/rtnetlink.h>
#include <linux/workqueue.h>
+#include <linux/delay.h>
MODULE_AUTHOR("Matt Mackall <mpm@selenic.com>");
MODULE_DESCRIPTION("Console driver for network interfaces");
@@ -175,9 +178,10 @@ enum target_state {
* @np: The netpoll structure for this target.
* Contains the other userspace visible parameters:
* dev_name (read-write)
- * local_ip (read-write)
- * remote_ip (read-write)
* local_mac (read-only)
+ * @local_ip: Source IP address of the target (read-write).
+ * @remote_ip: Destination IP address of the target (read-write).
+ * @ipv6: Whether the target addresses are IPv6 (read-write).
* @local_port: Source UDP port of the target (read-write).
* @remote_port: Destination UDP port of the target (read-write).
* @remote_mac: Destination ethernet address of the target (read-write).
@@ -208,6 +212,8 @@ struct netconsole_target {
bool extended;
bool release;
struct netpoll np;
+ union inet_addr local_ip, remote_ip;
+ bool ipv6;
u16 local_port, remote_port;
u8 remote_mac[ETH_ALEN];
/* protected by target_list_lock; +1 gives scnprintf() room for its
@@ -351,6 +357,208 @@ static void netconsole_skb_pool_flush(struct netconsole_target *nt)
skb_queue_purge_reason(&nt->skb_pool, SKB_CONSUMED);
}
+static void netcons_wait_carrier(struct netpoll *np, struct net_device *ndev)
+{
+ unsigned long atmost;
+
+ atmost = jiffies + netpoll_get_carrier_timeout() * HZ;
+ while (!netif_carrier_ok(ndev)) {
+ if (time_after(jiffies, atmost)) {
+ np_notice(np, "timeout waiting for carrier\n");
+ break;
+ }
+ msleep(1);
+ }
+}
+
+/*
+ * Returns a pointer to a string representation of the identifier used
+ * to select the egress interface for the given netpoll instance. buf
+ * is used to format np->dev_mac when np->dev_name is empty; bufsz must
+ * be at least MAC_ADDR_STR_LEN + 1 to fit the formatted MAC address
+ * and its NUL terminator.
+ */
+static char *netcons_egress_dev(struct netpoll *np, char *buf, size_t bufsz)
+{
+ if (np->dev_name[0])
+ return np->dev_name;
+
+ snprintf(buf, bufsz, "%pM", np->dev_mac);
+ return buf;
+}
+
+/*
+ * Populate the target's local_ip with the IPv6 address from ndev.
+ */
+static int netcons_take_ipv6(struct netconsole_target *nt,
+ struct net_device *ndev)
+{
+ char buf[MAC_ADDR_STR_LEN + 1];
+ struct netpoll *np = &nt->np;
+ int err = -EDESTADDRREQ;
+ struct inet6_dev *idev;
+
+ if (!IS_ENABLED(CONFIG_IPV6)) {
+ np_err(np, "IPv6 is not supported %s, aborting\n",
+ netcons_egress_dev(np, buf, sizeof(buf)));
+ return -EINVAL;
+ }
+
+ idev = __in6_dev_get(ndev);
+ if (idev) {
+ struct inet6_ifaddr *ifp;
+
+ read_lock_bh(&idev->lock);
+ list_for_each_entry(ifp, &idev->addr_list, if_list) {
+ if (!!(ipv6_addr_type(&ifp->addr) & IPV6_ADDR_LINKLOCAL) !=
+ !!(ipv6_addr_type(&nt->remote_ip.in6) & IPV6_ADDR_LINKLOCAL))
+ continue;
+ /* Got the IP, let's return */
+ nt->local_ip.in6 = ifp->addr;
+ err = 0;
+ break;
+ }
+ read_unlock_bh(&idev->lock);
+ }
+ if (err) {
+ np_err(np, "no IPv6 address for %s, aborting\n",
+ netcons_egress_dev(np, buf, sizeof(buf)));
+ return err;
+ }
+
+ np_info(np, "local IPv6 %pI6c\n", &nt->local_ip.in6);
+ return 0;
+}
+
+/*
+ * Populate the target's local_ip with the IPv4 address from ndev.
+ */
+static int netcons_take_ipv4(struct netconsole_target *nt,
+ struct net_device *ndev)
+{
+ char buf[MAC_ADDR_STR_LEN + 1];
+ struct netpoll *np = &nt->np;
+ const struct in_ifaddr *ifa;
+ struct in_device *in_dev;
+
+ in_dev = __in_dev_get_rtnl(ndev);
+ if (!in_dev) {
+ np_err(np, "no IP address for %s, aborting\n",
+ netcons_egress_dev(np, buf, sizeof(buf)));
+ return -EDESTADDRREQ;
+ }
+
+ ifa = rtnl_dereference(in_dev->ifa_list);
+ if (!ifa) {
+ np_err(np, "no IP address for %s, aborting\n",
+ netcons_egress_dev(np, buf, sizeof(buf)));
+ return -EDESTADDRREQ;
+ }
+
+ nt->local_ip.ip = ifa->ifa_local;
+ np_info(np, "local IP %pI4\n", &nt->local_ip.ip);
+
+ return 0;
+}
+
+/*
+ * Test whether the caller left nt->local_ip unset, so that
+ * netcons_netpoll_setup() should auto-populate it from the egress device.
+ *
+ * nt->local_ip is a union of __be32 (IPv4) and struct in6_addr (IPv6),
+ * so an IPv6 address whose first 4 bytes are zero (e.g. ::1, ::2,
+ * IPv4-mapped ::ffff:a.b.c.d) must not be tested via the IPv4 arm —
+ * doing so would misclassify a caller-supplied address as unset and
+ * silently overwrite it with whatever address the device exposes.
+ */
+static bool netcons_local_ip_unset(const struct netconsole_target *nt)
+{
+ if (nt->ipv6)
+ return ipv6_addr_any(&nt->local_ip.in6);
+ return !nt->local_ip.ip;
+}
+
+static int netcons_netpoll_setup(struct netconsole_target *nt)
+{
+ struct net *net = current->nsproxy->net_ns;
+ char buf[MAC_ADDR_STR_LEN + 1];
+ struct net_device *ndev = NULL;
+ struct netpoll *np = &nt->np;
+ bool ip_overwritten = false;
+ int err;
+
+ rtnl_lock();
+ if (np->dev_name[0])
+ ndev = __dev_get_by_name(net, np->dev_name);
+ else if (is_valid_ether_addr(np->dev_mac))
+ ndev = dev_getbyhwaddr(net, ARPHRD_ETHER, np->dev_mac);
+
+ if (!ndev) {
+ np_err(np, "%s doesn't exist, aborting\n",
+ netcons_egress_dev(np, buf, sizeof(buf)));
+ err = -ENODEV;
+ goto unlock;
+ }
+ netdev_hold(ndev, &np->dev_tracker, GFP_KERNEL);
+
+ if (netdev_master_upper_dev_get(ndev)) {
+ np_err(np, "%s is a slave device, aborting\n",
+ netcons_egress_dev(np, buf, sizeof(buf)));
+ err = -EBUSY;
+ goto put;
+ }
+
+ if (!netif_running(ndev)) {
+ np_info(np, "device %s not up yet, forcing it\n",
+ netcons_egress_dev(np, buf, sizeof(buf)));
+
+ err = dev_open(ndev, NULL);
+ if (err) {
+ np_err(np, "failed to open %s\n", ndev->name);
+ goto put;
+ }
+
+ rtnl_unlock();
+ netcons_wait_carrier(np, ndev);
+ rtnl_lock();
+ }
+
+ if (netcons_local_ip_unset(nt)) {
+ if (!nt->ipv6) {
+ err = netcons_take_ipv4(nt, ndev);
+ if (err)
+ goto put;
+ } else {
+ err = netcons_take_ipv6(nt, ndev);
+ if (err)
+ goto put;
+ }
+ ip_overwritten = true;
+ }
+
+ err = __netpoll_setup(np, ndev);
+ if (err)
+ goto put;
+ rtnl_unlock();
+
+ /* Make sure all NAPI polls which started before dev->npinfo
+ * was visible have exited before we start calling NAPI poll.
+ * NAPI skips locking if dev->npinfo is NULL.
+ */
+ synchronize_rcu();
+
+ return 0;
+
+put:
+ DEBUG_NET_WARN_ON_ONCE(np->dev);
+ if (ip_overwritten)
+ memset(&nt->local_ip, 0, sizeof(nt->local_ip));
+ netdev_put(ndev, &np->dev_tracker);
+unlock:
+ rtnl_unlock();
+ return err;
+}
+
/* Attempts to resume logging to a deactivated target. */
static void resume_target(struct netconsole_target *nt)
{
@@ -361,7 +569,7 @@ static void resume_target(struct netconsole_target *nt)
*/
netconsole_skb_pool_init(nt);
- if (netpoll_setup(&nt->np)) {
+ if (netcons_netpoll_setup(nt)) {
/* netpoll fails setup once, do not try again. */
netconsole_skb_pool_flush(nt);
nt->state = STATE_DISABLED;
@@ -506,17 +714,17 @@ static void netconsole_print_banner(struct netconsole_target *nt)
struct netpoll *np = &nt->np;
np_info(np, "local port %d\n", nt->local_port);
- if (np->ipv6)
- np_info(np, "local IPv6 address %pI6c\n", &np->local_ip.in6);
+ if (nt->ipv6)
+ np_info(np, "local IPv6 address %pI6c\n", &nt->local_ip.in6);
else
- np_info(np, "local IPv4 address %pI4\n", &np->local_ip.ip);
+ np_info(np, "local IPv4 address %pI4\n", &nt->local_ip.ip);
np_info(np, "interface name '%s'\n", np->dev_name);
np_info(np, "local ethernet address '%pM'\n", np->dev_mac);
np_info(np, "remote port %d\n", nt->remote_port);
- if (np->ipv6)
- np_info(np, "remote IPv6 address %pI6c\n", &np->remote_ip.in6);
+ if (nt->ipv6)
+ np_info(np, "remote IPv6 address %pI6c\n", &nt->remote_ip.in6);
else
- np_info(np, "remote IPv4 address %pI4\n", &np->remote_ip.ip);
+ np_info(np, "remote IPv4 address %pI4\n", &nt->remote_ip.ip);
np_info(np, "remote ethernet address %pM\n", nt->remote_mac);
}
@@ -647,20 +855,20 @@ static ssize_t local_ip_show(struct config_item *item, char *buf)
{
struct netconsole_target *nt = to_target(item);
- if (nt->np.ipv6)
- return sysfs_emit(buf, "%pI6c\n", &nt->np.local_ip.in6);
+ if (nt->ipv6)
+ return sysfs_emit(buf, "%pI6c\n", &nt->local_ip.in6);
else
- return sysfs_emit(buf, "%pI4\n", &nt->np.local_ip);
+ return sysfs_emit(buf, "%pI4\n", &nt->local_ip);
}
static ssize_t remote_ip_show(struct config_item *item, char *buf)
{
struct netconsole_target *nt = to_target(item);
- if (nt->np.ipv6)
- return sysfs_emit(buf, "%pI6c\n", &nt->np.remote_ip.in6);
+ if (nt->ipv6)
+ return sysfs_emit(buf, "%pI6c\n", &nt->remote_ip.in6);
else
- return sysfs_emit(buf, "%pI4\n", &nt->np.remote_ip);
+ return sysfs_emit(buf, "%pI4\n", &nt->remote_ip);
}
static ssize_t local_mac_show(struct config_item *item, char *buf)
@@ -840,7 +1048,7 @@ static ssize_t enabled_store(struct config_item *item,
*/
netconsole_skb_pool_init(nt);
- ret = netpoll_setup(&nt->np);
+ ret = netcons_netpoll_setup(nt);
if (ret) {
netconsole_skb_pool_flush(nt);
goto out_unlock;
@@ -1014,10 +1222,10 @@ static ssize_t local_ip_store(struct config_item *item, const char *buf,
goto out_unlock;
}
- ipv6 = netpoll_parse_ip_addr(buf, &nt->np.local_ip);
+ ipv6 = netpoll_parse_ip_addr(buf, &nt->local_ip);
if (ipv6 == -1)
goto out_unlock;
- nt->np.ipv6 = !!ipv6;
+ nt->ipv6 = !!ipv6;
ret = count;
out_unlock:
@@ -1039,10 +1247,10 @@ static ssize_t remote_ip_store(struct config_item *item, const char *buf,
goto out_unlock;
}
- ipv6 = netpoll_parse_ip_addr(buf, &nt->np.remote_ip);
+ ipv6 = netpoll_parse_ip_addr(buf, &nt->remote_ip);
if (ipv6 == -1)
goto out_unlock;
- nt->np.ipv6 = !!ipv6;
+ nt->ipv6 = !!ipv6;
ret = count;
out_unlock:
@@ -1842,8 +2050,8 @@ static struct sk_buff *find_skb(struct netconsole_target *nt, int len,
return skb;
}
-static void netpoll_udp_checksum(struct netpoll *np, struct sk_buff *skb,
- int len)
+static void netpoll_udp_checksum(struct netconsole_target *nt,
+ struct sk_buff *skb, int len)
{
struct udphdr *udph;
int udp_len;
@@ -1853,14 +2061,14 @@ static void netpoll_udp_checksum(struct netpoll *np, struct sk_buff *skb,
/* check needs to be set, since it will be consumed in csum_partial */
udph->check = 0;
- if (np->ipv6)
- udph->check = csum_ipv6_magic(&np->local_ip.in6,
- &np->remote_ip.in6,
+ if (nt->ipv6)
+ udph->check = csum_ipv6_magic(&nt->local_ip.in6,
+ &nt->remote_ip.in6,
udp_len, IPPROTO_UDP,
csum_partial(udph, udp_len, 0));
else
- udph->check = csum_tcpudp_magic(np->local_ip.ip,
- np->remote_ip.ip,
+ udph->check = csum_tcpudp_magic(nt->local_ip.ip,
+ nt->remote_ip.ip,
udp_len, IPPROTO_UDP,
csum_partial(udph, udp_len, 0));
if (udph->check == 0)
@@ -1869,7 +2077,6 @@ static void netpoll_udp_checksum(struct netpoll *np, struct sk_buff *skb,
static void push_udp(struct netconsole_target *nt, struct sk_buff *skb, int len)
{
- struct netpoll *np = &nt->np;
struct udphdr *udph;
int udp_len;
@@ -1883,7 +2090,7 @@ static void push_udp(struct netconsole_target *nt, struct sk_buff *skb, int len)
udph->dest = htons(nt->remote_port);
udp_set_len_short(udph, udp_len);
- netpoll_udp_checksum(np, skb, len);
+ netpoll_udp_checksum(nt, skb, len);
}
static void push_eth(struct netconsole_target *nt, struct sk_buff *skb)
@@ -1895,13 +2102,14 @@ static void push_eth(struct netconsole_target *nt, struct sk_buff *skb)
skb_reset_mac_header(skb);
ether_addr_copy(eth->h_source, np->dev->dev_addr);
ether_addr_copy(eth->h_dest, nt->remote_mac);
- if (np->ipv6)
+ if (nt->ipv6)
eth->h_proto = htons(ETH_P_IPV6);
else
eth->h_proto = htons(ETH_P_IP);
}
-static void push_ipv4(struct netpoll *np, struct sk_buff *skb, int len)
+static void push_ipv4(struct netconsole_target *nt, struct sk_buff *skb,
+ int len)
{
static atomic_t ip_ident;
struct iphdr *iph;
@@ -1922,13 +2130,14 @@ static void push_ipv4(struct netpoll *np, struct sk_buff *skb, int len)
iph->ttl = 64;
iph->protocol = IPPROTO_UDP;
iph->check = 0;
- put_unaligned(np->local_ip.ip, &iph->saddr);
- put_unaligned(np->remote_ip.ip, &iph->daddr);
+ put_unaligned(nt->local_ip.ip, &iph->saddr);
+ put_unaligned(nt->remote_ip.ip, &iph->daddr);
iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl);
skb->protocol = htons(ETH_P_IP);
}
-static void push_ipv6(struct netpoll *np, struct sk_buff *skb, int len)
+static void push_ipv6(struct netconsole_target *nt, struct sk_buff *skb,
+ int len)
{
struct ipv6hdr *ip6h;
@@ -1945,8 +2154,8 @@ static void push_ipv6(struct netpoll *np, struct sk_buff *skb, int len)
ip6h->payload_len = htons(sizeof(struct udphdr) + len);
ip6h->nexthdr = IPPROTO_UDP;
ip6h->hop_limit = 32;
- ip6h->saddr = np->local_ip.in6;
- ip6h->daddr = np->remote_ip.in6;
+ ip6h->saddr = nt->local_ip.in6;
+ ip6h->daddr = nt->remote_ip.in6;
skb->protocol = htons(ETH_P_IPV6);
}
@@ -1962,7 +2171,7 @@ static int netpoll_send_udp(struct netconsole_target *nt, const char *msg,
WARN_ON_ONCE(!irqs_disabled());
udp_len = len + sizeof(struct udphdr);
- if (np->ipv6)
+ if (nt->ipv6)
ip_len = udp_len + sizeof(struct ipv6hdr);
else
ip_len = udp_len + sizeof(struct iphdr);
@@ -1978,10 +2187,10 @@ static int netpoll_send_udp(struct netconsole_target *nt, const char *msg,
skb_put(skb, len);
push_udp(nt, skb, len);
- if (np->ipv6)
- push_ipv6(np, skb, len);
+ if (nt->ipv6)
+ push_ipv6(nt, skb, len);
else
- push_ipv4(np, skb, len);
+ push_ipv4(nt, skb, len);
push_eth(nt, skb);
skb->dev = np->dev;
@@ -2320,11 +2529,11 @@ static int netconsole_parser_cmdline(struct netconsole_target *nt, char *opt)
if (!delim)
goto parse_failed;
*delim = 0;
- ipv6 = netpoll_parse_ip_addr(cur, &np->local_ip);
+ ipv6 = netpoll_parse_ip_addr(cur, &nt->local_ip);
if (ipv6 < 0)
goto parse_failed;
else
- np->ipv6 = (bool)ipv6;
+ nt->ipv6 = (bool)ipv6;
cur = delim;
}
cur++;
@@ -2366,13 +2575,13 @@ static int netconsole_parser_cmdline(struct netconsole_target *nt, char *opt)
if (!delim)
goto parse_failed;
*delim = 0;
- ipv6 = netpoll_parse_ip_addr(cur, &np->remote_ip);
+ ipv6 = netpoll_parse_ip_addr(cur, &nt->remote_ip);
if (ipv6 < 0)
goto parse_failed;
- else if (ipversion_set && np->ipv6 != (bool)ipv6)
+ else if (ipversion_set && nt->ipv6 != (bool)ipv6)
goto parse_failed;
else
- np->ipv6 = (bool)ipv6;
+ nt->ipv6 = (bool)ipv6;
cur = delim + 1;
if (*cur != 0) {
@@ -2430,7 +2639,7 @@ static struct netconsole_target *alloc_param_target(char *target_config,
*/
netconsole_skb_pool_init(nt);
- err = netpoll_setup(&nt->np);
+ err = netcons_netpoll_setup(nt);
if (err) {
pr_err("Not enabling netconsole for %s%d. Netpoll setup failed\n",
NETCONSOLE_PARAM_TARGET_PREFIX, cmdline_count);
diff --git a/include/linux/netpoll.h b/include/linux/netpoll.h
index 79315461a7b1e0..1c6b1eec5efd68 100644
--- a/include/linux/netpoll.h
+++ b/include/linux/netpoll.h
@@ -32,9 +32,6 @@ struct netpoll {
char dev_name[IFNAMSIZ];
u8 dev_mac[ETH_ALEN];
const char *name;
-
- union inet_addr local_ip, remote_ip;
- bool ipv6;
};
#define np_info(np, fmt, ...) \
@@ -66,12 +63,12 @@ static inline void netpoll_poll_enable(struct net_device *dev) { return; }
#endif
int __netpoll_setup(struct netpoll *np, struct net_device *ndev);
-int netpoll_setup(struct netpoll *np);
void __netpoll_free(struct netpoll *np);
void netpoll_cleanup(struct netpoll *np);
void do_netpoll_cleanup(struct netpoll *np);
netdev_tx_t netpoll_send_skb(struct netpoll *np, struct sk_buff *skb);
void netpoll_zap_completion_queue(void);
+unsigned int netpoll_get_carrier_timeout(void);
#ifdef CONFIG_NETPOLL
static inline void *netpoll_poll_lock(struct napi_struct *napi)
diff --git a/net/core/netpoll.c b/net/core/netpoll.c
index f8da1048ea3ab0..fe1e0cda5d6bfc 100644
--- a/net/core/netpoll.c
+++ b/net/core/netpoll.c
@@ -38,9 +38,20 @@
#define USEC_PER_POLL 50
+/*
+ * carrier_timeout is netconsole-specific and only kept here to preserve the
+ * netpoll.carrier_timeout module-parameter ABI. Its value is exposed to
+ * netconsole through netpoll_get_carrier_timeout().
+ */
static unsigned int carrier_timeout = 4;
module_param(carrier_timeout, uint, 0644);
+unsigned int netpoll_get_carrier_timeout(void)
+{
+ return carrier_timeout;
+}
+EXPORT_SYMBOL_GPL(netpoll_get_carrier_timeout);
+
static netdev_tx_t netpoll_start_xmit(struct sk_buff *skb,
struct net_device *dev,
struct netdev_queue *txq)
@@ -381,205 +392,6 @@ int __netpoll_setup(struct netpoll *np, struct net_device *ndev)
}
EXPORT_SYMBOL_GPL(__netpoll_setup);
-/*
- * Returns a pointer to a string representation of the identifier used
- * to select the egress interface for the given netpoll instance. buf
- * is used to format np->dev_mac when np->dev_name is empty; bufsz must
- * be at least MAC_ADDR_STR_LEN + 1 to fit the formatted MAC address
- * and its NUL terminator.
- */
-static char *egress_dev(struct netpoll *np, char *buf, size_t bufsz)
-{
- if (np->dev_name[0])
- return np->dev_name;
-
- snprintf(buf, bufsz, "%pM", np->dev_mac);
- return buf;
-}
-
-static void netpoll_wait_carrier(struct netpoll *np, struct net_device *ndev,
- unsigned int timeout)
-{
- unsigned long atmost;
-
- atmost = jiffies + timeout * HZ;
- while (!netif_carrier_ok(ndev)) {
- if (time_after(jiffies, atmost)) {
- np_notice(np, "timeout waiting for carrier\n");
- break;
- }
- msleep(1);
- }
-}
-
-/*
- * Take the IPv6 from ndev and populate local_ip structure in netpoll
- */
-static int netpoll_take_ipv6(struct netpoll *np, struct net_device *ndev)
-{
- char buf[MAC_ADDR_STR_LEN + 1];
- int err = -EDESTADDRREQ;
- struct inet6_dev *idev;
-
- if (!IS_ENABLED(CONFIG_IPV6)) {
- np_err(np, "IPv6 is not supported %s, aborting\n",
- egress_dev(np, buf, sizeof(buf)));
- return -EINVAL;
- }
-
- idev = __in6_dev_get(ndev);
- if (idev) {
- struct inet6_ifaddr *ifp;
-
- read_lock_bh(&idev->lock);
- list_for_each_entry(ifp, &idev->addr_list, if_list) {
- if (!!(ipv6_addr_type(&ifp->addr) & IPV6_ADDR_LINKLOCAL) !=
- !!(ipv6_addr_type(&np->remote_ip.in6) & IPV6_ADDR_LINKLOCAL))
- continue;
- /* Got the IP, let's return */
- np->local_ip.in6 = ifp->addr;
- err = 0;
- break;
- }
- read_unlock_bh(&idev->lock);
- }
- if (err) {
- np_err(np, "no IPv6 address for %s, aborting\n",
- egress_dev(np, buf, sizeof(buf)));
- return err;
- }
-
- np_info(np, "local IPv6 %pI6c\n", &np->local_ip.in6);
- return 0;
-}
-
-/*
- * Take the IPv4 from ndev and populate local_ip structure in netpoll
- */
-static int netpoll_take_ipv4(struct netpoll *np, struct net_device *ndev)
-{
- char buf[MAC_ADDR_STR_LEN + 1];
- const struct in_ifaddr *ifa;
- struct in_device *in_dev;
-
- in_dev = __in_dev_get_rtnl(ndev);
- if (!in_dev) {
- np_err(np, "no IP address for %s, aborting\n",
- egress_dev(np, buf, sizeof(buf)));
- return -EDESTADDRREQ;
- }
-
- ifa = rtnl_dereference(in_dev->ifa_list);
- if (!ifa) {
- np_err(np, "no IP address for %s, aborting\n",
- egress_dev(np, buf, sizeof(buf)));
- return -EDESTADDRREQ;
- }
-
- np->local_ip.ip = ifa->ifa_local;
- np_info(np, "local IP %pI4\n", &np->local_ip.ip);
-
- return 0;
-}
-
-/*
- * Test whether the caller left np->local_ip unset, so that
- * netpoll_setup() should auto-populate it from the egress device.
- *
- * np->local_ip is a union of __be32 (IPv4) and struct in6_addr (IPv6),
- * so an IPv6 address whose first 4 bytes are zero (e.g. ::1, ::2,
- * IPv4-mapped ::ffff:a.b.c.d) must not be tested via the IPv4 arm —
- * doing so would misclassify a caller-supplied address as unset and
- * silently overwrite it with whatever address the device exposes.
- */
-static bool netpoll_local_ip_unset(const struct netpoll *np)
-{
- if (np->ipv6)
- return ipv6_addr_any(&np->local_ip.in6);
- return !np->local_ip.ip;
-}
-
-int netpoll_setup(struct netpoll *np)
-{
- struct net *net = current->nsproxy->net_ns;
- char buf[MAC_ADDR_STR_LEN + 1];
- struct net_device *ndev = NULL;
- bool ip_overwritten = false;
- int err;
-
- rtnl_lock();
- if (np->dev_name[0])
- ndev = __dev_get_by_name(net, np->dev_name);
- else if (is_valid_ether_addr(np->dev_mac))
- ndev = dev_getbyhwaddr(net, ARPHRD_ETHER, np->dev_mac);
-
- if (!ndev) {
- np_err(np, "%s doesn't exist, aborting\n",
- egress_dev(np, buf, sizeof(buf)));
- err = -ENODEV;
- goto unlock;
- }
- netdev_hold(ndev, &np->dev_tracker, GFP_KERNEL);
-
- if (netdev_master_upper_dev_get(ndev)) {
- np_err(np, "%s is a slave device, aborting\n",
- egress_dev(np, buf, sizeof(buf)));
- err = -EBUSY;
- goto put;
- }
-
- if (!netif_running(ndev)) {
- np_info(np, "device %s not up yet, forcing it\n",
- egress_dev(np, buf, sizeof(buf)));
-
- err = dev_open(ndev, NULL);
- if (err) {
- np_err(np, "failed to open %s\n", ndev->name);
- goto put;
- }
-
- rtnl_unlock();
- netpoll_wait_carrier(np, ndev, carrier_timeout);
- rtnl_lock();
- }
-
- if (netpoll_local_ip_unset(np)) {
- if (!np->ipv6) {
- err = netpoll_take_ipv4(np, ndev);
- if (err)
- goto put;
- } else {
- err = netpoll_take_ipv6(np, ndev);
- if (err)
- goto put;
- }
- ip_overwritten = true;
- }
-
- err = __netpoll_setup(np, ndev);
- if (err)
- goto put;
- rtnl_unlock();
-
- /* Make sure all NAPI polls which started before dev->npinfo
- * was visible have exited before we start calling NAPI poll.
- * NAPI skips locking if dev->npinfo is NULL.
- */
- synchronize_rcu();
-
- return 0;
-
-put:
- DEBUG_NET_WARN_ON_ONCE(np->dev);
- if (ip_overwritten)
- memset(&np->local_ip, 0, sizeof(np->local_ip));
- netdev_put(ndev, &np->dev_tracker);
-unlock:
- rtnl_unlock();
- return err;
-}
-EXPORT_SYMBOL(netpoll_setup);
-
static void rcu_cleanup_netpoll_info(struct rcu_head *rcu_head)
{
struct netpoll_info *npinfo =
|
| 3/2 | 2026/07/25 21:17 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 11467 output: 35 thoughts: 353 Thoughts: **Refactoring Netconsole/Netpoll: A Fuzzing Opportunity?** Okay, so I'm looking at this patch that's shuffling things around in the kernel network code. It's touching `drivers/net/netconsole.c`, `include/linux/netpoll.h`, and `net/core/netpoll.c`. Basically, they're moving IP address configuration—`local_ip`, `remote_ip`, `ipv6`—out of the `netpoll` structure and into `netconsole_target`. They're also moving the `netpoll_setup` logic into `netconsole.c` under the name `netcons_netpoll_setup`, and removing it from its original location in `net/core/netpoll.c`. The thinking here is sound; `netpoll` itself is just concerned with sending raw packets (SKBs) or ethernet frames. It doesn't need to be burdened with knowing about IP addresses, because that's the job of the specific network console. Wait, *netconsole* is constructing the UDP/IP headers, so yes, it *does* need the IP addresses. Now, this has me thinking about fuzzing. This patch modifies `netconsole`, which is a network console driver. So, can we fuzz this? `netconsole` is typically configured through configfs or module parameters. And since we are an expert we're well aware that virtualized environments make it reachable. Configfs for `netconsole` can definitely be mounted and manipulated. Okay, so `netconsole` *is* a specific module. The question is: does syzkaller fuzz it? Yes, syzkaller *can* fuzz configfs. Good. So, is `netcons_netpoll_setup` reachable? Yup, through the configfs interfaces, specifically either `enabled_store` or `alloc_param_target`. Time to dig into `drivers/net/netconsole.c`. Let's see what's what. |
| 4/2 | 2026/07/25 21:17 | tool | grepper |
0mArgs:{
"Expression": "netcons_netpoll_setup",
"PathPrefix": "drivers/net/netconsole.c"
}Results: {
"Output": "drivers/net/netconsole.c=436=static int netcons_take_ipv4(struct netconsole_target *nt,\n--\ndrivers/net/netconsole.c-465- * Test whether the caller left nt-\u003elocal_ip unset, so that\ndrivers/net/netconsole.c:466: * netcons_netpoll_setup() should auto-populate it from the egress device.\ndrivers/net/netconsole.c-467- *\n--\ndrivers/net/netconsole.c=474=static bool netcons_local_ip_unset(const struct netconsole_target *nt)\n--\ndrivers/net/netconsole.c-480-\ndrivers/net/netconsole.c:481:static int netcons_netpoll_setup(struct netconsole_target *nt)\ndrivers/net/netconsole.c-482-{\n--\ndrivers/net/netconsole.c=563=static void resume_target(struct netconsole_target *nt)\n--\ndrivers/net/netconsole.c-571-\ndrivers/net/netconsole.c:572:\tif (netcons_netpoll_setup(nt)) {\ndrivers/net/netconsole.c-573-\t\t/* netpoll fails setup once, do not try again. */\n--\ndrivers/net/netconsole.c=989=static ssize_t enabled_store(struct config_item *item,\n--\ndrivers/net/netconsole.c-1050-\ndrivers/net/netconsole.c:1051:\t\tret = netcons_netpoll_setup(nt);\ndrivers/net/netconsole.c-1052-\t\tif (ret) {\n--\ndrivers/net/netconsole.c=2603=static struct netconsole_target *alloc_param_target(char *target_config,\n--\ndrivers/net/netconsole.c-2641-\ndrivers/net/netconsole.c:2642:\terr = netcons_netpoll_setup(nt);\ndrivers/net/netconsole.c-2643-\tif (err) {\n"
} |
| 5/2 | 2026/07/25 21:17 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 12802 output: 29 thoughts: 162 Thoughts: **Analyzing the Netconsole Refactoring Patch** Okay, so this patch is essentially a refactoring, which is good. It's moving the `netpoll_setup` function to `netcons_netpoll_setup` and shifting `np->local_ip` to `nt->local_ip`. The key question is whether this warrants fuzzing attention. Given that it touches the initialization and IP address handling of netconsole, I'd say yes, it definitely does. We need to explore the potential for any overlooked vulnerabilities in the process. Now, a critical thought, does this fundamentally alter any core logic? From a quick glance, it appears the primary change is a code relocation, shifting initialization logic from `net/core/netpoll.c` to `drivers/net/netconsole.c`. Let's drill down and see if any entirely new functions were introduced or if existing ones are modified in a substantial way. Looking at the changes, `netcons_netpoll_setup`, `netcons_take_ipv4`, and `netcons_take_ipv6` look like the primary areas to focus on. These are obviously critical for the netconsole initialization. Finally, I need to check the configuration options. A quick scan of `CONFIG_NETCONSOLE` and `CONFIG_NETPOLL` will clarify the dependencies and enable us to assess how broadly this change impacts the kernel's overall configuration space. |
| 6/2 | 2026/07/25 21:17 | tool | grepper |
0mArgs:{
"Expression": "config NETCONSOLE",
"PathPrefix": "drivers/net/Kconfig"
}Results: {
"Output": "drivers/net/Kconfig=318=config MACSEC\n--\ndrivers/net/Kconfig-326-\ndrivers/net/Kconfig:327:config NETCONSOLE\ndrivers/net/Kconfig-328-\ttristate \"Network console logging support\"\n--\ndrivers/net/Kconfig-333-\ndrivers/net/Kconfig:334:config NETCONSOLE_DYNAMIC\ndrivers/net/Kconfig-335-\tbool \"Dynamic reconfiguration of logging targets\"\n--\ndrivers/net/Kconfig-344-\ndrivers/net/Kconfig:345:config NETCONSOLE_EXTENDED_LOG\ndrivers/net/Kconfig-346-\tbool \"Set kernel extended message by default\"\n--\ndrivers/net/Kconfig-354-\ndrivers/net/Kconfig:355:config NETCONSOLE_PREPEND_RELEASE\ndrivers/net/Kconfig-356-\tbool \"Prepend kernel release version in the message by default\"\n"
} |
| 7/2 | 2026/07/25 21:17 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 13538 output: 34 thoughts: 17 Thoughts: Here's a summary of my thought process: **Kconfig Hunt for NETCONSOLE** Okay, so I need to find where the `NETCONSOLE` configuration option is defined. My first instinct, given its relation to network functionality, is to look within the kernel's network driver configuration. That means I'll start with the `drivers/net/` directory and within that, the `Kconfig` file. That's the standard place to define these sorts of options. It's the logical starting point for locating and understanding the configuration options for network console functionality within the kernel. Let's see what's in there. |
| 8/2 | 2026/07/25 21:17 | tool | read-file |
0mArgs:{
"File": "drivers/net/Kconfig",
"FirstLine": 325,
"LineCount": 30
}Results: {
"Contents": " 325:\t\t MACsec is an encryption standard for Ethernet.\n 326:\t\n 327:\tconfig NETCONSOLE\n 328:\t\ttristate \"Network console logging support\"\n 329:\t\tdepends on PRINTK\n 330:\t\thelp\n 331:\t\t If you want to log kernel messages over the network, enable this.\n 332:\t\t See \u003cfile:Documentation/networking/netconsole.rst\u003e for details.\n 333:\t\n 334:\tconfig NETCONSOLE_DYNAMIC\n 335:\t\tbool \"Dynamic reconfiguration of logging targets\"\n 336:\t\tdepends on NETCONSOLE \u0026\u0026 SYSFS \u0026\u0026 CONFIGFS_FS \u0026\u0026 \\\n 337:\t\t\t\t!(NETCONSOLE=y \u0026\u0026 CONFIGFS_FS=m)\n 338:\t\tselect PRINTK_EXECUTION_CTX\n 339:\t\thelp\n 340:\t\t This option enables the ability to dynamically reconfigure target\n 341:\t\t parameters (interface, IP addresses, port numbers, MAC addresses)\n 342:\t\t at runtime through a userspace interface exported using configfs.\n 343:\t\t See \u003cfile:Documentation/networking/netconsole.rst\u003e for details.\n 344:\t\n 345:\tconfig NETCONSOLE_EXTENDED_LOG\n 346:\t\tbool \"Set kernel extended message by default\"\n 347:\t\tdepends on NETCONSOLE\n 348:\t\tdefault n\n 349:\t\thelp\n 350:\t\t Set extended log support for netconsole message. If this option is\n 351:\t\t set, log messages are transmitted with extended metadata header in a\n 352:\t\t format similar to /dev/kmsg. See\n 353:\t\t \u003cfile:Documentation/networking/netconsole.rst\u003e for details.\n 354:\t\n"
} |
| 9/2 | 2026/07/25 21:17 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 14187 output: 38 thoughts: 48 Thoughts: Okay, here's my take on those configurations, thinking through them myself: **Network Console Configuration Deep Dive** Right, so I'm diving into this network console setup. It looks like the key players here are `NETCONSOLE` and `NETCONSOLE_DYNAMIC` – those are the core configuration options I need to zero in on. I know that `NETCONSOLE_DYNAMIC` is essential for runtime reconfiguration, which is likely the desired functionality. And, as I suspected, I'll need `CONFIGFS_FS` enabled as well to make dynamic reconfiguration work. This is pretty standard for systems that support runtime configuration changes. Now, I should probably check the `netcons_netpoll_setup` function and other related functions. That will give me a clear idea of how all this gets wired together. Understanding the setup process is crucial to determine if this is the ideal approach for the intended application. |
| 10/2 | 2026/07/25 21:17 | tool | grepper |
0mArgs:{
"Expression": "^static int netcons_netpoll_setup",
"PathPrefix": "drivers/net/netconsole.c"
}Results: {
"Output": "drivers/net/netconsole.c=474=static bool netcons_local_ip_unset(const struct netconsole_target *nt)\n--\ndrivers/net/netconsole.c-480-\ndrivers/net/netconsole.c:481:static int netcons_netpoll_setup(struct netconsole_target *nt)\ndrivers/net/netconsole.c-482-{\n"
} |
| 11/2 | 2026/07/25 21:17 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 14569 output: 36 thoughts: 300 Thoughts: **Analyzing the New Network Console Functions** Okay, let's break this down. The key functions to keep a close eye on are: `netcons_netpoll_setup`, `netcons_take_ipv4`, `netcons_take_ipv6`, `netcons_wait_carrier`, and `netcons_egress_dev`. I know that `netpoll_udp_checksum`, `push_udp`, `push_eth`, `push_ipv4`, `push_ipv6`, and `netpoll_send_udp` are already present in the codebase. It seems they are just being adapted, with a change from 'np' to 'nt'. Now, a crucial detail: are these new functions static? Yes, they are. But they are called by functions that are not static, like `enabled_store` and `alloc_param_target`. Wait... `enabled_store` is static. It's a configfs callback. That makes sense. Let's delve into the roles of `enabled_store` and `alloc_param_target`. This is where the magic (or the potential issues) will likely lie. I need to understand how these functions interact with the new static ones and, especially, how the configfs callback plays a role. |
| 12/2 | 2026/07/25 21:17 | tool | grepper |
0mArgs:{
"Expression": "^static ssize_t enabled_store",
"PathPrefix": "drivers/net/netconsole.c"
}Results: {
"Output": "drivers/net/netconsole.c=969=static ssize_t sysdata_msgid_enabled_show(struct config_item *item,\n--\ndrivers/net/netconsole.c-988- */\ndrivers/net/netconsole.c:989:static ssize_t enabled_store(struct config_item *item,\ndrivers/net/netconsole.c-990-\t\tconst char *buf, size_t count)\n"
} |
| 13/2 | 2026/07/25 21:17 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 15293 output: 31 thoughts: 50 Thoughts: Here's my analysis of the situation: **Investigating Configfs and __setup Callbacks** Okay, so `enabled_store` is definitely tied into configfs, a crucial component for dynamic configuration in the kernel. My initial thought is to understand its behavior within that context. I need to keep that in mind, I need to know the context of its callback. Next, `alloc_param_target` is being called from `option_setup`. Ah, and `option_setup` is an `__setup` callback. That connects the dots - It's initializing something at kernel startup. Now I understand the control flow. Now, my next step is to see if there is any interesting, dynamic behavior here. Are we dealing with only static or are their any non-static functions? Let's check. That might reveal some important, non-obvious details about how this setup is actually working. I need to dig deeper. |
| 14/2 | 2026/07/25 21:17 | tool | grepper |
0mError:no matches Args: {
"Expression": "EXPORT_SYMBOL",
"PathPrefix": "drivers/net/netconsole.c"
}Results: {
"error": "no matches"
} |
| 15/2 | 2026/07/25 21:17 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 15586 output: 36 thoughts: 30 Thoughts: Okay, here's my take on those thoughts, framed as my own: **Investigating Network Console Symbol Exports** Hmm, no exported symbols coming out of `netconsole.c` – that's a bit surprising. I was expecting something there, but it seems I'm barking up the wrong tree, at least in that particular file. Time to adjust my approach. Since I'm still hunting for relevant symbols, let's pivot and see what's happening over in `net/core/netpoll.c`. I have a feeling that might be where the action is now. Perhaps some new functions are being introduced there, or some existing ones are being reworked. Gotta explore and see what's changed; that file's a likely candidate for network polling or console integration. |
| 16/2 | 2026/07/25 21:17 | tool | grepper |
0mArgs:{
"Expression": "netpoll_get_carrier_timeout",
"PathPrefix": "net/core/netpoll.c"
}Results: {
"Output": "net/core/netpoll.c-43- * netpoll.carrier_timeout module-parameter ABI. Its value is exposed to\nnet/core/netpoll.c:44: * netconsole through netpoll_get_carrier_timeout().\nnet/core/netpoll.c-45- */\n--\nnet/core/netpoll.c=47=module_param(carrier_timeout, uint, 0644);\nnet/core/netpoll.c-48-\nnet/core/netpoll.c:49:unsigned int netpoll_get_carrier_timeout(void)\nnet/core/netpoll.c-50-{\n--\nnet/core/netpoll.c-52-}\nnet/core/netpoll.c:53:EXPORT_SYMBOL_GPL(netpoll_get_carrier_timeout);\nnet/core/netpoll.c-54-\n"
} |
| 17/2 | 2026/07/25 21:17 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 16039 output: 33 thoughts: 277 Thoughts: **Analyzing Potential Focus Symbols** Okay, so `netpoll_get_carrier_timeout` is exported, that's a straightforward getter, so probably not the core of what I'm looking for. Let's dig deeper. The real meat of the recent changes seems to be in the movement of functions, so what about `netcons_netpoll_setup`? It's static, which is usually a red flag. The instructions say to prioritize non-static, non-inlined API entrypoints, but `netcons_netpoll_setup` *was* the key function that was moved. The question is, is it inlined? Looking closer, `netcons_netpoll_setup` is actually pretty large. It’s called from `resume_target`, `enabled_store`, and `alloc_param_target`, so it seems definitely not inlined. That could be a good candidate. Let's see if those calling functions give us anything more interesting. `enabled_store` is a configfs callback. Interesting. Let's also check out `alloc_param_target`. Maybe those functions themselves are what I'm after? I'll check `netconsole_target_get` or similar functions, perhaps `netconsole_target` configfs callbacks. Wait, aren't the `netconsole_target` configfs callbacks registered through `config_item_type`? Looks like a good place to start, let me check `drivers/net/netconsole.c` for `config_item_type`. |
| 18/2 | 2026/07/25 21:17 | tool | grepper |
0mArgs:{
"Expression": "config_item_type",
"PathPrefix": "drivers/net/netconsole.c"
}Results: {
"Output": "drivers/net/netconsole.c=1585=static const struct configfs_item_operations userdatum_ops = {\n--\ndrivers/net/netconsole.c-1588-\ndrivers/net/netconsole.c:1589:static const struct config_item_type userdatum_type = {\ndrivers/net/netconsole.c-1590-\t.ct_item_ops\t= \u0026userdatum_ops,\n--\ndrivers/net/netconsole.c=1640=static const struct configfs_group_operations userdata_ops = {\n--\ndrivers/net/netconsole.c-1644-\ndrivers/net/netconsole.c:1645:static const struct config_item_type userdata_type = {\ndrivers/net/netconsole.c-1646-\t.ct_item_ops\t= \u0026userdatum_ops,\n--\ndrivers/net/netconsole.c=1691=static const struct configfs_item_operations netconsole_target_item_ops = {\n--\ndrivers/net/netconsole.c-1694-\ndrivers/net/netconsole.c:1695:static const struct config_item_type netconsole_target_type = {\ndrivers/net/netconsole.c-1696-\t.ct_attrs\t\t= netconsole_target_attrs,\n--\ndrivers/net/netconsole.c=1817=static const struct configfs_group_operations netconsole_subsys_group_ops = {\n--\ndrivers/net/netconsole.c-1821-\ndrivers/net/netconsole.c:1822:static const struct config_item_type netconsole_subsys_type = {\ndrivers/net/netconsole.c-1823-\t.ct_group_ops\t= \u0026netconsole_subsys_group_ops,\n"
} |
| 19/2 | 2026/07/25 21:17 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 17133 output: 32 thoughts: 307 Thoughts: **Analyzing Netconsole Functions** Okay, let's break down these netconsole functions. My primary focus should be on `enabled_store`, `local_ip_store`, `remote_ip_store`, `alloc_param_target`, `netconsole_parser_cmdline`, and `netcons_netpoll_setup`. The goal here is to identify the crucial API entrypoints. First, a quick check to see if those functions are static. Yep, `netconsole_parser_cmdline`, `alloc_param_target`, and `enabled_store` are all static. Good. Now, are there any *non*-static ones? Ah, yes, `init_netconsole`, `netconsole_init`, and `netpoll_get_carrier_timeout` are not. Hang on... `netpoll_get_carrier_timeout` is actually exported. Interesting. The instructions emphasize preferring non-static functions as the preferred API entrypoints, over inlined static helpers. If there are no non-static functions, listing the static ones would be a reasonable backup. Let's make a note. Now, I'll turn my attention to `netconsole_init` to further evaluate the entry point options, in the context of the larger code. |
| 20/2 | 2026/07/25 21:18 | tool | grepper |
0mArgs:{
"Expression": "netconsole_init",
"PathPrefix": "drivers/net/netconsole.c"
}Results: {
"Output": "drivers/net/netconsole.c=231=static DEFINE_MUTEX(dynamic_netconsole_mutex);\ndrivers/net/netconsole.c-232-\ndrivers/net/netconsole.c:233:static int __init dynamic_netconsole_init(void)\ndrivers/net/netconsole.c-234-{\n--\ndrivers/net/netconsole.c=267=static void dynamic_netconsole_mutex_unlock(void)\n--\ndrivers/net/netconsole.c-273-\ndrivers/net/netconsole.c:274:static int __init dynamic_netconsole_init(void)\ndrivers/net/netconsole.c-275-{\n--\ndrivers/net/netconsole.c=2695=static int __init init_netconsole(void)\n--\ndrivers/net/netconsole.c-2739-\ndrivers/net/netconsole.c:2740:\terr = dynamic_netconsole_init();\ndrivers/net/netconsole.c-2741-\tif (err)\n"
} |
| 21/2 | 2026/07/25 21:18 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 18012 output: 28 thoughts: 489 Thoughts: **Analyzing the IP Configuration Migration from `netpoll` to `netconsole`** Okay, so this patch is a functional change, clearly. The core of it seems to involve moving the IP address configuration from `netpoll` to `netconsole`. Let's break this down. First, I need to list all the functions that are touched by this - it's the only way to get a solid grasp on what's changing. Alright, here's what I've got: * `netcons_netpoll_setup`, `netcons_take_ipv4`, `netcons_take_ipv6`, `netcons_wait_carrier`, `netcons_egress_dev` - these look like the primary interface changes within the `netconsole` side, and are the crucial methods. * `netpoll_udp_checksum`, `push_udp`, `push_eth`, `push_ipv4`, `push_ipv6`, `netpoll_send_udp` - these are the network packet sending functions which also need to be reconfigured. * `netconsole_parser_cmdline`, `alloc_param_target`, `enabled_store`, `local_ip_store`, `remote_ip_store` - these deal with the configuration parameters and their handling. Now, which ones are the *really* important ones? Okay, narrowing it down, the key ones are definitely `netcons_netpoll_setup`, the `take_ipv4` and `take_ipv6` methods because they are responsible for moving the configuration around, plus the `enabled_store`, `local_ip_store`, `remote_ip_store` and `alloc_param_target` because they deal with storing the parameters. And, the `netconsole_parser_cmdline` because it handles the command line. Now, let's consider the configuration options that must be enabled. I know `NETCONSOLE` is the central one, with `NETCONSOLE_DYNAMIC` being crucial if we want dynamic IP assignment. Of course, `NETPOLL` is selected automatically by `NETCONSOLE`. And, we will need `CONFIGFS_FS` for the dynamic configuration, and `IPV6` for the ipv6 features. Checking the dependencies, `NETCONSOLE` depends on `PRINTK`, and `NETCONSOLE_DYNAMIC` depends on `NETCONSOLE && SYSFS && CONFIGFS_FS`. This is all pretty straightforward. I should also check `NETPOLL` directly in `net/Kconfig` to be absolutely certain I understand its interaction. |
| 22/2 | 2026/07/25 21:18 | tool | grepper |
0mError:no matches Args: {
"Expression": "config NETPOLL",
"PathPrefix": "net/Kconfig"
}Results: {
"error": "no matches"
} |
| 23/2 | 2026/07/25 21:18 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 19087 output: 24 thoughts: 13 Thoughts: Here's my thought process, as requested: **Tracing the Source: NETPOLL's Definition** Okay, so I need to figure out exactly *where* `NETPOLL` is defined. This could be a macro, a constant, a variable, or even a function, depending on the context. Knowing its definition is absolutely crucial for understanding its role in the system. I'm going to start with the obvious first: I'll need to use my usual tools - `grep`, `find`, or whatever IDE-integrated search I'm comfortable with. I'll need to be precise, ensuring that I don't accidentally match something that *contains* `NETPOLL` but isn't the definition itself. I will look for include files or relevant header files where this might be defined. I'm hoping I can quickly pinpoint the exact file and line number. Once I've got that, I can trace its usage, see how it's used with other symbols, and ultimately, understand what it's controlling. Knowing this will give me a better understanding of how the code works. |
| 24/2 | 2026/07/25 21:18 | tool | grepper |
0mArgs:{
"Expression": "config NETPOLL",
"PathPrefix": ""
}Results: {
"Output": "drivers/net/Kconfig=355=config NETCONSOLE_PREPEND_RELEASE\n--\ndrivers/net/Kconfig-366-\ndrivers/net/Kconfig:367:config NETPOLL\ndrivers/net/Kconfig-368-\tdef_bool NETCONSOLE\n"
} |
| 25/2 | 2026/07/25 21:18 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 19436 output: 32 thoughts: 46 Thoughts: Okay, here's my take on those thoughts, framed as my own: **Investigating Network Configuration Options** Right, so I'm digging into network configuration options, and the first clue is that `NETPOLL` seems to be defined in `drivers/net/Kconfig`. That's not entirely surprising, given its name. And the default value looks like it's tied to `NETCONSOLE`. Need to keep that relationship in mind as I go forward. Now, I also want to double-check whether `CONFIGFS_FS` has any influence on the network subsystem. Let's see what's defined in `fs/configfs/Kconfig`. I'll cross-reference the dependencies to get a clearer picture of how everything interacts. Might be something useful there. |
| 26/2 | 2026/07/25 21:18 | tool | grepper |
0mArgs:{
"Expression": "config CONFIGFS_FS",
"PathPrefix": "fs/configfs/Kconfig"
}Results: {
"Output": "fs/configfs/Kconfig-1-# SPDX-License-Identifier: GPL-2.0-only\nfs/configfs/Kconfig:2:config CONFIGFS_FS\nfs/configfs/Kconfig-3-\ttristate \"Userspace-driven configuration filesystem\"\n"
} |
| 27/2 | 2026/07/25 21:18 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 19756 output: 219 thoughts: 365 Thoughts: **My Fuzzing Strategy for the Netconsole Refactor**
Okay, so I've been looking at this netconsole refactor and figuring out the best way to approach fuzzing it. First, I see that `CONFIGFS_FS` is a tristate, meaning it's something we can toggle. Based on that, I'm going to enable `NETCONSOLE`, `NETCONSOLE_DYNAMIC`, `CONFIGFS_FS`, and `IPV6` as a baseline. That should give us the most flexibility in our testing.
Let me see... Anything else to consider for enabling? Ah, `NETCONSOLE_EXTENDED_LOG`. Not strictly critical, but potentially useful to have for debugging, so I'll include it. `NETCONSOLE_PREPEND_RELEASE`? No, not essential for fuzzing.
Now, the important part: reachability. We need to make sure the functions we want to target are actually accessible. Let's see... `netcons_netpoll_setup`... yep, looks like it's reachable through `enabled_store`, which is a configfs callback. Excellent! That means Syzkaller can mount configfs and write to the `enabled` file, triggering the relevant code paths.
So, here's the fuzzing strategy I'm going to propose:
* **WorthFuzzing: True** (Absolutely!)
* **FocusSymbols:** I'm going to target these functions specifically:
* `netcons_netpoll_setup`
* `netcons_take_ipv4`
* `netcons_take_ipv6`
* `enabled_store`
* `local_ip_store`
* `remote_ip_store`
* `alloc_param_target`
* `netconsole_parser_cmdline`
* `netpoll_send_udp`
* **EnableConfigs:** Again, just to reiterate:
* `NETCONSOLE`
* `NETCONSOLE_DYNAMIC`
* `CONFIGFS_FS`
* `IPV6`
**Reasoning:** The patch fundamentally refactors netconsole and netpoll, moving crucial IP address configuration and setup logic to the netconsole target. New functions like `netcons_netpoll_setup`, `netcons_take_ipv4`, and `netcons_take_ipv6` are introduced. The changes are functional and easily reachable through configfs (for the dynamic netconsole feature) and module parameters. That makes them excellent candidates for fuzzing, and I think this configuration will give us the best chance of finding any vulnerabilities.
|
| 28/2 | 2026/07/25 21:18 | tool | set-results |
0mArgs:{
"EnableConfigs": [
"NETCONSOLE",
"NETCONSOLE_DYNAMIC",
"CONFIGFS_FS",
"IPV6"
],
"FocusSymbols": [
"netcons_netpoll_setup",
"netcons_take_ipv4",
"netcons_take_ipv6",
"enabled_store",
"local_ip_store",
"remote_ip_store",
"alloc_param_target",
"netconsole_parser_cmdline",
"netpoll_send_udp"
],
"Reasoning": "The patch refactors netconsole and netpoll by moving IP address configuration and setup logic from the generic netpoll structure to the netconsole target. It introduces new functions like `netcons_netpoll_setup`, `netcons_take_ipv4`, and `netcons_take_ipv6`. These changes are functional and reachable via configfs (dynamic netconsole) and module parameters, making them suitable for fuzzing.",
"WorthFuzzing": true
}Results: {
"EnableConfigs": [
"NETCONSOLE",
"NETCONSOLE_DYNAMIC",
"CONFIGFS_FS",
"IPV6"
],
"FocusSymbols": [
"netcons_netpoll_setup",
"netcons_take_ipv4",
"netcons_take_ipv6",
"enabled_store",
"local_ip_store",
"remote_ip_store",
"alloc_param_target",
"netconsole_parser_cmdline",
"netpoll_send_udp"
],
"Reasoning": "The patch refactors netconsole and netpoll by moving IP address configuration and setup logic from the generic netpoll structure to the netconsole target. It introduces new functions like `netcons_netpoll_setup`, `netcons_take_ipv4`, and `netcons_take_ipv6`. These changes are functional and reachable via configfs (dynamic netconsole) and module parameters, making them suitable for fuzzing.",
"WorthFuzzing": true
} |
| Total Calls | Total Tokens | Avg Tokens | Total Duration (Seconds) | Avg Duration (Seconds) |
|---|
| Total Calls | Total Duration (Seconds) | Avg Duration (Seconds) |
|---|