AI Trajectory


Trajectory: (Expand/Collapse All)
Seq Timestamp Type Name Duration
0/0 2026/08/04 03:29 flow patch-triage
0m Args:
null

Results:
{
  "EnableConfigs": null,
  "FocusSymbols": [],
  "Reasoning": "The patch only modifies user-space selftests (tools/testing/selftests/) and does not make any functional changes to the kernel code itself.",
  "WorthFuzzing": false
}

1/1 2026/08/04 03:29 action read-patch-diff
0m Args:
null

Results:
{
  "PatchDiff": "commit c898e69e783bd9f7616da84eb5ec3ea09d20399d\nAuthor: syz-cluster \u003ctriage@syzkaller.com\u003e\nDate:   Tue Aug 4 03:29:19 2026 +0000\n\n    syz-cluster: applied patch under review\n\ndiff --git a/tools/testing/selftests/net/ipv6_flowlabel.sh b/tools/testing/selftests/net/ipv6_flowlabel.sh\nindex cee95e252bee5..4c3de3a27807c 100755\n--- a/tools/testing/selftests/net/ipv6_flowlabel.sh\n+++ b/tools/testing/selftests/net/ipv6_flowlabel.sh\n@@ -8,7 +8,8 @@\n set -e\n \n echo \"TEST management\"\n-./in_netns.sh ./ipv6_flowlabel_mgr\n+./in_netns.sh \\\n+  sh -c 'sysctl -q -w net.ipv6.flowlabel_consistency=0 \u0026\u0026 ./ipv6_flowlabel_mgr'\n \n echo \"TEST datapath\"\n ./in_netns.sh \\\ndiff --git a/tools/testing/selftests/net/ipv6_flowlabel_mgr.c b/tools/testing/selftests/net/ipv6_flowlabel_mgr.c\nindex af95b48acea90..482921f7ee119 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,19 @@\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 FL_MAX_LINGER\t150\n \n static int flowlabel_get(int fd, uint32_t label, uint8_t share, uint16_t flags)\n {\n@@ -71,129 +60,406 @@ 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 struct sockaddr_in6 loopback_addr(void)\n+{\n+\tstruct sockaddr_in6 addr = {\n+\t\t.sin6_family\t= AF_INET6,\n+\t\t.sin6_addr\t= IN6ADDR_LOOPBACK_INIT,\n+\t\t.sin6_port\t= htons(8888),\n+\t};\n+\n+\treturn addr;\n+}\n+\n+static int tcp_listen(void)\n+{\n+\tstruct sockaddr_in6 addr = 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+\tstruct sockaddr_in6 addr = 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+\tif (flowlabel_put(cfd, flowlabel))\n+\t\terror(1, errno, \"flowlabel_put\");\n+\n+\t*client = cfd;\n+\t*accepted = afd;\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, 9, IPV6_FL_S_ANY, 0);\n+\tASSERT_TRUE(err) TH_LOG(\"expected get of a non-existent label to fail\");\n+\tASSERT_EQ(ENOENT, errno) TH_LOG(\"expected ENOENT, got %d\", errno);\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, 10);\n+\tASSERT_TRUE(err) TH_LOG(\"expected put of a non-existent label to fail\");\n+\tASSERT_EQ(ESRCH, errno) TH_LOG(\"expected ESRCH, got %d\", errno);\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+\tASSERT_EQ(EINVAL, errno) TH_LOG(\"expected EINVAL, got %d\", errno);\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+\tASSERT_EQ(EEXIST, errno) TH_LOG(\"expected EEXIST, got %d\", errno);\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+\tASSERT_EQ(ESRCH, errno) TH_LOG(\"expected ESRCH, got %d\", errno);\n+\n+\tASSERT_EQ(0, close(fd));\n+}\n+\n+TEST(exclusive_label_share)\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, 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+\tASSERT_EQ(EPERM, errno) TH_LOG(\"expected EPERM, got %d\", errno);\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+\tASSERT_EQ(EPERM, errno) TH_LOG(\"expected EPERM, got %d\", errno);\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+\tASSERT_EQ(EPERM, errno) TH_LOG(\"expected EPERM, got %d\", errno);\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 wstatus;\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+\tASSERT_EQ(EPERM, errno) TH_LOG(\"expected EPERM, got %d\", errno);\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+\tASSERT_EQ(EPERM, errno) TH_LOG(\"expected EPERM, got %d\", errno);\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\terr = flowlabel_get(fd, 3, IPV6_FL_S_USER, 0);\n+\t\tASSERT_TRUE(!err) TH_LOG(\"child failed to get the user-private label\");\n+\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+\n+\t\terr = flowlabel_get(fd, 3, IPV6_FL_S_USER, 0);\n+\t\tASSERT_TRUE(err) TH_LOG(\"child unexpectedly got the label after setuid(nobody)\");\n+\t\tASSERT_EQ(EPERM, errno) TH_LOG(\"expected EPERM, got %d\", errno);\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\terr = flowlabel_get(fd, 4, IPV6_FL_S_PROCESS, 0);\n+\t\tASSERT_TRUE(err) TH_LOG(\"child unexpectedly got the process-private label\");\n+\t\tASSERT_EQ(EPERM, errno) TH_LOG(\"expected EPERM, got %d\", errno);\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(cannot_renew_non_existent_label)\n {\n-\tint fd;\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_renew(fd, 5, 2 * (FL_MIN_LINGER * 2 + 1));\n+\tASSERT_TRUE(err) TH_LOG(\"expected renew of a non-existent label to fail\");\n+\tASSERT_EQ(ESRCH, errno) TH_LOG(\"expected ESRCH, got %d\", errno);\n+\n+\tASSERT_EQ(0, close(fd));\n+}\n+\n+TEST(can_renew_existing_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, 5, IPV6_FL_S_EXCL, IPV6_FL_F_CREATE);\n+\tASSERT_TRUE(!err) TH_LOG(\"failed to create a new label for renew validation\");\n+\n+\terr = flowlabel_renew(fd, 5, 2 * (FL_MIN_LINGER * 2 + 1));\n+\tASSERT_TRUE(!err) TH_LOG(\"failed to renew an existing valid label\");\n+\n+\terr = flowlabel_put(fd, 5);\n+\tASSERT_TRUE(!err) TH_LOG(\"failed to put the label\");\n \n-\tparse_opts(argc, argv);\n+\tASSERT_EQ(0, close(fd));\n+}\n+\n+TEST(renew_label_linger)\n+{\n+\t/* RENEW must extend a label's linger period: putting a renewed\n+\t * label and waiting out its original linger time must not be\n+\t * enough to allow the label to be recreated.\n+\t */\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, 6, 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+\terr = flowlabel_renew(fd, 6, 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, 6);\n+\tASSERT_TRUE(!err) TH_LOG(\"failed to put the label\");\n+\n+\tsleep(FL_MIN_LINGER * 2 + 1);\n+\n+\terr = flowlabel_get(fd, 6, 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+\tASSERT_EQ(EPERM, errno) TH_LOG(\"expected EPERM, got %d\", errno);\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, 7, \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(7, 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+static bool flowlabel_consistency_enabled(void)\n+{\n+\tchar buf[2] = {};\n+\tint fd;\n+\n+\tfd = open(\"/proc/sys/net/ipv6/flowlabel_consistency\", O_RDONLY);\n \tif (fd == -1)\n-\t\terror(1, errno, \"socket\");\n+\t\treturn true;\n \n-\trun_tests(fd);\n+\tif (read(fd, buf, sizeof(buf) - 1) \u003c 0)\n+\t\tbuf[0] = '1';\n+\tclose(fd);\n \n-\tif (close(fd))\n-\t\terror(1, errno, \"close\");\n+\treturn buf[0] != '0';\n+}\n \n-\treturn 0;\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+\tif (flowlabel_consistency_enabled())\n+\t\tSKIP(return,\n+\t\t     \"net.ipv6.flowlabel_consistency must be 0 (run via ipv6_flowlabel.sh)\");\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, 8, \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(8, ntohl(reflect_query.flr_label))\n+\t\tTH_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+\tASSERT_EQ(ESRCH, errno) TH_LOG(\"expected ESRCH, got %d\", errno);\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/08/04 03:29 agent patch-evaluator
0m Model:
best-expensive

Args:
null

Results:
{
  "EnableConfigs": null,
  "FocusSymbols": [],
  "Reasoning": "The patch only modifies user-space selftests (tools/testing/selftests/) and does not make any 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 c898e69e783bd9f7616da84eb5ec3ea09d20399d
Author: syz-cluster <triage@syzkaller.com>
Date:   Tue Aug 4 03:29:19 2026 +0000

    syz-cluster: applied patch under review

diff --git a/tools/testing/selftests/net/ipv6_flowlabel.sh b/tools/testing/selftests/net/ipv6_flowlabel.sh
index cee95e252bee5..4c3de3a27807c 100755
--- a/tools/testing/selftests/net/ipv6_flowlabel.sh
+++ b/tools/testing/selftests/net/ipv6_flowlabel.sh
@@ -8,7 +8,8 @@
 set -e
 
 echo "TEST management"
-./in_netns.sh ./ipv6_flowlabel_mgr
+./in_netns.sh \
+  sh -c 'sysctl -q -w net.ipv6.flowlabel_consistency=0 && ./ipv6_flowlabel_mgr'
 
 echo "TEST datapath"
 ./in_netns.sh \
diff --git a/tools/testing/selftests/net/ipv6_flowlabel_mgr.c b/tools/testing/selftests/net/ipv6_flowlabel_mgr.c
index af95b48acea90..482921f7ee119 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,19 @@
 #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 FL_MAX_LINGER	150
 
 static int flowlabel_get(int fd, uint32_t label, uint8_t share, uint16_t flags)
 {
@@ -71,129 +60,406 @@ 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 struct sockaddr_in6 loopback_addr(void)
+{
+	struct sockaddr_in6 addr = {
+		.sin6_family	= AF_INET6,
+		.sin6_addr	= IN6ADDR_LOOPBACK_INIT,
+		.sin6_port	= htons(8888),
+	};
+
+	return addr;
+}
+
+static int tcp_listen(void)
+{
+	struct sockaddr_in6 addr = 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)
+{
+	struct sockaddr_in6 addr = 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");
+
+	if (flowlabel_put(cfd, flowlabel))
+		error(1, errno, "flowlabel_put");
+
+	*client = cfd;
+	*accepted = afd;
+}
+
+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, 9, IPV6_FL_S_ANY, 0);
+	ASSERT_TRUE(err) TH_LOG("expected get of a non-existent label to fail");
+	ASSERT_EQ(ENOENT, errno) TH_LOG("expected ENOENT, got %d", errno);
+
+	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, 10);
+	ASSERT_TRUE(err) TH_LOG("expected put of a non-existent label to fail");
+	ASSERT_EQ(ESRCH, errno) TH_LOG("expected ESRCH, got %d", errno);
+
+	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(EINVAL, errno) TH_LOG("expected EINVAL, got %d", errno);
+
+	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");
+	ASSERT_EQ(EEXIST, errno) TH_LOG("expected EEXIST, got %d", errno);
+
+	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(ESRCH, errno) TH_LOG("expected ESRCH, got %d", errno);
+
+	ASSERT_EQ(0, close(fd));
+}
+
+TEST(exclusive_label_share)
+{
+	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");
+	ASSERT_EQ(EPERM, errno) TH_LOG("expected EPERM, got %d", errno);
+
+	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");
+	ASSERT_EQ(EPERM, errno) TH_LOG("expected EPERM, got %d", errno);
+
+	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");
+	ASSERT_EQ(EPERM, errno) TH_LOG("expected EPERM, got %d", errno);
+
+	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 wstatus;
+	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");
+	ASSERT_EQ(EPERM, errno) TH_LOG("expected EPERM, got %d", errno);
+
+	err = flowlabel_get(fd, 3, IPV6_FL_S_EXCL, 0);
+	ASSERT_TRUE(err) TH_LOG("expected get in exclusive mode to fail");
+	ASSERT_EQ(EPERM, errno) TH_LOG("expected EPERM, got %d", errno);
+
+	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))
+		err = flowlabel_get(fd, 3, IPV6_FL_S_USER, 0);
+		ASSERT_TRUE(!err) TH_LOG("child failed to get the user-private label");
+
+		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);
+		}
+
+		err = flowlabel_get(fd, 3, IPV6_FL_S_USER, 0);
+		ASSERT_TRUE(err) TH_LOG("child unexpectedly got the label after setuid(nobody)");
+		ASSERT_EQ(EPERM, errno) TH_LOG("expected EPERM, got %d", errno);
 		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));
+		err = flowlabel_get(fd, 4, IPV6_FL_S_PROCESS, 0);
+		ASSERT_TRUE(err) TH_LOG("child unexpectedly got the process-private label");
+		ASSERT_EQ(EPERM, errno) TH_LOG("expected EPERM, got %d", errno);
 		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(cannot_renew_non_existent_label)
 {
-	int fd;
+	int fd, err;
+
+	fd = socket(PF_INET6, SOCK_DGRAM, 0);
+	ASSERT_GE(fd, 0) TH_LOG("socket failed");
+
+	err = flowlabel_renew(fd, 5, 2 * (FL_MIN_LINGER * 2 + 1));
+	ASSERT_TRUE(err) TH_LOG("expected renew of a non-existent label to fail");
+	ASSERT_EQ(ESRCH, errno) TH_LOG("expected ESRCH, got %d", errno);
+
+	ASSERT_EQ(0, close(fd));
+}
+
+TEST(can_renew_existing_label)
+{
+	int fd, err;
+
+	fd = socket(PF_INET6, SOCK_DGRAM, 0);
+	ASSERT_GE(fd, 0) TH_LOG("socket failed");
+
+	err = flowlabel_get(fd, 5, IPV6_FL_S_EXCL, IPV6_FL_F_CREATE);
+	ASSERT_TRUE(!err) TH_LOG("failed to create a new label for renew validation");
+
+	err = flowlabel_renew(fd, 5, 2 * (FL_MIN_LINGER * 2 + 1));
+	ASSERT_TRUE(!err) TH_LOG("failed to renew an existing valid label");
+
+	err = flowlabel_put(fd, 5);
+	ASSERT_TRUE(!err) TH_LOG("failed to put the label");
 
-	parse_opts(argc, argv);
+	ASSERT_EQ(0, close(fd));
+}
+
+TEST(renew_label_linger)
+{
+	/* RENEW must extend a label's linger period: putting a renewed
+	 * label and waiting out its original linger time must not be
+	 * enough to allow the label to be recreated.
+	 */
+	int fd, err;
 
 	fd = socket(PF_INET6, SOCK_DGRAM, 0);
+	ASSERT_GE(fd, 0) TH_LOG("socket failed");
+
+	err = flowlabel_get(fd, 6, 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");
+
+	err = flowlabel_renew(fd, 6, 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, 6);
+	ASSERT_TRUE(!err) TH_LOG("failed to put the label");
+
+	sleep(FL_MIN_LINGER * 2 + 1);
+
+	err = flowlabel_get(fd, 6, 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(EPERM, errno) TH_LOG("expected EPERM, got %d", errno);
+
+	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, 7, &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(7, 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));
+}
+
+static bool flowlabel_consistency_enabled(void)
+{
+	char buf[2] = {};
+	int fd;
+
+	fd = open("/proc/sys/net/ipv6/flowlabel_consistency", O_RDONLY);
 	if (fd == -1)
-		error(1, errno, "socket");
+		return true;
 
-	run_tests(fd);
+	if (read(fd, buf, sizeof(buf) - 1) < 0)
+		buf[0] = '1';
+	close(fd);
 
-	if (close(fd))
-		error(1, errno, "close");
+	return buf[0] != '0';
+}
 
-	return 0;
+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;
+
+	if (flowlabel_consistency_enabled())
+		SKIP(return,
+		     "net.ipv6.flowlabel_consistency must be 0 (run via ipv6_flowlabel.sh)");
+
+	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, 8, &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(8, 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");
+	ASSERT_EQ(ESRCH, errno) TH_LOG("expected ESRCH, got %d", errno);
+
+	ASSERT_EQ(0, close(afd));
+	ASSERT_EQ(0, close(cfd));
+	ASSERT_EQ(0, close(listener));
 }
+
+TEST_HARNESS_MAIN

3/2 2026/08/04 03:29 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 9655
							output: 63
							thoughts: 571
						

Thoughts:
**WorthFuzzing=false: Analyzing a Selftest Patch**

Okay, so I've got a patch here that's touching `tools/testing/selftests/net/ipv6_flowlabel_mgr.c` and `tools/testing/selftests/net/ipv6_flowlabel.sh`. My initial thought is, "hmmm, that's all contained within the selftests directory, that's not kernel execution." Let me just double check, though, always good to be thorough. Right, the diff just confirms the two files within `tools/testing/selftests/`.

Since this modifies *only* selftests, which are user-space programs designed for testing, not the core kernel logic, it's pretty clear this won't trigger any meaningful fuzzing of the kernel itself. No functional changes there.

Now, let's go back and look at the instructions, just to be absolutely certain. The instructions specify scenarios where `WorthFuzzing=false`. It lists things like documentation changes, comments, purely decorative changes, unreachable code paths, vendor-specific drivers requiring specific hardware, and teardown callbacks. I don't see selftests explicitly listed, but it's clear these are used to test kernel features, not to execute code, and therefore it falls within the same spirit of the guidelines.

Let me just double-check, no, I've confirmed that the patch only touches `tools/testing/selftests/net/ipv6_flowlabel.sh` and `tools/testing/selftests/net/ipv6_flowlabel_mgr.c`.

Okay, I'm confident. The patch only modifies these user-space selftests, residing in `tools/testing/selftests/`, and it isn't changing any kernel code. This doesn't necessitate fuzzing the kernel.

So, the conclusion is **WorthFuzzing=false**. We can now call `set-results`.



4/2 2026/08/04 03:29 tool set-results
0m Args:
{
  "EnableConfigs": [],
  "FocusSymbols": [],
  "Reasoning": "The patch only modifies user-space selftests (tools/testing/selftests/) and does not make any functional changes to the kernel code itself.",
  "WorthFuzzing": false
}

Results:
{
  "EnableConfigs": null,
  "FocusSymbols": [],
  "Reasoning": "The patch only modifies user-space selftests (tools/testing/selftests/) and does not make any functional changes to the kernel code itself.",
  "WorthFuzzing": false
}

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