| Seq | Timestamp | Type | Name | Duration |
|---|---|---|---|---|
| 0/0 | 2026/07/27 16:15 | flow | patch-triage |
0mArgs:null Results: {
"EnableConfigs": null,
"FocusSymbols": [],
"Reasoning": "The patch only modifies a user-space selftest (tools/testing/selftests/net/ipv6_flowlabel_mgr.c) and makes no functional changes to the kernel code itself.",
"WorthFuzzing": false
} |
| 1/1 | 2026/07/27 16:15 | action | read-patch-diff |
0mArgs:null Results: {
"PatchDiff": "commit 4ea546b937941115a03afccd7661219a1fb614ee\nAuthor: syz-cluster \u003ctriage@syzkaller.com\u003e\nDate: Mon Jul 27 16:15:58 2026 +0000\n\n syz-cluster: applied patch under review\n\ndiff --git a/tools/testing/selftests/net/ipv6_flowlabel_mgr.c b/tools/testing/selftests/net/ipv6_flowlabel_mgr.c\nindex af95b48acea90b..9aa5c8146f1719 100644\n--- a/tools/testing/selftests/net/ipv6_flowlabel_mgr.c\n+++ b/tools/testing/selftests/net/ipv6_flowlabel_mgr.c\n@@ -6,6 +6,7 @@\n #include \u003carpa/inet.h\u003e\n #include \u003cerror.h\u003e\n #include \u003cerrno.h\u003e\n+#include \u003cfcntl.h\u003e\n #include \u003climits.h\u003e\n #include \u003clinux/in6.h\u003e\n #include \u003cstdbool.h\u003e\n@@ -19,31 +20,25 @@\n #include \u003csys/types.h\u003e\n #include \u003csys/wait.h\u003e\n #include \u003cunistd.h\u003e\n+#include \"kselftest_harness.h\"\n \n /* uapi/glibc weirdness may leave this undefined */\n #ifndef IPV6_FLOWLABEL_MGR\n #define IPV6_FLOWLABEL_MGR\t32\n #endif\n+#ifndef IPV6_FLOWINFO_SEND\n+#define IPV6_FLOWINFO_SEND\t33\n+#endif\n \n /* from net/ipv6/ip6_flowlabel.c */\n #define FL_MIN_LINGER\t\t6\n \n-#define explain(x)\t\t\t\t\t\t\t\\\n-\tdo { if (cfg_verbose) fprintf(stderr, \" \" x \"\\n\"); } while (0)\n-\n-#define __expect(x)\t\t\t\t\t\t\t\\\n-\tdo {\t\t\t\t\t\t\t\t\\\n-\t\tif (!(x))\t\t\t\t\t\t\\\n-\t\t\tfprintf(stderr, \"[OK] \" #x \"\\n\");\t\t\\\n-\t\telse\t\t\t\t\t\t\t\\\n-\t\t\terror(1, 0, \"[ERR] \" #x \" (line %d)\", __LINE__); \\\n-\t} while (0)\n-\n-#define expect_pass(x)\t__expect(x)\n-#define expect_fail(x)\t__expect(!(x))\n-\n-static bool cfg_long_running;\n-static bool cfg_verbose;\n+#define INIT_SIN6_LOOPBACK(name)\t\t\t\t\t\\\n+\tstruct sockaddr_in6 name = {\t\t\t\t\t\\\n+\t\t.sin6_family\t= AF_INET6,\t\t\t\t\\\n+\t\t.sin6_addr\t= IN6ADDR_LOOPBACK_INIT,\t\t\\\n+\t\t.sin6_port\t= htons(8888),\t\t\t\t\\\n+\t}\n \n static int flowlabel_get(int fd, uint32_t label, uint8_t share, uint16_t flags)\n {\n@@ -71,129 +66,344 @@ static int flowlabel_put(int fd, uint32_t label)\n \treturn setsockopt(fd, SOL_IPV6, IPV6_FLOWLABEL_MGR, \u0026req, sizeof(req));\n }\n \n-static void run_tests(int fd)\n+static int flowlabel_renew(int fd, uint32_t label, uint16_t linger)\n+{\n+\tstruct in6_flowlabel_req req = {\n+\t\t.flr_action = IPV6_FL_A_RENEW,\n+\t\t.flr_label = htonl(label),\n+\t\t.flr_linger = linger,\n+\t};\n+\n+\treturn setsockopt(fd, SOL_IPV6, IPV6_FLOWLABEL_MGR, \u0026req, sizeof(req));\n+}\n+\n+static int tcp_listen(void)\n+{\n+\tINIT_SIN6_LOOPBACK(addr);\n+\tconst int one = 1;\n+\tint fd;\n+\n+\tfd = socket(PF_INET6, SOCK_STREAM, 0);\n+\tif (fd == -1)\n+\t\terror(1, errno, \"socket listener\");\n+\tif (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, \u0026one, sizeof(one)))\n+\t\terror(1, errno, \"setsockopt SO_REUSEADDR\");\n+\tif (bind(fd, (void *)\u0026addr, sizeof(addr)))\n+\t\terror(1, errno, \"bind\");\n+\tif (listen(fd, 1))\n+\t\terror(1, errno, \"listen\");\n+\n+\treturn fd;\n+}\n+\n+static void tcp_connect(int listener, uint32_t flowlabel, int *client, int *accepted)\n+{\n+\tINIT_SIN6_LOOPBACK(addr);\n+\tconst int one = 1;\n+\tint cfd, afd;\n+\n+\tcfd = socket(PF_INET6, SOCK_STREAM, 0);\n+\tif (cfd == -1)\n+\t\terror(1, errno, \"socket client\");\n+\n+\tif (flowlabel_get(cfd, flowlabel, IPV6_FL_S_EXCL, IPV6_FL_F_CREATE))\n+\t\terror(1, errno, \"flowlabel_get\");\n+\tif (setsockopt(cfd, SOL_IPV6, IPV6_FLOWINFO_SEND, \u0026one, sizeof(one)))\n+\t\terror(1, errno, \"setsockopt flowinfo_send\");\n+\taddr.sin6_flowinfo = htonl(flowlabel);\n+\n+\tif (connect(cfd, (void *)\u0026addr, sizeof(addr)))\n+\t\terror(1, errno, \"connect\");\n+\n+\tafd = accept(listener, NULL, NULL);\n+\tif (afd == -1)\n+\t\terror(1, errno, \"accept\");\n+\n+\t*client = cfd;\n+\t*accepted = afd;\n+}\n+\n+static void set_flowlabel_consistency(bool enable)\n+{\n+\t/* flowlabel_consistency must be disable to use the IPV6_FL_F_REFLECT\n+\t * flag. This helper function is required for setting up and tearing\n+\t * down test cases for this flag.\n+\t */\n+\tint fd;\n+\n+\tfd = open(\"/proc/sys/net/ipv6/flowlabel_consistency\", O_WRONLY);\n+\tif (fd == -1)\n+\t\terror(1, errno, \"open flowlabel_consistency\");\n+\tif (write(fd, enable ? \"1\" : \"0\", 1) != 1)\n+\t\terror(1, errno, \"write flowlabel_consistency\");\n+\tif (close(fd))\n+\t\terror(1, errno, \"close flowlabel_consistency\");\n+}\n+\n+TEST(cannot_get_non_existent_label)\n+{\n+\tint fd, err;\n+\n+\tfd = socket(PF_INET6, SOCK_DGRAM, 0);\n+\tASSERT_GE(fd, 0) TH_LOG(\"socket failed\");\n+\n+\terr = flowlabel_get(fd, 1, IPV6_FL_S_ANY, 0);\n+\tASSERT_TRUE(err) TH_LOG(\"expected get of a non-existent label to fail\");\n+\n+\tASSERT_EQ(0, close(fd));\n+}\n+\n+TEST(cannot_put_non_existent_label)\n+{\n+\tint fd, err;\n+\n+\tfd = socket(PF_INET6, SOCK_DGRAM, 0);\n+\tASSERT_GE(fd, 0) TH_LOG(\"socket failed\");\n+\n+\terr = flowlabel_put(fd, 1);\n+\tASSERT_TRUE(err) TH_LOG(\"expected put of a non-existent label to fail\");\n+\n+\tASSERT_EQ(0, close(fd));\n+}\n+\n+TEST(cannot_create_label_greater_than_20_bits)\n+{\n+\tint fd, err;\n+\n+\tfd = socket(PF_INET6, SOCK_DGRAM, 0);\n+\tASSERT_GE(fd, 0) TH_LOG(\"socket failed\");\n+\n+\terr = flowlabel_get(fd, 0x1FFFFF, IPV6_FL_S_ANY, IPV6_FL_F_CREATE);\n+\tASSERT_TRUE(err) TH_LOG(\"expected label \u003e 20 bits to be rejected\");\n+\n+\tASSERT_EQ(0, close(fd));\n+}\n+\n+TEST(can_create_and_get_and_put_labels)\n+{\n+\tint fd, err;\n+\n+\tfd = socket(PF_INET6, SOCK_DGRAM, 0);\n+\tASSERT_GE(fd, 0) TH_LOG(\"socket failed\");\n+\n+\terr = flowlabel_get(fd, 1, IPV6_FL_S_ANY, IPV6_FL_F_CREATE);\n+\tASSERT_TRUE(!err) TH_LOG(\"failed to create label (FL_F_CREATE)\");\n+\n+\terr = flowlabel_get(fd, 1, IPV6_FL_S_ANY, 0);\n+\tASSERT_TRUE(!err) TH_LOG(\"failed to get the label without FL_F_CREATE\");\n+\n+\terr = flowlabel_get(fd, 1, IPV6_FL_S_ANY, IPV6_FL_F_CREATE);\n+\tASSERT_TRUE(!err) TH_LOG(\"failed to get it again with create flag set, too\");\n+\n+\terr = flowlabel_get(fd, 1, IPV6_FL_S_ANY, IPV6_FL_F_CREATE | IPV6_FL_F_EXCL);\n+\tASSERT_TRUE(err) TH_LOG(\"expected FL_F_EXCL to reject an already-existing label\");\n+\n+\terr = flowlabel_put(fd, 1);\n+\tASSERT_TRUE(!err) TH_LOG(\"failed to put first reference\");\n+\terr = flowlabel_put(fd, 1);\n+\tASSERT_TRUE(!err) TH_LOG(\"failed to put second reference\");\n+\terr = flowlabel_put(fd, 1);\n+\tASSERT_TRUE(!err) TH_LOG(\"failed to put third reference\");\n+\terr = flowlabel_put(fd, 1);\n+\tASSERT_TRUE(err) TH_LOG(\"expected fourth put to fail, no references left\");\n+\n+\tASSERT_EQ(0, close(fd));\n+}\n+\n+TEST(exclusive_label_share)\n {\n-\tint wstatus;\n+\tint fd, err;\n+\n+\tfd = socket(PF_INET6, SOCK_DGRAM, 0);\n+\tASSERT_GE(fd, 0) TH_LOG(\"socket failed\");\n+\n+\terr = flowlabel_get(fd, 2, IPV6_FL_S_EXCL, IPV6_FL_F_CREATE);\n+\tASSERT_TRUE(!err) TH_LOG(\"failed to create a new exclusive label (FL_S_EXCL)\");\n+\n+\terr = flowlabel_get(fd, 2, IPV6_FL_S_ANY, IPV6_FL_F_CREATE);\n+\tASSERT_TRUE(err) TH_LOG(\"expected reuse in non-exclusive mode to fail\");\n+\n+\terr = flowlabel_get(fd, 2, IPV6_FL_S_EXCL, IPV6_FL_F_CREATE);\n+\tASSERT_TRUE(err) TH_LOG(\"expected reuse in exclusive mode to fail too\");\n+\n+\terr = flowlabel_put(fd, 2);\n+\tASSERT_TRUE(!err) TH_LOG(\"failed to put the exclusive label\");\n+\n+\terr = flowlabel_get(fd, 2, IPV6_FL_S_ANY, IPV6_FL_F_CREATE);\n+\tASSERT_TRUE(err) TH_LOG(\"expected reuse to fail, due to linger\");\n+\n+\tsleep(FL_MIN_LINGER * 2 + 1);\n+\n+\terr = flowlabel_get(fd, 2, IPV6_FL_S_ANY, IPV6_FL_F_CREATE);\n+\tASSERT_TRUE(!err) TH_LOG(\"expected reuse to succeed after linger\");\n+\n+\tASSERT_EQ(0, close(fd));\n+}\n+\n+TEST(user_private_label_share)\n+{\n+\tint fd, err, wstatus;\n \tpid_t pid;\n \n-\texplain(\"cannot get non-existent label\");\n-\texpect_fail(flowlabel_get(fd, 1, IPV6_FL_S_ANY, 0));\n-\n-\texplain(\"cannot put non-existent label\");\n-\texpect_fail(flowlabel_put(fd, 1));\n-\n-\texplain(\"cannot create label greater than 20 bits\");\n-\texpect_fail(flowlabel_get(fd, 0x1FFFFF, IPV6_FL_S_ANY,\n-\t\t\t\t IPV6_FL_F_CREATE));\n-\n-\texplain(\"create a new label (FL_F_CREATE)\");\n-\texpect_pass(flowlabel_get(fd, 1, IPV6_FL_S_ANY, IPV6_FL_F_CREATE));\n-\texplain(\"can get the label (without FL_F_CREATE)\");\n-\texpect_pass(flowlabel_get(fd, 1, IPV6_FL_S_ANY, 0));\n-\texplain(\"can get it again with create flag set, too\");\n-\texpect_pass(flowlabel_get(fd, 1, IPV6_FL_S_ANY, IPV6_FL_F_CREATE));\n-\texplain(\"cannot get it again with the exclusive (FL_FL_EXCL) flag\");\n-\texpect_fail(flowlabel_get(fd, 1, IPV6_FL_S_ANY,\n-\t\t\t\t\t IPV6_FL_F_CREATE | IPV6_FL_F_EXCL));\n-\texplain(\"can now put exactly three references\");\n-\texpect_pass(flowlabel_put(fd, 1));\n-\texpect_pass(flowlabel_put(fd, 1));\n-\texpect_pass(flowlabel_put(fd, 1));\n-\texpect_fail(flowlabel_put(fd, 1));\n-\n-\texplain(\"create a new exclusive label (FL_S_EXCL)\");\n-\texpect_pass(flowlabel_get(fd, 2, IPV6_FL_S_EXCL, IPV6_FL_F_CREATE));\n-\texplain(\"cannot get it again in non-exclusive mode\");\n-\texpect_fail(flowlabel_get(fd, 2, IPV6_FL_S_ANY, IPV6_FL_F_CREATE));\n-\texplain(\"cannot get it again in exclusive mode either\");\n-\texpect_fail(flowlabel_get(fd, 2, IPV6_FL_S_EXCL, IPV6_FL_F_CREATE));\n-\texpect_pass(flowlabel_put(fd, 2));\n-\n-\tif (cfg_long_running) {\n-\t\texplain(\"cannot reuse the label, due to linger\");\n-\t\texpect_fail(flowlabel_get(fd, 2, IPV6_FL_S_ANY,\n-\t\t\t\t\t IPV6_FL_F_CREATE));\n-\t\texplain(\"after sleep, can reuse\");\n-\t\tsleep(FL_MIN_LINGER * 2 + 1);\n-\t\texpect_pass(flowlabel_get(fd, 2, IPV6_FL_S_ANY,\n-\t\t\t\t\t IPV6_FL_F_CREATE));\n-\t}\n+\tfd = socket(PF_INET6, SOCK_DGRAM, 0);\n+\tASSERT_GE(fd, 0) TH_LOG(\"socket failed\");\n+\n+\terr = flowlabel_get(fd, 3, IPV6_FL_S_USER, IPV6_FL_F_CREATE);\n+\tASSERT_TRUE(!err) TH_LOG(\"failed to create a new user-private label (FL_S_USER)\");\n+\n+\terr = flowlabel_get(fd, 3, IPV6_FL_S_ANY, 0);\n+\tASSERT_TRUE(err) TH_LOG(\"expected get in non-exclusive mode to fail\");\n+\n+\terr = flowlabel_get(fd, 3, IPV6_FL_S_EXCL, 0);\n+\tASSERT_TRUE(err) TH_LOG(\"expected get in exclusive mode to fail\");\n+\n+\terr = flowlabel_get(fd, 3, IPV6_FL_S_USER, 0);\n+\tASSERT_TRUE(!err) TH_LOG(\"failed to get it again in user mode\");\n \n-\texplain(\"create a new user-private label (FL_S_USER)\");\n-\texpect_pass(flowlabel_get(fd, 3, IPV6_FL_S_USER, IPV6_FL_F_CREATE));\n-\texplain(\"cannot get it again in non-exclusive mode\");\n-\texpect_fail(flowlabel_get(fd, 3, IPV6_FL_S_ANY, 0));\n-\texplain(\"cannot get it again in exclusive mode\");\n-\texpect_fail(flowlabel_get(fd, 3, IPV6_FL_S_EXCL, 0));\n-\texplain(\"can get it again in user mode\");\n-\texpect_pass(flowlabel_get(fd, 3, IPV6_FL_S_USER, 0));\n-\texplain(\"child process can get it too, but not after setuid(nobody)\");\n \tpid = fork();\n-\tif (pid == -1)\n-\t\terror(1, errno, \"fork\");\n+\tASSERT_NE(-1, pid) TH_LOG(\"fork failed\");\n \tif (!pid) {\n-\t\texpect_pass(flowlabel_get(fd, 3, IPV6_FL_S_USER, 0));\n-\t\tif (setuid(USHRT_MAX))\n+\t\tif (flowlabel_get(fd, 3, IPV6_FL_S_USER, 0))\n+\t\t\texit(1);\n+\t\tif (setuid(USHRT_MAX)) {\n \t\t\tfprintf(stderr, \"[INFO] skip setuid child test\\n\");\n-\t\telse\n-\t\t\texpect_fail(flowlabel_get(fd, 3, IPV6_FL_S_USER, 0));\n+\t\t\texit(0);\n+\t\t}\n+\t\tif (!flowlabel_get(fd, 3, IPV6_FL_S_USER, 0))\n+\t\t\texit(1);\n \t\texit(0);\n \t}\n-\tif (wait(\u0026wstatus) == -1)\n-\t\terror(1, errno, \"wait\");\n-\tif (!WIFEXITED(wstatus) || WEXITSTATUS(wstatus) != 0)\n-\t\terror(1, errno, \"wait: unexpected child result\");\n-\n-\texplain(\"create a new process-private label (FL_S_PROCESS)\");\n-\texpect_pass(flowlabel_get(fd, 4, IPV6_FL_S_PROCESS, IPV6_FL_F_CREATE));\n-\texplain(\"can get it again\");\n-\texpect_pass(flowlabel_get(fd, 4, IPV6_FL_S_PROCESS, 0));\n-\texplain(\"child process cannot can get it\");\n+\tASSERT_EQ(pid, wait(\u0026wstatus)) TH_LOG(\"wait failed\");\n+\tASSERT_TRUE(WIFEXITED(wstatus)) TH_LOG(\"child did not exit normally\");\n+\tASSERT_EQ(0, WEXITSTATUS(wstatus)) TH_LOG(\"child reported unexpected result\");\n+\n+\tASSERT_EQ(0, close(fd));\n+}\n+\n+TEST(process_private_label_share)\n+{\n+\tint fd, err, wstatus;\n+\tpid_t pid;\n+\n+\tfd = socket(PF_INET6, SOCK_DGRAM, 0);\n+\tASSERT_GE(fd, 0) TH_LOG(\"socket failed\");\n+\n+\terr = flowlabel_get(fd, 4, IPV6_FL_S_PROCESS, IPV6_FL_F_CREATE);\n+\tASSERT_TRUE(!err) TH_LOG(\"failed to create a new process-private label (FL_S_PROCESS)\");\n+\n+\terr = flowlabel_get(fd, 4, IPV6_FL_S_PROCESS, 0);\n+\tASSERT_TRUE(!err) TH_LOG(\"failed to get it again\");\n+\n \tpid = fork();\n-\tif (pid == -1)\n-\t\terror(1, errno, \"fork\");\n+\tASSERT_NE(-1, pid) TH_LOG(\"fork failed\");\n \tif (!pid) {\n-\t\texpect_fail(flowlabel_get(fd, 4, IPV6_FL_S_PROCESS, 0));\n+\t\tif (!flowlabel_get(fd, 4, IPV6_FL_S_PROCESS, 0))\n+\t\t\texit(1);\n \t\texit(0);\n \t}\n-\tif (wait(\u0026wstatus) == -1)\n-\t\terror(1, errno, \"wait\");\n-\tif (!WIFEXITED(wstatus) || WEXITSTATUS(wstatus) != 0)\n-\t\terror(1, errno, \"wait: unexpected child result\");\n-}\n-\n-static void parse_opts(int argc, char **argv)\n-{\n-\tint c;\n-\n-\twhile ((c = getopt(argc, argv, \"lv\")) != -1) {\n-\t\tswitch (c) {\n-\t\tcase 'l':\n-\t\t\tcfg_long_running = true;\n-\t\t\tbreak;\n-\t\tcase 'v':\n-\t\t\tcfg_verbose = true;\n-\t\t\tbreak;\n-\t\tdefault:\n-\t\t\terror(1, 0, \"%s: parse error\", argv[0]);\n-\t\t}\n-\t}\n+\tASSERT_EQ(pid, wait(\u0026wstatus)) TH_LOG(\"wait failed\");\n+\tASSERT_TRUE(WIFEXITED(wstatus)) TH_LOG(\"child did not exit normally\");\n+\tASSERT_EQ(0, WEXITSTATUS(wstatus)) TH_LOG(\"child reported unexpected result\");\n+\n+\tASSERT_EQ(0, close(fd));\n }\n \n-int main(int argc, char **argv)\n+TEST(renew_label_linger)\n {\n-\tint fd;\n-\n-\tparse_opts(argc, argv);\n+\t/* After a label with EXCL share is put and lingered, it must be\n+\t * possible to create a new one. Check if RENEW action extends\n+\t * the linger period of put label, blocking creation after previous\n+\t * linger time.\n+\t */\n+\tint fd, err;\n \n \tfd = socket(PF_INET6, SOCK_DGRAM, 0);\n-\tif (fd == -1)\n-\t\terror(1, errno, \"socket\");\n+\tASSERT_GE(fd, 0) TH_LOG(\"socket failed\");\n \n-\trun_tests(fd);\n+\terr = flowlabel_get(fd, 5, IPV6_FL_S_EXCL, IPV6_FL_F_CREATE);\n+\tASSERT_TRUE(!err) TH_LOG(\"failed to create a new label with FL_MIN_LINGER linger time\");\n \n-\tif (close(fd))\n-\t\terror(1, errno, \"close\");\n+\terr = flowlabel_renew(fd, 5, 2 * (FL_MIN_LINGER * 2 + 1));\n+\tASSERT_TRUE(!err) TH_LOG(\"failed to renew the label to increase its linger time\");\n+\n+\terr = flowlabel_put(fd, 5);\n+\tASSERT_TRUE(!err) TH_LOG(\"failed to put the label\");\n \n-\treturn 0;\n+\tsleep(FL_MIN_LINGER * 2 + 1);\n+\n+\terr = flowlabel_get(fd, 5, IPV6_FL_S_ANY, IPV6_FL_F_CREATE);\n+\tASSERT_TRUE(err) TH_LOG(\"expected reuse to fail, new linger time not over yet\");\n+\n+\tASSERT_EQ(0, close(fd));\n }\n+\n+TEST(remote_flag)\n+{\n+\t/* The REMOTE flag, used for getsockopt, is expected to retrieve the\n+\t * label from the latest received header.\n+\t */\n+\tstruct in6_flowlabel_req freq = {\n+\t\t.flr_action = IPV6_FL_A_GET,\n+\t\t.flr_flags = IPV6_FL_F_REMOTE,\n+\t};\n+\tsocklen_t freq_len = sizeof(freq);\n+\tint listener, cfd, afd, err;\n+\n+\tlistener = tcp_listen();\n+\ttcp_connect(listener, 6, \u0026cfd, \u0026afd);\n+\n+\terr = getsockopt(afd, SOL_IPV6, IPV6_FLOWLABEL_MGR, \u0026freq, \u0026freq_len);\n+\tASSERT_TRUE(!err) TH_LOG(\"getsockopt with IPV6_FL_F_REMOTE failed\");\n+\tASSERT_EQ(6, ntohl(freq.flr_label)) TH_LOG(\"unexpected remote flow label\");\n+\n+\tASSERT_EQ(0, close(afd));\n+\tASSERT_EQ(0, close(cfd));\n+\tASSERT_EQ(0, close(listener));\n+}\n+\n+TEST(reflect_flag)\n+{\n+\t/* The REFLECT flag acts as a trigger to the REPFLOW bit. When REPFLOW\n+\t * is triggered for a socket, it adopts the label received from the\n+\t * connected socket.\n+\t */\n+\tstruct in6_flowlabel_req reflect_on = {\n+\t\t.flr_action = IPV6_FL_A_GET,\n+\t\t.flr_flags = IPV6_FL_F_REFLECT,\n+\t};\n+\tstruct in6_flowlabel_req reflect_query = {\n+\t\t.flr_action = IPV6_FL_A_GET,\n+\t};\n+\tstruct in6_flowlabel_req reflect_off = {\n+\t\t.flr_action = IPV6_FL_A_PUT,\n+\t\t.flr_flags = IPV6_FL_F_REFLECT,\n+\t};\n+\tsocklen_t reflect_query_len = sizeof(reflect_query);\n+\tint listener, cfd, afd, err;\n+\n+\tset_flowlabel_consistency(false);\n+\n+\tlistener = tcp_listen();\n+\terr = setsockopt(listener, SOL_IPV6, IPV6_FLOWLABEL_MGR, \u0026reflect_on, sizeof(reflect_on));\n+\tASSERT_TRUE(!err) TH_LOG(\"failed to enable REFLECT on the listener\");\n+\n+\ttcp_connect(listener, 7, \u0026cfd, \u0026afd);\n+\n+\terr = getsockopt(afd, SOL_IPV6, IPV6_FLOWLABEL_MGR, \u0026reflect_query, \u0026reflect_query_len);\n+\tASSERT_TRUE(!err) TH_LOG(\"failed to query the accepted socket's outgoing label\");\n+\tASSERT_EQ(7, ntohl(reflect_query.flr_label)) TH_LOG(\"accepted socket did not reflect client's label\");\n+\n+\terr = setsockopt(afd, SOL_IPV6, IPV6_FLOWLABEL_MGR, \u0026reflect_off, sizeof(reflect_off));\n+\tASSERT_TRUE(!err) TH_LOG(\"failed to disable REFLECT on the accepted socket\");\n+\n+\terr = setsockopt(afd, SOL_IPV6, IPV6_FLOWLABEL_MGR, \u0026reflect_off, sizeof(reflect_off));\n+\tASSERT_TRUE(err) TH_LOG(\"expected disabling REFLECT twice to fail\");\n+\n+\tset_flowlabel_consistency(true);\n+\n+\tASSERT_EQ(0, close(afd));\n+\tASSERT_EQ(0, close(cfd));\n+\tASSERT_EQ(0, close(listener));\n+}\n+\n+TEST_HARNESS_MAIN\n"
} |
| 2/1 | 2026/07/27 16:16 | agent | patch-evaluator |
0mModel:best-expensive Args: null Results: {
"EnableConfigs": null,
"FocusSymbols": [],
"Reasoning": "The patch only modifies a user-space selftest (tools/testing/selftests/net/ipv6_flowlabel_mgr.c) and makes no functional changes to the kernel code itself.",
"WorthFuzzing": false
}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 4ea546b937941115a03afccd7661219a1fb614ee
Author: syz-cluster <triage@syzkaller.com>
Date: Mon Jul 27 16:15:58 2026 +0000
syz-cluster: applied patch under review
diff --git a/tools/testing/selftests/net/ipv6_flowlabel_mgr.c b/tools/testing/selftests/net/ipv6_flowlabel_mgr.c
index af95b48acea90b..9aa5c8146f1719 100644
--- a/tools/testing/selftests/net/ipv6_flowlabel_mgr.c
+++ b/tools/testing/selftests/net/ipv6_flowlabel_mgr.c
@@ -6,6 +6,7 @@
#include <arpa/inet.h>
#include <error.h>
#include <errno.h>
+#include <fcntl.h>
#include <limits.h>
#include <linux/in6.h>
#include <stdbool.h>
@@ -19,31 +20,25 @@
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
+#include "kselftest_harness.h"
/* uapi/glibc weirdness may leave this undefined */
#ifndef IPV6_FLOWLABEL_MGR
#define IPV6_FLOWLABEL_MGR 32
#endif
+#ifndef IPV6_FLOWINFO_SEND
+#define IPV6_FLOWINFO_SEND 33
+#endif
/* from net/ipv6/ip6_flowlabel.c */
#define FL_MIN_LINGER 6
-#define explain(x) \
- do { if (cfg_verbose) fprintf(stderr, " " x "\n"); } while (0)
-
-#define __expect(x) \
- do { \
- if (!(x)) \
- fprintf(stderr, "[OK] " #x "\n"); \
- else \
- error(1, 0, "[ERR] " #x " (line %d)", __LINE__); \
- } while (0)
-
-#define expect_pass(x) __expect(x)
-#define expect_fail(x) __expect(!(x))
-
-static bool cfg_long_running;
-static bool cfg_verbose;
+#define INIT_SIN6_LOOPBACK(name) \
+ struct sockaddr_in6 name = { \
+ .sin6_family = AF_INET6, \
+ .sin6_addr = IN6ADDR_LOOPBACK_INIT, \
+ .sin6_port = htons(8888), \
+ }
static int flowlabel_get(int fd, uint32_t label, uint8_t share, uint16_t flags)
{
@@ -71,129 +66,344 @@ static int flowlabel_put(int fd, uint32_t label)
return setsockopt(fd, SOL_IPV6, IPV6_FLOWLABEL_MGR, &req, sizeof(req));
}
-static void run_tests(int fd)
+static int flowlabel_renew(int fd, uint32_t label, uint16_t linger)
+{
+ struct in6_flowlabel_req req = {
+ .flr_action = IPV6_FL_A_RENEW,
+ .flr_label = htonl(label),
+ .flr_linger = linger,
+ };
+
+ return setsockopt(fd, SOL_IPV6, IPV6_FLOWLABEL_MGR, &req, sizeof(req));
+}
+
+static int tcp_listen(void)
+{
+ INIT_SIN6_LOOPBACK(addr);
+ const int one = 1;
+ int fd;
+
+ fd = socket(PF_INET6, SOCK_STREAM, 0);
+ if (fd == -1)
+ error(1, errno, "socket listener");
+ if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)))
+ error(1, errno, "setsockopt SO_REUSEADDR");
+ if (bind(fd, (void *)&addr, sizeof(addr)))
+ error(1, errno, "bind");
+ if (listen(fd, 1))
+ error(1, errno, "listen");
+
+ return fd;
+}
+
+static void tcp_connect(int listener, uint32_t flowlabel, int *client, int *accepted)
+{
+ INIT_SIN6_LOOPBACK(addr);
+ const int one = 1;
+ int cfd, afd;
+
+ cfd = socket(PF_INET6, SOCK_STREAM, 0);
+ if (cfd == -1)
+ error(1, errno, "socket client");
+
+ if (flowlabel_get(cfd, flowlabel, IPV6_FL_S_EXCL, IPV6_FL_F_CREATE))
+ error(1, errno, "flowlabel_get");
+ if (setsockopt(cfd, SOL_IPV6, IPV6_FLOWINFO_SEND, &one, sizeof(one)))
+ error(1, errno, "setsockopt flowinfo_send");
+ addr.sin6_flowinfo = htonl(flowlabel);
+
+ if (connect(cfd, (void *)&addr, sizeof(addr)))
+ error(1, errno, "connect");
+
+ afd = accept(listener, NULL, NULL);
+ if (afd == -1)
+ error(1, errno, "accept");
+
+ *client = cfd;
+ *accepted = afd;
+}
+
+static void set_flowlabel_consistency(bool enable)
+{
+ /* flowlabel_consistency must be disable to use the IPV6_FL_F_REFLECT
+ * flag. This helper function is required for setting up and tearing
+ * down test cases for this flag.
+ */
+ int fd;
+
+ fd = open("/proc/sys/net/ipv6/flowlabel_consistency", O_WRONLY);
+ if (fd == -1)
+ error(1, errno, "open flowlabel_consistency");
+ if (write(fd, enable ? "1" : "0", 1) != 1)
+ error(1, errno, "write flowlabel_consistency");
+ if (close(fd))
+ error(1, errno, "close flowlabel_consistency");
+}
+
+TEST(cannot_get_non_existent_label)
+{
+ int fd, err;
+
+ fd = socket(PF_INET6, SOCK_DGRAM, 0);
+ ASSERT_GE(fd, 0) TH_LOG("socket failed");
+
+ err = flowlabel_get(fd, 1, IPV6_FL_S_ANY, 0);
+ ASSERT_TRUE(err) TH_LOG("expected get of a non-existent label to fail");
+
+ ASSERT_EQ(0, close(fd));
+}
+
+TEST(cannot_put_non_existent_label)
+{
+ int fd, err;
+
+ fd = socket(PF_INET6, SOCK_DGRAM, 0);
+ ASSERT_GE(fd, 0) TH_LOG("socket failed");
+
+ err = flowlabel_put(fd, 1);
+ ASSERT_TRUE(err) TH_LOG("expected put of a non-existent label to fail");
+
+ ASSERT_EQ(0, close(fd));
+}
+
+TEST(cannot_create_label_greater_than_20_bits)
+{
+ int fd, err;
+
+ fd = socket(PF_INET6, SOCK_DGRAM, 0);
+ ASSERT_GE(fd, 0) TH_LOG("socket failed");
+
+ err = flowlabel_get(fd, 0x1FFFFF, IPV6_FL_S_ANY, IPV6_FL_F_CREATE);
+ ASSERT_TRUE(err) TH_LOG("expected label > 20 bits to be rejected");
+
+ ASSERT_EQ(0, close(fd));
+}
+
+TEST(can_create_and_get_and_put_labels)
+{
+ int fd, err;
+
+ fd = socket(PF_INET6, SOCK_DGRAM, 0);
+ ASSERT_GE(fd, 0) TH_LOG("socket failed");
+
+ err = flowlabel_get(fd, 1, IPV6_FL_S_ANY, IPV6_FL_F_CREATE);
+ ASSERT_TRUE(!err) TH_LOG("failed to create label (FL_F_CREATE)");
+
+ err = flowlabel_get(fd, 1, IPV6_FL_S_ANY, 0);
+ ASSERT_TRUE(!err) TH_LOG("failed to get the label without FL_F_CREATE");
+
+ err = flowlabel_get(fd, 1, IPV6_FL_S_ANY, IPV6_FL_F_CREATE);
+ ASSERT_TRUE(!err) TH_LOG("failed to get it again with create flag set, too");
+
+ err = flowlabel_get(fd, 1, IPV6_FL_S_ANY, IPV6_FL_F_CREATE | IPV6_FL_F_EXCL);
+ ASSERT_TRUE(err) TH_LOG("expected FL_F_EXCL to reject an already-existing label");
+
+ err = flowlabel_put(fd, 1);
+ ASSERT_TRUE(!err) TH_LOG("failed to put first reference");
+ err = flowlabel_put(fd, 1);
+ ASSERT_TRUE(!err) TH_LOG("failed to put second reference");
+ err = flowlabel_put(fd, 1);
+ ASSERT_TRUE(!err) TH_LOG("failed to put third reference");
+ err = flowlabel_put(fd, 1);
+ ASSERT_TRUE(err) TH_LOG("expected fourth put to fail, no references left");
+
+ ASSERT_EQ(0, close(fd));
+}
+
+TEST(exclusive_label_share)
{
- int wstatus;
+ int fd, err;
+
+ fd = socket(PF_INET6, SOCK_DGRAM, 0);
+ ASSERT_GE(fd, 0) TH_LOG("socket failed");
+
+ err = flowlabel_get(fd, 2, IPV6_FL_S_EXCL, IPV6_FL_F_CREATE);
+ ASSERT_TRUE(!err) TH_LOG("failed to create a new exclusive label (FL_S_EXCL)");
+
+ err = flowlabel_get(fd, 2, IPV6_FL_S_ANY, IPV6_FL_F_CREATE);
+ ASSERT_TRUE(err) TH_LOG("expected reuse in non-exclusive mode to fail");
+
+ err = flowlabel_get(fd, 2, IPV6_FL_S_EXCL, IPV6_FL_F_CREATE);
+ ASSERT_TRUE(err) TH_LOG("expected reuse in exclusive mode to fail too");
+
+ err = flowlabel_put(fd, 2);
+ ASSERT_TRUE(!err) TH_LOG("failed to put the exclusive label");
+
+ err = flowlabel_get(fd, 2, IPV6_FL_S_ANY, IPV6_FL_F_CREATE);
+ ASSERT_TRUE(err) TH_LOG("expected reuse to fail, due to linger");
+
+ sleep(FL_MIN_LINGER * 2 + 1);
+
+ err = flowlabel_get(fd, 2, IPV6_FL_S_ANY, IPV6_FL_F_CREATE);
+ ASSERT_TRUE(!err) TH_LOG("expected reuse to succeed after linger");
+
+ ASSERT_EQ(0, close(fd));
+}
+
+TEST(user_private_label_share)
+{
+ int fd, err, wstatus;
pid_t pid;
- explain("cannot get non-existent label");
- expect_fail(flowlabel_get(fd, 1, IPV6_FL_S_ANY, 0));
-
- explain("cannot put non-existent label");
- expect_fail(flowlabel_put(fd, 1));
-
- explain("cannot create label greater than 20 bits");
- expect_fail(flowlabel_get(fd, 0x1FFFFF, IPV6_FL_S_ANY,
- IPV6_FL_F_CREATE));
-
- explain("create a new label (FL_F_CREATE)");
- expect_pass(flowlabel_get(fd, 1, IPV6_FL_S_ANY, IPV6_FL_F_CREATE));
- explain("can get the label (without FL_F_CREATE)");
- expect_pass(flowlabel_get(fd, 1, IPV6_FL_S_ANY, 0));
- explain("can get it again with create flag set, too");
- expect_pass(flowlabel_get(fd, 1, IPV6_FL_S_ANY, IPV6_FL_F_CREATE));
- explain("cannot get it again with the exclusive (FL_FL_EXCL) flag");
- expect_fail(flowlabel_get(fd, 1, IPV6_FL_S_ANY,
- IPV6_FL_F_CREATE | IPV6_FL_F_EXCL));
- explain("can now put exactly three references");
- expect_pass(flowlabel_put(fd, 1));
- expect_pass(flowlabel_put(fd, 1));
- expect_pass(flowlabel_put(fd, 1));
- expect_fail(flowlabel_put(fd, 1));
-
- explain("create a new exclusive label (FL_S_EXCL)");
- expect_pass(flowlabel_get(fd, 2, IPV6_FL_S_EXCL, IPV6_FL_F_CREATE));
- explain("cannot get it again in non-exclusive mode");
- expect_fail(flowlabel_get(fd, 2, IPV6_FL_S_ANY, IPV6_FL_F_CREATE));
- explain("cannot get it again in exclusive mode either");
- expect_fail(flowlabel_get(fd, 2, IPV6_FL_S_EXCL, IPV6_FL_F_CREATE));
- expect_pass(flowlabel_put(fd, 2));
-
- if (cfg_long_running) {
- explain("cannot reuse the label, due to linger");
- expect_fail(flowlabel_get(fd, 2, IPV6_FL_S_ANY,
- IPV6_FL_F_CREATE));
- explain("after sleep, can reuse");
- sleep(FL_MIN_LINGER * 2 + 1);
- expect_pass(flowlabel_get(fd, 2, IPV6_FL_S_ANY,
- IPV6_FL_F_CREATE));
- }
+ fd = socket(PF_INET6, SOCK_DGRAM, 0);
+ ASSERT_GE(fd, 0) TH_LOG("socket failed");
+
+ err = flowlabel_get(fd, 3, IPV6_FL_S_USER, IPV6_FL_F_CREATE);
+ ASSERT_TRUE(!err) TH_LOG("failed to create a new user-private label (FL_S_USER)");
+
+ err = flowlabel_get(fd, 3, IPV6_FL_S_ANY, 0);
+ ASSERT_TRUE(err) TH_LOG("expected get in non-exclusive mode to fail");
+
+ err = flowlabel_get(fd, 3, IPV6_FL_S_EXCL, 0);
+ ASSERT_TRUE(err) TH_LOG("expected get in exclusive mode to fail");
+
+ err = flowlabel_get(fd, 3, IPV6_FL_S_USER, 0);
+ ASSERT_TRUE(!err) TH_LOG("failed to get it again in user mode");
- explain("create a new user-private label (FL_S_USER)");
- expect_pass(flowlabel_get(fd, 3, IPV6_FL_S_USER, IPV6_FL_F_CREATE));
- explain("cannot get it again in non-exclusive mode");
- expect_fail(flowlabel_get(fd, 3, IPV6_FL_S_ANY, 0));
- explain("cannot get it again in exclusive mode");
- expect_fail(flowlabel_get(fd, 3, IPV6_FL_S_EXCL, 0));
- explain("can get it again in user mode");
- expect_pass(flowlabel_get(fd, 3, IPV6_FL_S_USER, 0));
- explain("child process can get it too, but not after setuid(nobody)");
pid = fork();
- if (pid == -1)
- error(1, errno, "fork");
+ ASSERT_NE(-1, pid) TH_LOG("fork failed");
if (!pid) {
- expect_pass(flowlabel_get(fd, 3, IPV6_FL_S_USER, 0));
- if (setuid(USHRT_MAX))
+ if (flowlabel_get(fd, 3, IPV6_FL_S_USER, 0))
+ exit(1);
+ if (setuid(USHRT_MAX)) {
fprintf(stderr, "[INFO] skip setuid child test\n");
- else
- expect_fail(flowlabel_get(fd, 3, IPV6_FL_S_USER, 0));
+ exit(0);
+ }
+ if (!flowlabel_get(fd, 3, IPV6_FL_S_USER, 0))
+ exit(1);
exit(0);
}
- if (wait(&wstatus) == -1)
- error(1, errno, "wait");
- if (!WIFEXITED(wstatus) || WEXITSTATUS(wstatus) != 0)
- error(1, errno, "wait: unexpected child result");
-
- explain("create a new process-private label (FL_S_PROCESS)");
- expect_pass(flowlabel_get(fd, 4, IPV6_FL_S_PROCESS, IPV6_FL_F_CREATE));
- explain("can get it again");
- expect_pass(flowlabel_get(fd, 4, IPV6_FL_S_PROCESS, 0));
- explain("child process cannot can get it");
+ ASSERT_EQ(pid, wait(&wstatus)) TH_LOG("wait failed");
+ ASSERT_TRUE(WIFEXITED(wstatus)) TH_LOG("child did not exit normally");
+ ASSERT_EQ(0, WEXITSTATUS(wstatus)) TH_LOG("child reported unexpected result");
+
+ ASSERT_EQ(0, close(fd));
+}
+
+TEST(process_private_label_share)
+{
+ int fd, err, wstatus;
+ pid_t pid;
+
+ fd = socket(PF_INET6, SOCK_DGRAM, 0);
+ ASSERT_GE(fd, 0) TH_LOG("socket failed");
+
+ err = flowlabel_get(fd, 4, IPV6_FL_S_PROCESS, IPV6_FL_F_CREATE);
+ ASSERT_TRUE(!err) TH_LOG("failed to create a new process-private label (FL_S_PROCESS)");
+
+ err = flowlabel_get(fd, 4, IPV6_FL_S_PROCESS, 0);
+ ASSERT_TRUE(!err) TH_LOG("failed to get it again");
+
pid = fork();
- if (pid == -1)
- error(1, errno, "fork");
+ ASSERT_NE(-1, pid) TH_LOG("fork failed");
if (!pid) {
- expect_fail(flowlabel_get(fd, 4, IPV6_FL_S_PROCESS, 0));
+ if (!flowlabel_get(fd, 4, IPV6_FL_S_PROCESS, 0))
+ exit(1);
exit(0);
}
- if (wait(&wstatus) == -1)
- error(1, errno, "wait");
- if (!WIFEXITED(wstatus) || WEXITSTATUS(wstatus) != 0)
- error(1, errno, "wait: unexpected child result");
-}
-
-static void parse_opts(int argc, char **argv)
-{
- int c;
-
- while ((c = getopt(argc, argv, "lv")) != -1) {
- switch (c) {
- case 'l':
- cfg_long_running = true;
- break;
- case 'v':
- cfg_verbose = true;
- break;
- default:
- error(1, 0, "%s: parse error", argv[0]);
- }
- }
+ ASSERT_EQ(pid, wait(&wstatus)) TH_LOG("wait failed");
+ ASSERT_TRUE(WIFEXITED(wstatus)) TH_LOG("child did not exit normally");
+ ASSERT_EQ(0, WEXITSTATUS(wstatus)) TH_LOG("child reported unexpected result");
+
+ ASSERT_EQ(0, close(fd));
}
-int main(int argc, char **argv)
+TEST(renew_label_linger)
{
- int fd;
-
- parse_opts(argc, argv);
+ /* After a label with EXCL share is put and lingered, it must be
+ * possible to create a new one. Check if RENEW action extends
+ * the linger period of put label, blocking creation after previous
+ * linger time.
+ */
+ int fd, err;
fd = socket(PF_INET6, SOCK_DGRAM, 0);
- if (fd == -1)
- error(1, errno, "socket");
+ ASSERT_GE(fd, 0) TH_LOG("socket failed");
- run_tests(fd);
+ err = flowlabel_get(fd, 5, IPV6_FL_S_EXCL, IPV6_FL_F_CREATE);
+ ASSERT_TRUE(!err) TH_LOG("failed to create a new label with FL_MIN_LINGER linger time");
- if (close(fd))
- error(1, errno, "close");
+ err = flowlabel_renew(fd, 5, 2 * (FL_MIN_LINGER * 2 + 1));
+ ASSERT_TRUE(!err) TH_LOG("failed to renew the label to increase its linger time");
+
+ err = flowlabel_put(fd, 5);
+ ASSERT_TRUE(!err) TH_LOG("failed to put the label");
- return 0;
+ sleep(FL_MIN_LINGER * 2 + 1);
+
+ err = flowlabel_get(fd, 5, IPV6_FL_S_ANY, IPV6_FL_F_CREATE);
+ ASSERT_TRUE(err) TH_LOG("expected reuse to fail, new linger time not over yet");
+
+ ASSERT_EQ(0, close(fd));
}
+
+TEST(remote_flag)
+{
+ /* The REMOTE flag, used for getsockopt, is expected to retrieve the
+ * label from the latest received header.
+ */
+ struct in6_flowlabel_req freq = {
+ .flr_action = IPV6_FL_A_GET,
+ .flr_flags = IPV6_FL_F_REMOTE,
+ };
+ socklen_t freq_len = sizeof(freq);
+ int listener, cfd, afd, err;
+
+ listener = tcp_listen();
+ tcp_connect(listener, 6, &cfd, &afd);
+
+ err = getsockopt(afd, SOL_IPV6, IPV6_FLOWLABEL_MGR, &freq, &freq_len);
+ ASSERT_TRUE(!err) TH_LOG("getsockopt with IPV6_FL_F_REMOTE failed");
+ ASSERT_EQ(6, ntohl(freq.flr_label)) TH_LOG("unexpected remote flow label");
+
+ ASSERT_EQ(0, close(afd));
+ ASSERT_EQ(0, close(cfd));
+ ASSERT_EQ(0, close(listener));
+}
+
+TEST(reflect_flag)
+{
+ /* The REFLECT flag acts as a trigger to the REPFLOW bit. When REPFLOW
+ * is triggered for a socket, it adopts the label received from the
+ * connected socket.
+ */
+ struct in6_flowlabel_req reflect_on = {
+ .flr_action = IPV6_FL_A_GET,
+ .flr_flags = IPV6_FL_F_REFLECT,
+ };
+ struct in6_flowlabel_req reflect_query = {
+ .flr_action = IPV6_FL_A_GET,
+ };
+ struct in6_flowlabel_req reflect_off = {
+ .flr_action = IPV6_FL_A_PUT,
+ .flr_flags = IPV6_FL_F_REFLECT,
+ };
+ socklen_t reflect_query_len = sizeof(reflect_query);
+ int listener, cfd, afd, err;
+
+ set_flowlabel_consistency(false);
+
+ listener = tcp_listen();
+ err = setsockopt(listener, SOL_IPV6, IPV6_FLOWLABEL_MGR, &reflect_on, sizeof(reflect_on));
+ ASSERT_TRUE(!err) TH_LOG("failed to enable REFLECT on the listener");
+
+ tcp_connect(listener, 7, &cfd, &afd);
+
+ err = getsockopt(afd, SOL_IPV6, IPV6_FLOWLABEL_MGR, &reflect_query, &reflect_query_len);
+ ASSERT_TRUE(!err) TH_LOG("failed to query the accepted socket's outgoing label");
+ ASSERT_EQ(7, ntohl(reflect_query.flr_label)) TH_LOG("accepted socket did not reflect client's label");
+
+ err = setsockopt(afd, SOL_IPV6, IPV6_FLOWLABEL_MGR, &reflect_off, sizeof(reflect_off));
+ ASSERT_TRUE(!err) TH_LOG("failed to disable REFLECT on the accepted socket");
+
+ err = setsockopt(afd, SOL_IPV6, IPV6_FLOWLABEL_MGR, &reflect_off, sizeof(reflect_off));
+ ASSERT_TRUE(err) TH_LOG("expected disabling REFLECT twice to fail");
+
+ set_flowlabel_consistency(true);
+
+ ASSERT_EQ(0, close(afd));
+ ASSERT_EQ(0, close(cfd));
+ ASSERT_EQ(0, close(listener));
+}
+
+TEST_HARNESS_MAIN
|
| 3/2 | 2026/07/27 16:16 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 8603 output: 73 thoughts: 502 Thoughts: **WorthFuzzing=false: IPv6 Flow Label Selftest Patch** Okay, let's see. This patch touches `tools/testing/selftests/net/ipv6_flowlabel_mgr.c`. Right, it's converting an existing test and adding new ones, all related to IPv6 flow labels, but crucially, it's *only* in the selftests. No kernel code is being modified here. Let me quickly double-check the diff… Yep, just that one file. Since this is purely a selftest update, there's zero functional impact on the kernel itself that warrants fuzzing. It's user-space testing, not kernel behavior. I need to make sure I'm following the rules correctly. Let me reread the criteria... Hmm, selftests aren't explicitly *listed* in the "WorthFuzzing=false" list, but it's pretty clear that they fall under the spirit of the restrictions. These are isolated user-space tests; fuzzing the kernel based on changes *within* them makes no sense since the kernel itself hasn't been modified. Ah, the instructions say my job is to determine if it makes functional changes to the kernel. Therefore, because this patch solely concerns user-space selftests, I'm confident that it does *not* warrant fuzzing. I'll return WorthFuzzing=false. |
| 4/2 | 2026/07/27 16:16 | tool | set-results |
0mArgs:{
"EnableConfigs": [],
"FocusSymbols": [],
"Reasoning": "The patch only modifies a user-space selftest (tools/testing/selftests/net/ipv6_flowlabel_mgr.c) and makes no functional changes to the kernel code itself.",
"WorthFuzzing": false
}Results: {
"EnableConfigs": null,
"FocusSymbols": [],
"Reasoning": "The patch only modifies a user-space selftest (tools/testing/selftests/net/ipv6_flowlabel_mgr.c) and makes no functional changes to the kernel code itself.",
"WorthFuzzing": false
} |
| Total Calls | Total Tokens | Avg Tokens | Total Duration (Seconds) | Avg Duration (Seconds) |
|---|
| Total Calls | Total Duration (Seconds) | Avg Duration (Seconds) |
|---|