Pergunta

Recentemente, deparei com um artigo que as reivindicações Microsoft está banindo a função memcpy() em suas lojas de programação segura. Eu entendo as vulnerabilidades inerentes à função, mas é necessário proibir o seu uso inteiramente?

programas Devo escrever estar evitando memcpy() inteiramente, ou apenas garantir que ele é usado de forma segura? Que alternativas existem que fornecem functionalilty semelhante, mas mais seguro?

Foi útil?

Solução

A Microsoft fornece href="http://msdn.microsoft.com/en-us/library/wes2t00f.aspx" para memcpy e wmemcpy que validam seus parâmetros.

memcpy_s diz, "Hmm, antes de ler a partir deste endereço, deixe-me verificar por mim mesmo que ele não é um ponteiro nulo, e antes de eu escrever para este endereço, vou realizar esse teste novamente I deve também comparar o número. de bytes fui solicitado para copiar para o tamanho reivindicou do destino;. se e somente se a chamada passa todos esses testes devo realizar a cópia "

memcpy diz "Coisas do destino em um registrador, encher a fonte em um registrador, coisas a contagem em um registrador, execute MOVSB ??ou MOVSW." (Exemplo de geocities, não muito tempo neste mundo: http: // www. geocities.com/siliconvalley/park/3230/x86asm/asml1013.html )

Editar: Para um exemplo na natureza do O seu desejo é uma ordem abordagem para memcpy, considere OpenSolaris, onde memcpy é (para algumas configurações) definido em termos de bcopy, e bcopy (para algumas configurações) é ...

void
     33 bcopy(from, to, count)
     34 #ifdef vax
     35     unsigned char *from, *to;
     36     int count;
     37 {
     38 
     39     asm("   movc3   12(ap),*4(ap),*8(ap)");
     40 }
     41 #else
     42 #ifdef u3b      /* movblkb only works with register args */
     43     unsigned char *from, *to;
     44     int count;
     45 {
     46     asm("   movblkb %r6, %r8, %r7");
     47 }
     48 #else
     49     unsigned char *from, *to;
     50     int count;
     51 {
     52     while ((count--) > 0)
     53         *to++ = *from++;
     54 }
     55 #endif

Edit: Obrigado, Millie Smith! Aqui está o que estava na página geocities I ligada acima:

MOVS

Os movs de instrução é usado para copiar cadeia de origem para o destino (sim, copiar, não se move). Esta instrução tem duas variantes: movsb e MOVSW. O movsb ( "move cadeia de bytes") move um byte de cada vez, enquanto se move MOVSW dois bytes de cada vez.

Uma vez que nós gostaríamos de mover vários bytes de cada vez, estas instruções movs são feitos em lotes usando o prefixo rep. O número de movimentos é especificado pelo registo CX. Veja o exemplo abaixo:

:
lds   si, [src]
les   di, [dest]
cld
mov   cx, 100
rep   movsb
:

Este exemplo irá copiar 100 bytes de src para dest. Se você substituir movsb com MOVSW, você copiar 200 bytes em vez. Se você remover o prefixo representante, o registo CX não terá nenhum efeito. Você vai passar um byte (se é movsb, ou 2 bytes se é MOVSW).

Outras dicas

A motosserra, se usado corretamente, é seguro. A mesma coisa com memcpy (). Mas em ambos os casos, se você bater um prego, ele pode voar e feri-lo.

Em suma, memcpy () é necessário para baixo nível de computação e não vai desaparecer, mas de alto nível de programação que você não precisa dele. Não há memcpy () em Python.

Não se preocupe. Microsofts alternativas não são muito melhor. O valor principal é que estes causam o seu código para se tornar portável para Linux. A Microsoft está fazendo muito mais dinheiro no sistema operacional que eles vendem aos seus clientes que eles estão fazendo na cópia do Visual C ++ que você comprou.

O artigo descreve-se uma alternativa mais segura: memcpy_s, que requer que você especifique o tamanho máximo do alvo. Quando este número é fornecido independente da quantidade de bytes a ser transferido, que actua como uma barreira para impedir a sobrecarga do buffer. Claro, você pode abusar que, dando o mesmo número a ambos.

É proibição memcpy () no meu código fazendo-me um programador melhor e meu aplicativo mais seguro ou apenas mais incompatíveis? Estou incerto, se MS realmente quer mudar alguma coisa ou apenas fazer qualquer novo incompatível código C com outros compiladores. Btw. MS faz este truque em muitas funções e é muito chato. strcpy -> strcpy_s -.> StringCchCopy

Eu acho que C deve deixar uma opção para o programador para filmar seu próprio pé. gerenciamento de memória manual é seguro, se feito corretamente.

Você mesmo disse: "A Microsoft está banindo a função memcpy () em suas lojas programação segura , eu entendo os vulnerabilidades inerentes a função ,"

memcpy () e uma infinidade de outras funções padrão são conhecidos por causar vulnerabilidades, então por que uma loja de programação segura permitir o seu uso quando um (ainda que parcial) melhoria é trivial?

Sem dúvida, em seus esforços para melhorar a segurança dos seus próprios produtos, as revisões de código claramente indicado que essas funções foram responsáveis ??por uma proporção significativa de vulnerabilidades, buffer overflows etc. Em vez de wrappers make para uso interno, eles introduziram-los em a biblioteca padrão e acrescentou um aviso do compilador (não uma proibição) para o benefício de todos.

Se você estiver usando versões mais antigas, como C99 ou C ++ 98, ou no Solaris, você não pode usar memcpy_s, a menos que você tem a biblioteca Seguro C instalado.

memcpy_s () é uma implementação específica do Microsoft que não existe no não-MS implementações, incluindo ANSI, antes de C11, por seus próprios padrões.

Vou deixar o pro-MS e anti-MS coisas de lado, porque é irrelevante.

memmove () é uma solução melhor de qualquer maneira, uma vez que abordou a questão de sobreposição. memmove_s () é mais robusto, mas novamente, só se você estiver em C11 ou mais tarde.

A alternativa é chamar memcpy_s

Você é suposto memcpy_s de uso () em vez. O mesmo tipo de versões _s existem para uma variedade de outras funções consideradas como não seguro.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top