Reject unrepresentable POSIX listener descriptors before Unix-domain accept
Los mantenedores suelen responder en 1 día
Evaluación
- Dificultad
- 2/5
- Tiempo estimado
- 1-3 horas
- Aptitud para principiantes
- 84/100
- Tipo de issue
- Error
- Claridad
- Bien especificado
- Estado de actividad
- Activo
- Stack tecnológico
- rust
- Área
- backend, networking
Línea de trabajo
Lee std/net/unix.wave en unix_accept y compara su validación con std/net/socket_base.wave y las rutas protegidas net_accept_v4/net_accept_v6. Añade pruebas de regresión para descriptores demasiado grandes y negativos al truncarse, y comprueba que un accept válido posterior recibe la conexión en cola y los datos. Ejecuta las regresiones con O0 y O2; informa por separado de los resultados en sistemas que no sean Linux.
Escrito por el modelo de indexación a partir del texto del issue.
Descripción
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.
- Lenguaje dominante
- Rust
- Estrellas
- 56
- Forks
- 21
- Merge medio
- 20 h 49 min
- PR fusionados (30 d)
- 45
Preparar el entorno
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de wavefnd/Wave
-
bug help wanted
Dificultad 5/5 Más de una semana Aptitud para principiantes 35/100
Los mantenedores suelen responder en 1 día
-
bug help wanted
Dificultad 4/5 3-5 días Aptitud para principiantes 53/100
Los mantenedores suelen responder en 1 día
-
bug build help wanted
Dificultad 4/5 3-5 días Aptitud para principiantes 56/100
Los mantenedores suelen responder en 1 día
-
bug ci help wanted
Dificultad 4/5 3-5 días Aptitud para principiantes 48/100
Los mantenedores suelen responder en 1 día
-
Prevent compiler stack overflow on long acyclic forward type-alias chainsPosiblemente ocupada @hiyouwhatsapp la tomó hace 3 días. Abiertobug
Dificultad 4/5 3-5 días Aptitud para principiantes 35/100
Los mantenedores suelen responder en 1 día
Todos los issues de wavefnd/Wave
Issues similares
-
bug
Dificultad 2/5 1-3 horas Aptitud para principiantes 73/100
Los mantenedores suelen responder en 1 día
-
🐞 bug 🧩 bevy_gantz_egui
Dificultad 2/5 1-3 horas Aptitud para principiantes 82/100
nannou-org/gantz#500 ·
Los mantenedores suelen responder en 1 día
-
[Feature]: Fedora 45 repoAbiertoenhancement
Dificultad 2/5 1-3 horas Aptitud para principiantes 68/100
metasequoiaime/msime#10989 ·
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
fritzprix/libr-agent#2612 ·
Los mantenedores suelen responder en 1 día
-
find: -printf %h drops a doubled slashPosiblemente ocupada @qodelicious la tomó hoy. Abierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 68/100
Los mantenedores suelen responder en 1 día