Pergunta

Eu terminei recentemente um curso universitário em C. Por isso me falta experiência, é claro.

Algumas universidades tendem a ensinar seus alunos programação segura, ou pelo menos alguns elementos . Há mesmo um vídeo ( tirada aqui ).

Estar em C, copiando cordas, requer - tanto quanto eu sei - strcpy ou funções string.h. Como você usá-lo de forma segura em todos os dias de programação? Você tem algumas funções, que alocação alça para evitar de estouro de buffer? Há a CERT garantir padrão de codificação para C . Ele está oferecendo exemplos e soluções compatíveis:

int main(int argc, char *argv[]) {
  /* ... */
  char prog_name[128];
  strcpy(prog_name, argv[0]);
  /* ... */
}

E a alternativa é:

int main(int argc, char *argv[]) {
  /* ... */
  char *prog_name = (char *)malloc(strlen(argv[0])+1);
  if (prog_name != NULL) {
    strcpy(prog_name, argv[0]);
  }
  else {
    /* Couldn't get the memory - recover */
  }
  /* ... */
}

Tomado daqui, 2ª exemplo .

Mas, tanto quanto eu entendo que é apenas mais um desafio, mais código, mais trabalho. Por que ninguém mudar a própria biblioteca? Ou, pelo menos, por que ninguém fornecer uma biblioteca alternativa segura ou funções, que lidar com isso da maneira certa?

Obrigado pela leitura, Wishi

Foi útil?

Solução

A função Posix para este (disponível em quase todos os sistemas) é strdup(). strcpy() é usado se você não deseja alocar nova memória e já tem um buffer que deseja usar, mas então é melhor conhecido como grande que é tampão e se os ajustes da corda nele. Se você não sabe se os ajustes da corda, há strncpy() que copia apenas um determinado número de caracteres. Assim, você pode limitar a quantidade copiados para o seu tamanho buffers.

E, além disso, há muitas picar bibliotecas que gerenciam tamanhos de cordas de diferentes maneiras.

E uma vez que você marcou-o C ++:. Há std::string que faz todo o gerenciamento de memória para você e não lhe dá esses problemas

Outras dicas

l (strlcpy, strlcat) funções de OpenBSD são geralmente melhor do que o n funções, eles são ambos mais rápido e mais fácil de usar segurança, mas eles estão fora do padrão. No entanto, eles são BSD licenciado para que você pode incluir uma boa implementação conhecido em qualquer programa para que possa ser tanto de plataforma cruzada e seguro.

Para o Windows, se você não se preocupam com a portabilidade, você pode usar _s * funções.

Use strncpy :

#define BUFSIZE 127
int main(int argc, char *argv[]) {
  /* ... */
  char prog_name[BUFSIZE + 1];
  strncpy(prog_name, argv[0], BUFSIZE);
  progname[BUFSIZE]= '\0';
  /* ... */
}

Existem versões *n* para a maioria das funções str*.

Se bem entendi, a sua pergunta real é porque as funções da API não são feitas mais seguro.

Uma das razões razão é que a biblioteca C é o legado (tarde demais para mudar isso agora).

A principal razão, no entanto, é que a biblioteca é projetado para ser minimalista, para que ele faz o mínimo e é de responsabilidade do usuário para garantir que ele é chamado corretamente. Se ele estava fazendo todas as verificações excessivas, em seguida, um preço seria pago cada vez que é chamado, mesmo se o usuário pode assegurar por outras razões que nenhum problema vai ocorrer. Isto é muito, muito comum em muitas APIs.

Dito isto, há bibliotecas suficientes que fornecem alternativas mais seguras, eles não são apenas uma parte da biblioteca padrão. Além disso, muitas pessoas que fazem trabalho de maior coisas nível com C ++, que tem bibliotecas de classe padrão para muitas dessas coisas.

Na verdade, a Microsoft fez fornecer alternativas seguras para as funções CRT. Todo mundo que conheço odeia embora e desativa o aviso de que você não deve usar as antigas funções. Se você quer algo seguro, talvez você deve usar C ++. E em seguida, cordas STL ou algo como Qt.

Bem, ou você vai para plataformas como .NET ou Java, que normalmente não sofrem com esses problemas (seu aplicativo pode falhar, mas não há maneira de código de injetar em seu aplicativo através de um buffer overflow).

Edit: Com Data Execution Prevention / NX ativada (padrão para o Vista e .NET), isso não deve ser um problema para plataformas tradicionais.

int main
(
    int argc, 
    char *argV[]
) 
{
   char prog_name[128];
   if (strlen(argV[0]) < sizeof(prog_name))
   {
       strcpy(prog_name, argV[0]);
   }
   else
   {
       printf("%s is too large for the internal buffer\n", argV[0]);
   }

   return 0;
}

Talvez você iria encontrar respostas leitura útil para esta pergunta

scroll top