Here's a much reduced test program. The key is to splice more than a page from the pipe into the second socket (AF_ALG in this case) and more than that into the pipe. David --- // https://syzkaller.appspot.com/bug?id=613f5060400df25674e1b213295ef45a8422b077 // autogenerated by syzkaller (https://github.com/google/syzkaller) #define _GNU_SOURCE #include <endian.h> #include <errno.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <fcntl.h> #include <unistd.h> #include <sys/syscall.h> #include <sys/socket.h> #include <sys/mman.h> #include <sys/wait.h> #include <netinet/in.h> #include <linux/if_alg.h> #define OSERROR(R, S) do { if ((long)(R) == -1L) { perror((S)); exit(1); } } while(0) static const unsigned char data[1024 * 1024] = { "\x44\xf9\xb1\x08\xb1\xcd\xc8\x85\xc9\xc5\x33\xd2\x1f\x47\x4b\xec\x8b" "\xfe\xf1\xdf\x1e\x2d\xa7\x1e\x57\x8d\xc6\xb9\x1d\x09\xf7\xab\x15\x37" "\x85\x71\xd8\xe2\x75\x46\x09\x00\x00\x00\x6e\x75\x43\x69\x14\xab\x71" "\x75\x28\xee\x4b\x7a\x9b\xea\xf9\x08\xd1\x11\x37\xc1\x19\x03\x06\x4e" "\x83\xb4\x95\x1f\x4d\x43\x3a\x54\x04\x97\x0c\x85\xd9\x2d\x70\x83\xfd" "\x38\x84\x4c\xbb\x0c\x6c\x5e\xb5\x08\xdd\xc2\xdc\x7a\x59\x0a\xa7\x94" "\x1b\x1e\x9e\xeb\x5a\x68\x81\x38\xde\xa0\x9b\x77\x6c\xbf\xa7\x84\xcb" "\xf5\x50\xbf\x30\x74\xfb\x0d\x77\x5d\xa4\xdf\x5a\x3f\x48\xbb\xdf\x45" "\x2e\xeb\x6b\x92\x3d\xa9\xd0\xe2\x5b\x80\xf7\x6a\x87\x36\x64\xb5\x75" "\x34\x44\xfe\x05\xf3\x3e\x5f\x91\x04\x55\x40\x83\x6c\x3c\xd6\xaf\x10" "\xf0\xcd\x01\x8f\x0c\x6f\x57\xf9\x26\xac\x95\x9a\x56\x28\xc4\x50\x88" "\xfb\xe0\xc8\x7f\xbe\x6c\xbc\xda\x46\x62\xd2\xa1\x2f\x6d\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", }; int main(int argc, char *argv[]) { struct sockaddr_in6 sin6; struct sockaddr_alg salg; int pipefd[2], ipv6fd, algfd, hashfd, res, wt; res = pipe(pipefd); OSERROR(res, "pipe"); ipv6fd = socket(AF_INET6, SOCK_STREAM, IPPROTO_IP); OSERROR(ipv6fd, "socket/inet6"); memset(&sin6, 0, sizeof(sin6)); sin6.sin6_family = AF_INET6; sin6.sin6_port = htons(2); res = bind(ipv6fd, (struct sockaddr *)&sin6, sizeof(sin6)); OSERROR(res, "bind/inet6"); memset(&sin6, 0, sizeof(sin6)); sin6.sin6_family = AF_INET6; sin6.sin6_port = htons(2); sin6.sin6_addr.s6_addr[15] = 1; res = sendto(ipv6fd, NULL, 0, MSG_OOB|MSG_NOSIGNAL|MSG_FASTOPEN|0x2000000, (struct sockaddr *)&sin6, sizeof(sin6)); OSERROR(res, "sendto_1"); res = send(ipv6fd, data, 0xd0d0c2ac /* massive overrun */, MSG_OOB); OSERROR(res, "sendto_2"); algfd = socket(AF_ALG, SOCK_SEQPACKET, 0); OSERROR(algfd, "socket/alg"); memset(&salg, 0, sizeof(salg)); salg.salg_family = AF_ALG; strcpy(salg.salg_type, "hash"); strcpy(salg.salg_name, "sha3-512"); res = bind(algfd, (struct sockaddr *)&salg, sizeof(salg)); OSERROR(res, "bind/alg"); hashfd = accept4(algfd, NULL, 0, 0); OSERROR(hashfd, "accept/alg"); switch (fork()) { case -1: OSERROR(-1, "fork"); case 0: res = splice(pipefd[0], 0, hashfd, 0, 65536, 0); OSERROR(res, "splice/p->h"); return 0; default: sleep(1); break; } res = splice(ipv6fd, 0, pipefd[1], 0, 32767, 0); OSERROR(res, "splice/i->p"); wait(&wt); return 0; }