crypto: deadlock in alg_setsockopt

From: Dmitry Vyukov
Date: Tue Dec 29 2015 - 13:37:02 EST


Hello,

On commit 8513342170278468bac126640a5d2d12ffbff106
+ crypto: algif_skcipher - Use new skcipher interface
+ crypto: algif_skcipher - Require setkey before accept(2)
+ crypto: af_alg - Disallow bind/setkey/... after accept(2)

The following program creates an unkillable, deadlocked process:

// autogenerated by syzkaller (http://github.com/google/syzkaller)
#include <unistd.h>
#include <sys/syscall.h>
#include <string.h>
#include <stdint.h>
#include <pthread.h>

long r[10];

int main()
{
memset(r, -1, sizeof(r));
r[0] = syscall(SYS_mmap, 0x20000000ul, 0x10000ul, 0x3ul,
0x32ul, 0xfffffffffffffffful, 0x0ul);
r[1] = syscall(SYS_socket, 0x26ul, 0x5ul, 0x0ul, 0, 0, 0);
*(uint16_t*)0x20000112 = (uint16_t)0x26;
memcpy((void*)0x20000114,
"\x73\x6b\x63\x69\x70\x68\x65\x72\x00\x00\x00\x00\x00\x00", 14);
*(uint32_t*)0x20000122 = (uint32_t)0x209;
*(uint32_t*)0x20000126 = (uint32_t)0x4e;
memcpy((void*)0x2000012a,
"\x65\x63\x62\x28\x61\x72\x63\x34\x29\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
64);
r[7] = syscall(SYS_bind, r[1], 0x20000112ul, 0x58ul, 0, 0, 0);
r[9] = syscall(SYS_setsockopt, r[1], 0x117ul, 0x1ul,
0x20003000ul, 0xd2ul, 0);
return 0;
}

root 28768 0.0 0.0 1144 4 pts/0 D+ 18:25 0:00 |
\_ ./a.out

# cat /proc/28768/stack
[<ffffffff84b65496>] __lock_sock+0xe6/0x160
[<ffffffff84b6560b>] lock_sock_nested+0xfb/0x120
[<ffffffff827dd899>] alg_setsockopt+0x2a9/0x3d0
[<ffffffff84b605b8>] SyS_setsockopt+0x158/0x240
[<ffffffff85c8ebb6>] entry_SYSCALL_64_fastpath+0x16/0x7a
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/