handleAccept handles the accept(2) and accept4(2) syscalls.
(n *seccomp.Notif, fd int, addrPtr uintptr, addrSizePtr uintptr, flags int)
| 409 | |
| 410 | // handleAccept handles the accept(2) and accept4(2) syscalls. |
| 411 | func (p *Process) handleAccept(n *seccomp.Notif, fd int, addrPtr uintptr, addrSizePtr uintptr, flags int) error { |
| 412 | s, ok := p.getSocket(fd) |
| 413 | if !ok { |
| 414 | return n.Skip() |
| 415 | } |
| 416 | |
| 417 | ret, errno, err := s.Accept(flags) |
| 418 | if err != nil { |
| 419 | return fmt.Errorf("accept socket: %w", err) |
| 420 | } |
| 421 | if errno != 0 { |
| 422 | return n.Return(0, errno) |
| 423 | } |
| 424 | |
| 425 | if addrPtr != 0 && addrSizePtr != 0 { |
| 426 | peer, errno, err := ret.PeerAddr() |
| 427 | if err != nil { |
| 428 | return fmt.Errorf("get peer addr of accepted socket: %w", err) |
| 429 | } |
| 430 | if errno != 0 { |
| 431 | return n.Return(0, errno) |
| 432 | } |
| 433 | |
| 434 | if s.Inode.Domain == unix.AF_INET6 && peer.Addr().Is4() { |
| 435 | // `python -m http.server -b ::` followed by `curl -4 localhost:8000` |
| 436 | // reports the client address as ::ffff:127.0.0.1, not the IPv4 address. |
| 437 | peer = netip.AddrPortFrom(netip.AddrFrom16(peer.Addr().As16()), peer.Port()) |
| 438 | } |
| 439 | |
| 440 | errno, err = p.vmWriteSockaddr(n, peer, addrPtr, addrSizePtr) |
| 441 | if err != nil { |
| 442 | return fmt.Errorf("write sock addr: %w", err) |
| 443 | } |
| 444 | if errno != 0 { |
| 445 | // TODO(adtac): gvisor [0] says Linux doesn't give you an error here, but |
| 446 | // it looks like the kernel source code does [1]. Check who is right here. |
| 447 | // [0] https://github.com/google/gvisor/blob/7b151e25d076b81480456069917baffc2808578f/pkg/sentry/syscalls/linux/sys_socket.go#L313 |
| 448 | // [1] https://elixir.bootlin.com/linux/v6.7/source/net/socket.c#L1942 |
| 449 | return n.Return(0, errno) |
| 450 | } |
| 451 | } |
| 452 | |
| 453 | if err := p.installSocket(n, ret, flags&unix.SOCK_CLOEXEC); err != nil { |
| 454 | return fmt.Errorf("install socket: %w", err) |
| 455 | } |
| 456 | return nil |
| 457 | } |
| 458 | |
| 459 | // handleGetsockopt handles the getsockopt(2) syscall to emulate SO_ERROR. |
| 460 | func (p *Process) handleGetsockopt(n *seccomp.Notif, fd int, level int, name int, valPtr uintptr, valSizePtr uintptr) error { |
no test coverage detected