Istnieje kilka binarnych buforów o stałym rozmiarze w programie, które są używane do przechowywania danych. I memcpy służy do kopiowania bufora z jednego do drugiego. Ponieważ bufor źródłowy może być większy niż bufor docelowy. Jak wykryć przepełnienie bufora?Jak zapobiec przepełnieniu bufora memcpy?
Odpowiedz
Musisz wiedzieć, ile danych znajduje się w buforze źródłowym i ile miejsca jest dostępne w buforze docelowym.
Nie dzwoń pod numer memcpy()
, jeśli w buforze docelowym nie ma wystarczającej ilości miejsca na dane, które chcesz skopiować z bufora źródłowego. (Musisz zdecydować, czy można obciąć dane, jeśli źródło jest większe od celu).
Jeśli nie wiesz, przepisz kod, aby wiedzieć, ile jest miejsca; w przeciwnym razie nie jest bezpieczny.
Należy pamiętać, że jeśli istnieje prawdopodobieństwo zachodzenia na siebie buforów źródłowego i docelowego, należy użyć raczej memmove()
niż memcpy()
.
W języku C++ spójrz na znak zachęty, używając w pierwszej kolejności memcpy()
; to jest operacja w stylu C zamiast C++.
Dzięki. jaki jest właściwy sposób wykonywania kopii pamięci w C++? –
@MichaelD: Przechowuj dane w 'std :: vector <>' i po prostu użyj 'vector2 = wektor1'. – MSalters
Jak mogę wstawić dane do wektora? użyć funkcji push_back, aby wstawić bajt daty według bajtu? –
Powinieneś zawsze wiedzieć i sprawdzić rozmiar buforów src i dest!
void *memcpy(void *dest, const void *src, size_t n);
n
nigdy nie powinien być większy niż src
lub dest
wielkości.
Jeśli na przykład masz:
docelowy rozmiar 4 bajty
źródło 5 bajtów rozmiar
Możesz upewnić się skopiować co najwyżej 4 bajtów do bufora docelowego:
size_t getCopySize(size_t sourceSize, size_t destSize)
{
return (destSize <= sourceSize ? destSize : sourceSize);
}
memcpy(destination, source, getCopySize(sizeof(source),sizeof(destination)));
Na podstawie Twojej aplikacji możesz również upewnić się, że pozostałe dane zostaną skopiowane później, lub możesz je pominąć, jeśli niektóre dane mogą zostać zignorowane.
Jak wykryć przepełnienie bufora?
Myślę, że masz trzy lub cztery możliwości (podać lub przyjąć).
Pierwszym wyborem jest zapewnienie "bezpiecznej" funkcji dla memcpy
. Tego właśnie wymagam w kodzie pod moim spisem i regularnie go audytuję. Wymagam również, aby wszystkie parametry zostały zatwierdzone i wszystkie parametry zostały potwierdzone.
Asercje tworzą własny kod debugowania. Chcę, żeby programiści pisali kod; i nie chcę, żeby tracili czas na debugowanie. Tak więc wymagam od nich pisania kodu, który sam się debuguje. ASSERT również dokumentuje rzeczy dość dobrze, więc mogą skąpić w dokumentacji. W kompilacjach wersji, ASSERT są usuwane przez makra przedpporalne.
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;
}
Jeśli safe_memcpy
powraca non-0, a następnie wystąpił błąd jak zły parametr lub potencjalnego przepełnienia bufora.
Drugi wybór polega na użyciu "bezpieczniejszych" funkcji zapewnianych przez standard C. C ma "bezpieczniejsze" funkcje poprzez ISO/IEC TR 24731-1, Bounds Checking Interfaces. Na zgodnych platformach można po prostu zadzwonić pod numer gets_s
i sprintf_s
. Oferują one spójne zachowanie (jak zawsze zapewnienie, że ciąg jest kończony NULL
) i spójne wartości zwracane (jak 0 w przypadku sukcesu lub errno_t
).
errno_t err = memcpy_s(dest, dsize, src, cnt);
...
Niestety, gcc i glibc nie są zgodne ze standardem C. Ulrich Drepper (jeden z opiekunów glibc) nazwał interfejsy sprawdzania granic "horribly inefficient BSD crap" i nigdy nie zostały one dodane.
Trzecim wyborem jest użycie "bezpieczniejszych" interfejsów platformy, jeśli są obecne. W systemie Windows dzieje się tak, jak w przypadku ISO/IEC TR 24731-1, Bounds Checking Interfaces. Masz również bibliotekę String Safe.
W Apple i BSD nie masz "bezpieczniejszej" funkcji dla memcpy
. Ale masz bezpieczniejsze funkcje łańcuchowe, takie jak strlcpy
, strlcat
i przyjaciele.
W systemie Linux, twoim czwartym wyborem jest użycie FORTIFY_SOURCE. FORTIFY_SOURCE używa "bezpieczniejszych" wariantów funkcji wysokiego ryzyka, takich jak memcpy
, strcpy
i gets
. Kompilator używa bezpieczniejszych wariantów, gdy może wydedukować rozmiar bufora docelowego. Jeśli kopia przekroczyłaby docelowy rozmiar bufora, program wywoła abort()
. Jeśli kompilator nie może wydedukować docelowego rozmiaru bufora, wówczas warianty "bezpieczniejsze" nie są używane.
Aby wyłączyć test FORTIFY_SOURCE, należy skompilować program pod numerem -U_FORTIFY_SOURCE
lub -D_FORTIFY_SOURCE=0
.
- 1. boost :: asio :: buffer: pobieranie rozmiaru bufora i zapobieganie przepełnieniu bufora?
- 2. Jak zapobiegać przepełnieniu bufora przez scanf w C?
- 3. Jak zapobiec przepełnieniu podczas używania zwykłych funkcji matematycznych exp() log()?
- 4. Jak mogę zapobiec przepełnieniu stosu funkcji mojego Ackermana?
- 5. W jaki sposób mogę zapobiec przepełnieniu papieru jointjs?
- 6. copy_to_user vs memcpy
- 7. strcpy vs. memcpy
- 8. Przypisanie struktury lub memcpy?
- 9. Wiadomość nagłówka, tak jak przy przepełnieniu stosu
- 10. Skracanie CSS przy przepełnieniu tekstu
- 11. Ukryta przepełniona zawartość w przepełnieniu?
- 12. Zapobieganie przepełnieniu linii w dokumentacji R?
- 13. Delphi CopyMemory vs C++ memcpy
- 14. przepełnienia bufora jak homeowrk
- 15. memcpy vs cesja w C
- 16. unikać reprezentacja pułapka z memcpy
- 17. W Emacs, jak zapobiec wyświetlaniu tego samego bufora w różnych oknach w tej samej ramce?
- 18. Jak ustawić lokalny atrybut bufora dla określonego bufora?
- 19. Jak renderować/rysować obiekt bufora do bufora ramki bez glDrawPixels
- 20. Dlaczego ostrzeżenie FxCop o przepełnieniu (CA2233) w tym kodzie C#?
- 21. Dodawanie znaku plus po "..." przy przepełnieniu tekstu
- 22. Vim: jak: źródło części bufora
- 23. Jak mogę wywołać przepełnienie bufora?
- 24. Uzyskiwanie kompilacji GCC bez wstawiania wywołania memcpy
- 25. Intencjonalny program wykorzystujący przepełnienie bufora
- 26. Zapobiegaj przepełnieniu stosu Wyjątek od awaryjnego procesu
- 27. Jak zapobiec dziedziczeniu css
- 28. Jak zapobiec odinstalowaniu aplikacji?
- 29. Jak zapobiec wysyłaniu formularza
- 30. Jak zapobiegać przepełnieniu elementu potomnego przez jego rodzica?
Wykryto? Znasz rozmiar bufora docelowego? Następnie wpisz kod podobny do tego memcpy (src, dst, sizeof (dst)). – BSen
Porównaj rozmiar bufora źródłowego i bufora docelowego i zobacz, który jest większy? – SingerOfTheFall
@Błąd, że '' sizeof'' po prostu poda rozmiar wskaźnika. – juanchopanza