Reject unrepresentable POSIX listener descriptors before Unix-domain accept

Đang mở Phù hợp với người mới
#1,082 1 bình luận 0 reaction 0 người được giao Xem trên GitHub

Maintainer thường phản hồi trong vòng 1 ngày

@ShahadatTest đang làm issue này rồi.

Từ ngày 3/11/2026.

  • #1083 của @ShahadatTest — đang mở

Đánh giá

Độ khó
2/5
Thời gian dự kiến
1-3 giờ
Mức phù hợp với người mới
84/100
Loại issue
Lỗi
Độ rõ ràng
Đặc tả rõ ràng
Mức độ hoạt động
Sôi nổi
Công nghệ
rust
Lĩnh vực
backend, networking

Hướng nghiên cứu

Đọc std/net/unix.wave tại unix_accept và so sánh phần xác thực của nó với std/net/socket_base.wave cùng các đường đi được bảo vệ net_accept_v4/net_accept_v6. Thêm kiểm thử hồi quy cho các bộ mô tả quá lớn và trở thành số âm khi bị cắt cụt, đồng thời kiểm tra rằng một accept hợp lệ tiếp theo nhận được kết nối đang chờ trong hàng đợi và dữ liệu. Chạy các kiểm thử hồi quy ở O0 và O2; báo cáo riêng kết quả trên các hệ thống không phải Linux.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Mô tả

bug good first issue

Problem

unix_accept calls the native accept provider directly without the existing target-aware net_fd_valid guard. Its public listener field is i64, but POSIX descriptors are narrower. A value such as live_fd + 2^32 or live_fd - 2^32 is rejected by net_fd_valid yet can alias the real listener during the native call, consuming its queued connection.

Starting points: unix_accept and the existing target-aware descriptor validation. The guarded net_accept_v4/net_accept_v6 paths are useful references.

Reproduction

Audited canonical master e1f8effd195b6339c3979b1e091e63c25f1da983 on Linux amd64 with checkout-built Wave 0.0.1-alpha-dev, matching std, Rust 1.89.0, Cargo jobs=2 and LLVM 21.1.8. The master SHA was rechecked before registration.

The audit executed both offsets at O0 and O2 using fresh inherited, nonblocking local Unix listeners and one queued byte. The following compact reproduction combines those cases; no remote service is involved:

from pathlib import Path
import socket
import subprocess
import tempfile

root = Path.cwd()
compiler = root / "target/debug/wavec"
with tempfile.TemporaryDirectory(prefix="wave-unix-accept-") as temporary:
    directory = Path(temporary)
    for optimization in ("-O0", "-O2"):
        for delta in (4294967296, -4294967296):
            with socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) as listener:
                with socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) as client:
                    address = directory / "listen"
                    if address.exists():
                        address.unlink()
                    listener.bind(str(address))
                    listener.listen(2)
                    listener.setblocking(False)
                    client.connect(str(address))
                    client.sendall(b"Z")
                    source = directory / "probe.wave"
                    binary = directory / "probe"
                    source.write_text(f"""
import("std::net::unix")::{{UnixListener,UnixStream,unix_accept,unix_read,unix_close}};
import("std::net::error")::{{NetResult,NetIoResult}};
import("std::net::socket_base")::{{net_fd_valid}};
fun main() -> i32 {{
    var invalid: i64 = {listener.fileno()} + ({delta});
    var result: NetResult<UnixStream> = unix_accept(UnixListener {{ fd: invalid }});
    println("valid={{}} accepted={{}} error={{}}",
        net_fd_valid(invalid), result.ok, result.error.native_code);
    if (result.ok) {{
        var sample: u8 = 0;
        var read: NetIoResult = unix_read(result.value, &sample, 1);
        println("read={{}} byte={{}}", read.count, sample);
        unix_close(result.value);
    }}
    return 0;
}}
""", encoding="utf-8")
                    subprocess.run([
                        str(compiler), "--std-root", str(root / "std"), "build",
                        str(source), optimization, "-o", str(binary),
                    ], check=True, capture_output=True, timeout=45)
                    result = subprocess.run(
                        [str(binary)], pass_fds=(listener.fileno(),),
                        capture_output=True, text=True, timeout=3,
                    )
                    print(optimization, delta, result.returncode, result.stdout.strip())

Observed for both offsets at O0/O2:

valid=0 accepted=1 error=0
read=1 byte=90

The invalid listener consumed a valid pending connection, and the accepted stream read Z. Reusing a listener after its connection was drained would not be a valid negative control.

Scope

Apply the existing target-aware descriptor guard before accepting a Unix-domain connection. Reject invalid listeners without accepting, closing or otherwise modifying the real descriptor or queued connection. Preserve valid-listener behavior, ordinary provider error contracts and full-width Windows SOCKET handling where applicable.

Related: #988 fixed ordinary portable socket entry points, #1069 timed TCP and #807 readiness. This direct Unix accept path is a separate remaining omission.

This is suitable for a first contribution: one public entry point, an established validation helper and a deterministic local-socket regression. No new API or descriptor-width policy is needed.

Completion criteria

  • Oversized and truncating-negative POSIX descriptors fail before native accept.
  • The pending connection and its queued data remain available to a subsequent valid accept.
  • Valid and ordinary invalid listeners retain expected results.
  • O0/O2 regressions exercise both offsets; non-Linux execution is reported separately rather than inferred from the Linux reproduction.
Ngôn ngữ chính
Rust
Star
56
Fork
21
Merge trung bình
22 giờ 57 phút
Pull request đã merge (30 ngày)
46

Chuẩn bị môi trường

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Issue khác của wavefnd/Wave

Tất cả issue của wavefnd/Wave

Issue tương tự

Thêm issue về Rust

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.