strncat library funciona como c++ c string strncpy

c++ - library - ¿Por qué strncpy es inseguro?



strncpy c (6)

El problema original es obviamente que strcpy(3) no era una operación segura de memoria , por lo que un atacante podría suministrar una cadena más larga que el búfer que sobrescribiría el código en la pila y, si se organizaba cuidadosamente, podría ejecutar código arbitrario del atacante.

Pero strncpy(3) tiene otro problema, ya que no proporciona la terminación nula en todos los casos en el destino. (Imagine una cadena fuente más larga que el búfer de destino.) Las operaciones futuras pueden esperar cadenas C terminados conforme entre búferes de igual tamaño y un mal funcionamiento aguas abajo cuando el resultado se copia a un tercer búfer.

Usar strncpy (3) es mejor que strcpy (3) pero cosas como strlcpy (3) son aún mejores.

Estoy buscando averiguar por qué strncpy se considera inseguro. ¿Alguien tiene algún tipo de documentación sobre esto o ejemplos de un exploit que lo usa?


La peor situación se produce cuando la memoria de búfer de origen y de destino se superpone entre sí. Así que evite el uso de strncpy cuando sienta que puede haber una superposición de situaciones en su programa. En lugar de strncpy puede usar la función memmove en el escenario de superposición.

A continuación, describo un ejemplo simple que describe el strncpy en el escenario de superposición.

#include <stdio.h> #include <string.h> int main() { char aszMessage[10] ="12345"; //Source Buffer short siLen=4; // Length of byte you want to copy strncpy(aszMessage + 2,aszMessage+1,siLen);//Here memory overlap printf("/n/n/tMessage = %s/n",aszMessage); return 0; }

Aquí estoy de acuerdo, la salida debería ser 122345, pero aquí la salida es 122222, ese es el escenario de mayor caída de strncpy.

Este problema se puede resolver usando la función memove.

#include <stdio.h> #include <string.h> int main() { char aszMessage[10] ="12345"; //Source Buffer short siLen=4; // Length of byte you want to copy memmove(aszMessage + 2,aszMessage+1,siLen);//Here memory overlap printf("/n/n/tMessage = %s/n",aszMessage); return 0; }

Ahora estoy obteniendo el deseo de salida 122345.

Para obtener más detalles, puede ver este enlace http://aticleworld.com/how-to-use-strncpy-and-how-to-write-your-own-strncpy/


La pregunta se basa en una premisa "cargada", que hace que la pregunta en sí no sea válida.

La conclusión es que strncpy no se considera inseguro y nunca se ha considerado inseguro. Las únicas afirmaciones de "inseguridad" que se pueden atribuir a esa función son las afirmaciones generales de la inseguridad general del modelo de memoria C y el lenguaje C en sí mismo. (Pero obviamente ese es un tema completamente diferente).

Dentro del reino del lenguaje C, la creencia equivocada de algún tipo de "inseguridad" inherente a strncpy se deriva del patrón dudoso generalizado de usar strncpy para "copia segura de cadenas", es decir, algo que esta función no hace y nunca ha sido concebida. Tal uso es de hecho altamente propenso a errores. Pero incluso si pone un signo de igualdad entre "altamente propenso a errores" e "inseguro", sigue siendo un problema de uso (es decir, una falta de problema educativo) no un problema strncpy .

Básicamente, se puede decir que el único problema con strncpy es una asignación de nombres desafortunada, lo que hace que los programadores novatos asuman que entienden lo que hace esta función en lugar de leer la especificación. Al mirar el nombre de la función, un programador incompetente asume que strncpy es una "versión segura" de strcpy , mientras que en realidad estas dos funciones no están relacionadas.

Exactamente el mismo reclamo se puede hacer contra el operador de división, por ejemplo. Como la mayoría de ustedes sabe, una de las preguntas más frecuentes sobre el lenguaje C es "Asumí que 1/2 evaluará a 0.5 pero en su lugar obtuve 0 ¿Por qué?" Sin embargo, no afirmamos que el operador de la división sea inseguro solo porque los principiantes del lenguaje tienden a malinterpretar su comportamiento.

Para otro ejemplo, no llamamos a las funciones del generador de números pseudoaleatorio "inseguras" solo porque los programadores incompetentes a menudo se sorprenden desagradablemente por el hecho de que su salida no es verdaderamente aleatoria.

Así es exactamente con la función strncpy . Así como a los programadores principiantes les toma tiempo aprender qué hacen realmente los generadores de números pseudoaleatorios, les lleva tiempo aprender qué es realmente lo que strncpy hace. Lleva tiempo aprender que strncpy es una función de conversión , destinada a convertir cadenas terminadas en cero a cadenas de ancho fijo . Lleva tiempo aprender que strncpy tiene absolutamente nada que ver con la "copia segura de cadenas" y que no se puede usar con ese propósito.

Por supuesto, generalmente un estudiante de idiomas necesita mucho más tiempo para aprender el propósito de strncpy que para resolver las cosas con el operador de la división. Sin embargo, esta es una base para cualquier reclamo de "inseguridad" contra strncpy .

PS El documento CERT vinculado en la respuesta aceptada está dedicado exactamente a eso: demostrar las inseguridades del típico abuso incompetente de la función strncpy como una versión "segura" de strcpy . De ninguna manera pretende decir que strncpy sí mismo es de alguna manera inseguro.


Los peligros de strncpy, _snprintf y wcsncpy deberían ser igualmente conocidos, pero aparentemente no lo son. Estas funciones le permiten especificar el tamaño del búfer pero, y esto es realmente importante, no garantizan la terminación nula. Si le pide a estas funciones que escriban más caracteres que llenarán el búfer, se detendrán, evitando así el desbordamiento del búfer, pero no anularán el búfer. Para usar estas funciones correctamente, tienes que hacer este tipo de tonterías.

Por favor, consulte el siguiente enlace para su referencia!

https://randomascii.wordpress.com/2013/04/03/stop-using-strncpy-already/


Para usar strncpy de forma segura, uno debe (1) pegar manualmente un carácter nulo en el búfer de resultados, (2) saber que el búfer termina con un nulo de antemano y pasar (longitud-1) a strncpy, o (3) saber que el buffer nunca se copiará usando ningún método que no vincule su longitud a la longitud del buffer.

Es importante tener en cuenta que strncpy llenará cero todo en el búfer más allá de la cadena copiada, mientras que otras variantes strcpy de longitud limitada no lo harán. En algunos casos, esto puede ser una pérdida de rendimiento, pero en otros casos puede ser una ventaja de seguridad. Por ejemplo, si se usa strlcpy para copiar "supercalifragilisticexpalidocious" en un búfer y luego para copiar "it", el búfer contendrá "it ^ ercalifragilisticexpalidocious ^" (usando "^" para representar un byte cero). Si el búfer se copia a un formato de tamaño fijo, los datos adicionales pueden etiquetarse junto con él.


Echa un vistazo a este sitio ; es una explicación bastante detallada. Básicamente, strncpy() no requiere terminación de NUL y, por lo tanto, es susceptible a una variedad de exploits.