¿Hay una manera de evadir -Wformat-security?

3

Estoy tratando de aprender sobre errores de cadena de formato y encontré la opción gcc -Wformat-security para generar una advertencia cuando se encuentra un error potencial de cadena de formato. Me gustaría saber si hay una manera de evadir esta comprobación y aún tener un problema de error de formato. Por ejemplo:

#include <stdio.h>
#include <stdlib.h>

int main (int argc, char * argv[])
{
  char outbuf[32];
  char buffer[32];

  if (argc < 2)
  {
     fprintf (stderr, "Error missing argument!\n");
     exit (EXIT_FAILURE);
  }

  snprintf (buffer, 28, "ERR Wrong command: %8s", argv[1]);
  sprintf (outbuf, buffer);

  perror(outbuf);

  return EXIT_SUCCESS;
}

Cuando se compila en 32 bits, se bloqueará en la entrada %21d (no en %20d , pero en cualquier número superior a 20). Pero, -Wformat-security lo detectará y emitirá una advertencia de la siguiente manera:

$> gcc -m32 -Wall -Wextra -Wformat-security -std=c99 -o fstring fstring.c 
fstring.c: In function ‘main’:
fstring.c:19:3: warning: format not a string literal and no format arguments [-Wformat-security]
   sprintf (outbuf, buffer);
   ^

Entonces, ¿hay alguna forma de ocultar el error de la advertencia y aún tener una posible explotación?

Editar : mi punto no es corregir el error, sino entender qué tipo de errores de cadena de formato no son capturados por esta advertencia. Es útil comprender dónde buscar si no se genera ninguna advertencia, pero hay posibles errores de cadena de formato.

    
pregunta perror 11.11.2013 - 22:58
fuente

1 respuesta

4

Debe mantener el formato seguro de la función y con el uso de los argumentos no deseados, omita el formato de seguridad. ¡Por ejemplo, por ejemplo, printf(var); es 100% inseguro! y un compilador capaz de detectarlo, pero printf(var1,var2) (puede ser seguro y también peligroso)! El compilador no es lo suficientemente inteligente como para detectar.
Puedes usar un código como printf(argv[1],"junk");

Por ejemplo

#include <stdio.h>
#include <stdlib.h>

int main (int argc, char * argv[])
{
  printf (argv[1],argc);
  //              ^^^^---------> Junk :)
  return EXIT_SUCCESS;
}
/*
sajjad@xxx:~$ gcc -m32 -Wall -Wextra -Wformat-security -std=c99 a.c 
sajjad@xxx:~$ ./a.out %n%n%n
Bus error: 10
sajjad@xxx:~$ ./a.out %s%s%s
Bus error: 10
sajjad@xxx:~$ ./a.out %x%x%x
bffcfb242bffcfb88sajjad@xxx:~$ ./a.out %d%d%d
-10747629722-1074762872sajjad@xxx:~$ ./a.out %s
???|???sajjad@xxx:~$
/*

/*

#include <stdio.h>
#include <stdlib.h>

int main (int argc, char * argv[])
{
  char outbuf[32];
  char buffer[32];

  if (argc < 2)
  {
     fprintf (stderr, "Error missing argument!\n");
     exit (EXIT_FAILURE);
  }

  snprintf (buffer, 28, "ERR Wrong command: %8s", argv[1]);
  sprintf (outbuf,buffer, "junk");
  //                      ^^^^^^---------> Junk :)
  perror(outbuf);

  return EXIT_SUCCESS;
}

*/
    
respondido por el Sajjad Pourali 12.11.2013 - 00:13
fuente

Lea otras preguntas en las etiquetas