On Mon, Nov 27, 2017 at 10:56:47AM -0800, syzbot wrote: > Hello, > > syzkaller hit the following crash on > 1ea8d039f9edcfefb20d8ddfe136930f6e551529 > git://git.cmpxchg.org/linux-mmots.git/master > compiler: gcc (GCC) 7.1.1 20170620 > .config is attached > Raw console output is attached. > C reproducer is attached > syzkaller reproducer is attached. See https://goo.gl/kgGztJ > for information about syzkaller reproducers Still happens on latest Linus tree (v4.15-rc1) with crypto/master merged in. It seems that _aead_recvmsg() is being confused by the operation mode being changed from encryption to decryption while it has dropped the socket lock in af_alg_wait_for_data(). Here's a simplified reproducer: #include <linux/if_alg.h> #include <sys/socket.h> #include <sys/wait.h> #include <unistd.h> int main() { for (;;) { int algfd, reqfd; struct sockaddr_alg addr = { .salg_type = "aead", .salg_name = "gcm(aes)", }; struct { struct cmsghdr hdr; __u32 op; } set_op = { .hdr = { .cmsg_len = sizeof(set_op), .cmsg_level = SOL_ALG, .cmsg_type = ALG_SET_OP, }, }; struct msghdr set_op_msg = { .msg_control = &set_op, .msg_controllen = sizeof(set_op), }; char key[16] = { 0 }; char buf[4096]; algfd = socket(AF_ALG, SOCK_SEQPACKET, 0); bind(algfd, (void *)&addr, sizeof(addr)); setsockopt(algfd, SOL_ALG, ALG_SET_KEY, key, sizeof(key)); reqfd = accept(algfd, NULL, NULL); set_op.op = ALG_OP_ENCRYPT; sendmsg(reqfd, &set_op_msg, 0); if (fork() == 0) { set_op.op = ALG_OP_DECRYPT; sendmsg(reqfd, &set_op_msg, 0); break; } read(reqfd, buf, sizeof(buf)); wait(NULL); } }