Lectura y escritura fuera de límites en qsort() de glibc
Una lectura y escritura fuera de límites recientemente identificada en `qsort()` de glibc aparece solo cuando los programas le pasan una función de comparación “mala”, como una que desborda al restar enteros o viola las reglas de ordenación con flotantes y NaN. Los comentaristas debaten si esto es realmente una vulnerabilidad de seguridad en glibc o simplemente comportamiento indefinido causado por código incorrecto del llamador, y si merece un CVE dada su rareza y dificultad de explotación. El hilo se amplía hacia una comparación de las culturas de seguridad en C/C++ frente a Rust y otros lenguajes, discutiendo cuánto deben defender las bibliotecas contra el uso indebido frente a preservar rendimiento y simplicidad.
Naturaleza del error de qsort
- El error es una lectura/escritura fuera de límites en
qsortde glibc cuando la llamada suministra una función de comparación no transitiva (con errores). - Muchos lo ven como “error del usuario” (parámetro inválido), análogo a llamar a
memcpycon punteros incorrectos, pero aun así coinciden en que corregir las comprobaciones de límites es una buena práctica defensiva. - Otros subrayan que la implementación “obvia” del comparador (
a - b) es sutilmente incorrecta debido al desbordamiento entero, así que esto no es puramente un caso extremo exótico.
“Lo estás usando mal” vs vulnerabilidad de seguridad
- Un bando argumenta que esto es principalmente un error en el código de la aplicación, ya que los estándares exigen explícitamente un orden total; el comportamiento indefinido recae en quien llama.
- Otro bando dice que, si un uso indebido común puede causar corrupción de memoria, eso es un problema legítimo de seguridad y merece un CVE para la implementación de la biblioteca también.
- Hay críticas hacia la actitud de “como es UB, vale cualquier cosa” en la cultura de C/C++, en contraste con normas más defensivas en otros entornos.
Comparadores, NaN y coma flotante
- Ordenar flotantes con NaN o infinitos mal gestionados puede violar los requisitos del comparador, provocando fallos o comportamientos incorrectos.
- Los ejemplos muestran cómo los NaN rompen la reflexividad y la transitividad, confundiendo a los algoritmos de ordenación. Algunos sugieren que intentar ordenar NaN es, en sí mismo, normalmente un error lógico.
Culturas de seguridad del lenguaje y desbordamiento entero
- Se cita Rust como ejemplo de tratar los casos de “lo estás usando mal” como problemas de seguridad: los comparadores defectuosos pueden dar resultados erróneos pero no UB; traits como
Ordson seguros, con “unsafe traits” separados para invariantes que pueden causar UB si se rompen. - Discusión sobre el manejo del desbordamiento:
- Operaciones comprobadas/saturadas/por envoltura en Rust y comportamiento de depuración frente a compilación de रिलीज़.
- Desbordamiento con signo en C/C++ como UB; el wraparound sin signo a menudo no es lo que los programadores pretenden.
- Ada, Pascal y WUFFS como ejemplos de lenguajes o DSL que codifican rangos/refinamientos para mayor seguridad.
Rendimiento y alternativas a qsort
qsortse describe como relativamente lento; para código de alto rendimiento se recomiendastd::sortde C++ o bibliotecas especializadas, a veces mediante un envoltorio fino de C++ invocable desde C.- Algunos se preocupan por el coste de rendimiento de comprobaciones de seguridad adicionales; otros argumentan que el coste suele ser insignificante.
Explotabilidad, CVE y puntuación
- Se debate la explotabilidad: requiere un comparador ya defectuoso y, a menudo, un contexto privilegiado (por ejemplo, setuid-root); en el hilo no se conocen explotaciones reales.
- Hay opiniones encontradas sobre si debe emitirse un CVE:
- A favor: anima a los usuarios a auditar comparadores y actualizar.
- En contra: los CVE son costosos para entornos regulados y deberían reservarse para problemas claramente explotables.
- Frustración más amplia con las puntuaciones CVSS: algunos errores graves y fácilmente explotables obtienen puntuaciones bajas, mientras que errores impracticables de tipo DoS reciben puntuaciones altas, dificultando la priorización.