¿Por qué gcc (o glibc) no implementó las funciones _s?

6 minutos de lectura

avatar de usuario
suhdonghwi

_s funciones, como scanf_s, printf_s parece ser estándar opcional. MSVC ha implementado estas funciones, pero gcc no.

¿Hay alguna razón específica para no implementar funciones seguras? Es scanf de glibc lo suficientemente seguro?

  • Esto puede proporcionar algo de luz sobre la situación del Anexo K: open-std.org/jtc1/sc22/wg14/www/docs/n1967.htm

    – Christian Gibbons

    6 de junio de 2018 a las 15:58

  • Su conclusión: El diseño de las interfaces de verificación de Bounds, aunque bien intencionado, adolece de demasiados problemas para corregirlos. Se ha visto que el uso de las API conduce a un software menos seguro y de peor calidad que confiar en enfoques establecidos o tecnologías modernas. Los enfoques más efectivos y menos intrusivos se han vuelto comunes y, a menudo, son los preferidos tanto por los usuarios como por los expertos en seguridad. Por lo tanto, proponemos que el Anexo K se elimine de la próxima revisión de la norma C, o que quede obsoleto y luego se elimine.

    – Christian Gibbons

    6 de junio de 2018 a las 16:01

  • ¿No eran las funciones del Anexo K una iniciativa de Microsoft para empezar? ¿O al menos uno en el que MS estuvo profundamente involucrada?

    – John Bollinger

    6 de junio de 2018 a las 16:03

  • @lurker: ¿Dónde estás usando GCC? El problema está en realidad en la biblioteca C. Si está usando GCC en Windows y está configurado para conocer las funciones en Microsoft C RunTime (CRT), entonces podrá usarlas. Si no está en Windows, las funciones generalmente no están disponibles en la biblioteca C local. Puede encontrar algunas implementaciones complementarias, pero no necesariamente están completas. Consulte el documento N1967 para obtener más detalles sobre lo que (no) está disponible.

    –Jonathan Leffler

    6 de junio de 2018 a las 16:15

  • @JohnBollinger: Más o menos. El Anexo K *_s() funciones están íntimamente relacionadas, pero son críticamente diferentes de las *_s() funciones que Microsoft agregó a MSVC. Sí, creo que Microsoft jugó un papel decisivo en la producción del informe TR 24731-1, pero el resultado fue diferente en aspectos clave de lo que MS ya había lanzado en la naturaleza, y la compatibilidad con versiones anteriores se convirtió en un problema. MS no podría cumplir con el estándar fácilmente porque rompería sus promesas de compatibilidad con versiones anteriores.

    –Jonathan Leffler

    6 de junio de 2018 a las 16:24

avatar de usuario
jonathan leffler

los _s Las funciones son opcionales (Anexo K de la norma C11). Son ampliamente considerados como ‘no muy beneficiosos’.

En las respuestas a mi pregunta ¿Usas las funciones “seguras” de TR-24731?, puedes encontrar información sobre dónde hay problemas con la especificación estándar, como diferencias cruciales entre el estándar y la implementación de Microsoft. TR 24731-1 fue un informe técnico del comité de estándares C. El informe se incorporó casi palabra por palabra, con una función adicional, previamente omitida, IIRC, en el estándar C11 como (opcional pero ‘normativo’) Anexo K. También hay TR 24731-2 para un conjunto diferente de funciones, sin el _s sufijo. Encontró resistencia por un conjunto diferente de razones.

Asimismo, existe una propuesta ante el Comité de Normas C que se eliminen las funciones de la próxima revisión de la norma:

Ese documento es una lectura directa y convincente de las razones por las que el TR-24731 (*_s()) funciones no se han implementado ampliamente.

Las razones clave incluyen:

  • El problema solo se detecta una vez, luego se soluciona y luego el *_s() la función es innecesaria.
  • Esto hace que sea muy difícil probar el *_s() funciones, o el código que las utiliza.
  • No es fácil integrar las funciones nuevas en el código antiguo (que es donde se obtendrían mayores beneficios).
  • Las funciones inherentemente ralentizan el software con una verificación extensa pero redundante.

Consulte el documento para obtener más detalles. El documento termina con la sección:

Corrección técnica sugerida

A pesar de más de una década desde la propuesta original y casi diez años desde la ratificación de ISO/IEC TR 24731-1:2007, y casi cinco años desde la introducción de las interfaces de verificación de límites en el estándar C, no ha surgido ninguna implementación conforme viable. . Las API continúan siendo controvertidas y los implementadores continúan rechazando las solicitudes de implementación.

El diseño de las interfaces de verificación de Bounds, aunque bien intencionado, adolece de demasiados problemas para corregirlos. Se ha visto que el uso de las API conduce a un software menos seguro y de peor calidad que confiar en enfoques establecidos o tecnologías modernas. Los enfoques más efectivos y menos intrusivos se han vuelto comunes y, a menudo, son los preferidos tanto por los usuarios como por los expertos en seguridad.

Por lo tanto, proponemos que el Anexo K se elimine de la próxima revisión de la norma C, o que quede obsoleto y luego se elimine.

  • Honestamente, la única parte del Anexo K que siempre debe implementarse es memset_s y solo para admitir código sensible a la seguridad. Dicho esto, sería bueno tener un strtok reemplazo que también es multiplataforma.

    – Mgetz

    27 de junio de 2018 a las 16:07

  • Oh, he hecho eso, por strtok sería bueno que fuera parte del estándar en lugar de una feliz casualidad. Mantengo la necesidad de un memset_s aunque eso no se puede optimizar.

    – Mgetz

    27 de junio de 2018 a las 16:14

  • @Mgetz: Fui y miré C11 §7.24.6.1 El memset función y §K.3.7.4.1 El memset_s función y la diferencia útil es de hecho el requisito: a diferencia de memsetcualquier llamada al memset_s La función debe evaluarse estrictamente de acuerdo con las reglas de la máquina abstracta como se describe en (5.1.2.3). Es decir, cualquier llamada al memset_s asumirá que la memoria indicada por s y n puede ser accesible en el futuro y por lo tanto debe contener los valores indicados por c.

    –Jonathan Leffler

    27 de junio de 2018 a las 16:20


  • Ese requisito significa que las llamadas a memset_s() es posible que no se optimice, incluso si la variable que se está configurando no se vuelve a referenciar. Eso, a su vez, permite que un programador se asegure de que las contraseñas se anulen cuando ya no se necesiten y otras operaciones similares. El argumento adicional no es realmente necesario; la semántica adicional relacionada con la (no) optimización ciertamente es útil en un conjunto pequeño pero significativo de casos de uso.

    –Jonathan Leffler

    27 de junio de 2018 a las 16:22


  • @JonathanLeffler: Más importante que un particular memset_s La función, creo, sería un medio general de obligar al compilador a sincronizar los estados de los objetos de máquina abstracta y el estado de la memoria visto por la CPU. Usando un ordinario memset seguido de una fuerza de sincronización sería equivalente a memset_s, pero el código consciente de la seguridad también necesita sincronización para otros fines. Por ejemplo, algo como unsigned u = *p; if (u < ARRAY_SIZE) array[u]++; podría introducir una vulnerabilidad de seguridad si *p se carga una vez para la comparación y nuevamente para el paso de indexación.

    – Super gato

    28 de junio de 2018 a las 19:29

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad