Ci sono alcuni buffer binari con dimensioni fisse in un programma che vengono utilizzati per memorizzare i dati. E memcpy è usato per copiare il buffer da uno all'altro. Poiché il buffer di origine potrebbe essere più grande del buffer di destinazione. Come posso rilevare se c'è overflow del buffer?Come evitare l'overflow del buffer memcpy?
risposta
È necessario conoscere la quantità di dati presente nel buffer di origine e la quantità di spazio disponibile nel buffer di destinazione.
Non chiamare memcpy()
se non c'è spazio sufficiente nel buffer di destinazione per tutti i dati che si desidera copiare dal buffer di origine. (È necessario decidere se è corretto troncare i dati se la fonte è più grande della destinazione.)
Se non si conosce, riscrivere il codice in modo da sapere quanto spazio ci sia; altrimenti, non è sicuro.
Nota: se è possibile che i buffer di origine e di destinazione si sovrappongano, è necessario utilizzare memmove()
anziché memcpy()
.
In C++, guardare in primo luogo utilizzando memcpy()
in primo luogo; questa è un'operazione in stile C piuttosto che C++.
Grazie. qual è il modo corretto di fare la copia di memoria in C++? –
@MichaelD: memorizza i tuoi dati in un 'std :: vector <>', e usa semplicemente 'vector2 = vector1'. – MSalters
Come posso inserire dati nel vettore? usa push_back per inserire data byte per byte? –
Si dovrebbe sempre conoscere e controllare la dimensione dei buffer src e dest!
void *memcpy(void *dest, const void *src, size_t n);
n
non dovrebbe mai essere più grande di quanto src
o dest
dimensioni.
Se ad esempio si dispone di:
destinazione 4 byte dimensioni
fonte 5 byte dimensioni
Si può fare in modo di copiare, al massimo, 4 byte di buffer di destinazione:
size_t getCopySize(size_t sourceSize, size_t destSize)
{
return (destSize <= sourceSize ? destSize : sourceSize);
}
memcpy(destination, source, getCopySize(sizeof(source),sizeof(destination)));
In base all'applicazione, è possibile anche assicurarsi che i dati rimanenti vengano copiati in un secondo momento, oppure è possibile saltarlo se alcuni dati possono essere ignorati.
Come posso rilevare se c'è overflow del buffer?
Penso che tu abbia tre o quattro scelte (dare o prendere).
La prima scelta consiste nel fornire una funzione di "sicurezza" per memcpy
. Questo è quello che richiedo nel codice sotto la mia competenza, e regolarmente controllo per questo. Richiedo inoltre che tutti i parametri siano convalidati e che tutti i parametri siano asseriti.
Le asserzioni creano un codice di auto-debug. Voglio che gli sviluppatori scrivano il codice; e non voglio che perdano tempo nel debugging. Quindi chiedo loro di scrivere il codice che esegue il debug di se stesso. ASSERT documenta anche le cose piuttosto bene, in modo da poter lesinare sulla documentazione. Nelle build di rilascio, gli ASSERT vengono rimossi dalle macro di preporcessor.
errno_t safe_memcpy(void* dest, size_t dsize, void* src, size_t ssize, size_t cnt)
{
ASSERT(dest != NULL);
ASSERT(src != NULL);
ASSERT(dsize != 0);
ASSERT(ssize != 0);
ASSERT(cnt != 0);
// What was the point of this call?
if(cnt == 0)
retrn 0;
if(dest == NULL || src == NULL)
return EINVALID;
if(dsize == 0 || ssize == 0)
return EINVALID;
ASSERT(dsize <= RSIZE_MAX);
ASSERT(ssize <= RSIZE_MAX);
ASSERT(cnt <= RSIZE_MAX);
if(dsize > RSIZE_MAX || ssize > RSIZE_MAX || cnt > RSIZE_MAX)
return EINVALID;
size_t cc = min(min(dsize, ssize), cnt);
memmove(dest, src, cc);
if(cc != cnt)
return ETRUNCATE;
return 0;
}
Se i safe_memcpy
rendimenti non-0, poi c'è stato un errore come un brutto parametro o potenziale buffer overflow.
La seconda scelta è l'uso di funzioni "più sicure" fornite dallo standard C. C ha funzioni "più sicure" tramite ISO/IEC TR 24731-1, Bounds Checking Interfaces. Su piattaforme conformi, puoi semplicemente chiamare gets_s
e sprintf_s
. Offrono un comportamento coerente (come garantire sempre una stringa terminata con NULL
) e valori di ritorno coerenti (come 0 in caso di successo o errno_t
).
errno_t err = memcpy_s(dest, dsize, src, cnt);
...
Sfortunatamente gcc e glibc non sono conformi allo standard C. Ulrich Drepper (uno dei manutentori di glibc) ha chiamato bounds controllando le interfacce "horribly inefficient BSD crap" e non sono mai stati aggiunti.
La terza scelta è quella di utilizzare interfacce "più sicuri" della piattaforma, se presente. Su Windows, sembra essere uguale a quelli di ISO/IEC TR 24731-1, Bounds Checking Interfaces. Hai anche la libreria String Safe.
Su Apple e BSD, non si dispone di una funzione "più sicura" per memcpy
. Ma hai funzioni di stringa più sicure come strlcpy
, strlcat
e amici.
Su Linux, la quarta scelta è utilizzare FORTIFY_SOURCE. FORTIFY_SOURCE utilizza varianti "più sicure" di funzioni ad alto rischio come memcpy
, strcpy
e gets
. Il compilatore utilizza le varianti più sicure quando può dedurre la dimensione del buffer di destinazione. Se la copia supera la dimensione del buffer di destinazione, il programma chiama abort()
. Se il compilatore non può dedurre la dimensione del buffer di destinazione, le varianti "più sicure" non vengono utilizzate.
Per disabilitare FORTIFY_SOURCE per il test, è necessario compilare il programma con -U_FORTIFY_SOURCE
o -D_FORTIFY_SOURCE=0
.
- 1. boost :: asio :: buffer: recupero della dimensione del buffer e prevenzione dell'overflow del buffer?
- 2. evitano con memcpy
- 3. memcpy ottimizzato
- 4. Overflow del buffer come homeowrk
- 5. Come evitare il pop-up del buffer * Comando shell asincrona * in Emacs?
- 6. Utilizzo del buffer del protocollo come oggetto dati generale?
- 7. copy_to_user vs memcpy
- 8. Qual è la dimensione massima dei buffer che memcpy/memset ecc. Può gestire?
- 9. C memcpy al contrario
- 10. Buffer del protocollo C++, invio di array intero
- 11. evitare di tenere Vim buffer aperti in background chiuso
- 12. memcpy asincrono in linux?
- 13. Memcpy() nella programmazione sicura?
- 14. strcpy vs. memcpy
- 15. Quale utilizzare: memmove() o memcpy() - quando i buffer non si sovrappongono?
- 16. Buffer bicicletta in Emacs: evitare graffi e messaggi tampone
- 17. Ottenere SIGILL quando si cerca di eseguire del buffer overflow
- 18. Come vengono scelte le dimensioni del buffer?
- 19. come memcpy l'array bidimensionale in C?
- 20. Come funziona l'implementazione interna di memcpy?
- 21. Proprietà del buffer in Netty 4: Come viene gestito il ciclo di vita del buffer?
- 22. Delphi CopyMemory vs C++ memcpy
- 23. Spiegazione del buffer/cache dapper
- 24. È possibile l'overflow del buffer PHP?
- 25. Differenza tra strncpy e memcpy?
- 26. Dimensione del buffer ottimale per il file buffer?
- 27. Limite del buffer iOS opensl.
- 28. memcpy(), quale dovrebbe essere il valore del parametro size?
- 29. Dimensione ottimale del buffer Android
- 30. Sprintf (buffer, "% s [...]", buffer, [...]) è sicuro?
Rileva? Conosci la dimensione del buffer di destinazione? Quindi scrivere il codice come questa memcpy (src, dst, sizeof (dst)) – BSen
Confrontare le dimensioni del buffer di origine e del buffer di destinazione e vedere quale è più grande? – SingerOfTheFall
@BSen che '' sizeof'' darà solo la dimensione di un puntatore. – juanchopanza