NetBSD-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
kern/59220: accept(2): null pointer deref
>Number: 59220
>Category: kern
>Synopsis: accept(2): null pointer deref
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: kern-bug-people
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Wed Mar 26 16:20:00 +0000 2025
>Originator: Taylor R Campbell
>Release: current, 10, 9, ...
>Organization:
The NetLOCAL_CONNWAIT Foundacrash
>Environment:
>Description:
uvm_fault(0x..., 0x0, 1) -> e
fatal page fault in supervisor mode
trap type 6 code 0 rip 0x... cs 0x8 rflags 0x10202 cr2 0 ilevel 0 rsp 0x...
curlwp 0x... pid 558.558 lowest kstack 0x...
kernel page fault trap, code=0
Stopped in pid 558.558 (t_unix) at netbsd:solocked2+0x3: movq 0(%rsi),%rdi
solocked2() at netbsd:solocked2+0x3
do_sys_accept() at netbsd:do_sys_accept+0x17f
sys_accept() at netbsd:sys_accept+0x48
syscall() at netbsd:syscall+0x112
--- syscall (number 30) ---
netbsd:syscall+0x112:
ds b700
es 0
fs 87c0
gs 3940
rdi ffff8e88bd7a64e0
rsi 0
rbp ffff9b005540edc0
rbx ffff8e88bd7a64e0
rdx ffff8e88bd6abc00
rcx 7
rax ffff8e88bcc0b700
r8 0
r9 0
r10 d103a0
r11 246
r12 ffff9b005540ee68
r13 ffff8e88bd7a6980
r14 ffff8e88bd975728
r15 ffff8e88bcc0b700
rip ffffffff80e83c7e solocked2+0x3
cs 0
rflags 10202
rsp ffff9b005540ed98
ss 10
netbsd:solocked2+0x3: movq 0(%rsi),%rdi
db{1}>
(gdb) list *(solocked2+0x3)
0xffffffff80e842ce is in solocked2 (/home/riastradh/netbsd/current/src/sys/kern/uipc_socket2.c:1504).
1499 /*
1500 * Used only for diagnostic assertions, so so_lock should be
1501 * stable at this point, hence on need for atomic_load_*.
1502 */
1503 lock = so1->so_lock;
1504 if (lock != so2->so_lock)
1505 return false;
1506 return mutex_owned(lock);
1507 }
1508
(gdb) disas solocked2
Dump of assembler code for function solocked2:
0xffffffff80e842cb <+0>: mov (%rdi),%rax
0xffffffff80e842ce <+3>: mov (%rsi),%rdi
0xffffffff80e842d1 <+6>: cmp %rax,%rdi
0xffffffff80e842d4 <+9>: je 0xffffffff80e842d9 <solocked2+14>
0xffffffff80e842d6 <+11>: xor %eax,%eax
0xffffffff80e842d8 <+13>: retq
0xffffffff80e842d9 <+14>: push %rbp
0xffffffff80e842da <+15>: mov %rsp,%rbp
0xffffffff80e842dd <+18>: callq 0xffffffff80de89d6 <mutex_owned>
0xffffffff80e842e2 <+23>: test %eax,%eax
0xffffffff80e842e4 <+25>: setne %al
0xffffffff80e842e7 <+28>: pop %rbp
0xffffffff80e842e8 <+29>: retq
>How-To-Repeat:
ATF_TC(sockaddr_un_local_connwait);
ATF_TC_HEAD(sockaddr_un_local_connwait, tc)
{
atf_tc_set_md_var(tc, "descr", "Check that LOCAL_CONNWAIT works");
}
ATF_TC_BODY(sockaddr_un_local_connwait, tc)
{
/* too annoying to fit this into the test(...) framework above */
struct sockaddr_un sun = {.sun_family = AF_UNIX, .sun_path = "sock"};
int listener, conn, acc;
const int one = 1;
struct pollfd pfd;
int nfd, error;
socklen_t errorlen = sizeof(error);
RL(listener = socket(PF_LOCAL, SOCK_STREAM|SOCK_NONBLOCK, 0));
RL(bind(listener, (const struct sockaddr *)&sun, sizeof(sun)));
RL(listen(listener, 5));
/* accept would block */
ATF_REQUIRE_ERRNO(EAGAIN, accept(listener, NULL, NULL) == -1);
/* success without accept if we don't set LOCAL_CONNWAIT */
RL(conn = socket(PF_LOCAL, SOCK_STREAM|SOCK_NONBLOCK, 0));
RL(connect(conn, (const struct sockaddr *)&sun, sizeof(sun)));
RL(close(conn));
/* accept should happen now; chuck the client */
RL(acc = accept(listener, NULL, NULL));
RL(close(acc));
/* fail EINPROGRESS without accept if we do set LOCAL_CONNWAIT */
RL(conn = socket(PF_LOCAL, SOCK_STREAM|SOCK_NONBLOCK, 0));
RL(setsockopt(conn, SOL_LOCAL, LOCAL_CONNWAIT, &one, sizeof(one)));
ATF_REQUIRE_ERRNO(EINPROGRESS,
connect(conn, (const struct sockaddr *)&sun, sizeof(sun)) == -1);
ATF_REQUIRE_ERRNO(EALREADY,
connect(conn, (const struct sockaddr *)&sun, sizeof(sun)) == -1);
/* accept should happen now and connect should finish */
RL(acc = accept(listener, NULL, NULL));
pfd = (struct pollfd){.fd = conn, .events = POLLOUT};
RL(nfd = poll(&pfd, 1, 0));
ATF_REQUIRE_MSG(pfd.revents & POLLOUT, "revents=0x%x", pfd.revents);
RL(getsockopt(conn, SOL_SOCKET, SO_ERROR, &error, &errorlen));
ATF_REQUIRE_MSG(errorlen == sizeof(error), "errorlen=%d", errorlen);
ATF_REQUIRE_MSG(error == 0, "error=%d", error);
RL(close(acc));
RL(close(conn));
RL(close(listener));
}
>Fix:
Yes, please!
Home |
Main Index |
Thread Index |
Old Index