Reject unrepresentable POSIX listener descriptors before Unix-domain accept
Maintainer thường phản hồi trong vòng 1 ngày
Đá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ả
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
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- 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.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của wavefnd/Wave
-
bug help wanted
Độ khó 5/5 Hơn một tuần Mức phù hợp với người mới 35/100
Maintainer thường phản hồi trong vòng 1 ngày
-
bug help wanted
Độ khó 4/5 3-5 ngày Mức phù hợp với người mới 53/100
Maintainer thường phản hồi trong vòng 1 ngày
-
bug build help wanted
Độ khó 4/5 3-5 ngày Mức phù hợp với người mới 56/100
Maintainer thường phản hồi trong vòng 1 ngày
-
bug ci help wanted
Độ khó 4/5 3-5 ngày Mức phù hợp với người mới 48/100
Maintainer thường phản hồi trong vòng 1 ngày
-
Prevent compiler stack overflow on long acyclic forward type-alias chainsCó thể đã có người làm @hiyouwhatsapp đã nhận 4 ngày trước. Đang mởbug
Độ khó 4/5 3-5 ngày Mức phù hợp với người mới 35/100
Maintainer thường phản hồi trong vòng 1 ngày
Issue tương tự
-
binding:python bug
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 82/100
Maintainer thường phản hồi trong vòng 1 ngày
-
enhancement
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
coollabsio/orbit#72 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
enhancement
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 70/100
-
bug order-flow studies ui
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 88/100
userFRM/egui-charts#2417 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 72/100
Maintainer thường phản hồi trong vòng 2 ngày