Книга: Разработка приложений в среде Linux. Второе издание

7.1. Код, содержащий ошибки

7.1. Код, содержащий ошибки

 1: / * broken.с* /
 2:
 3: #include <stdlib.h>
 4: #include <stdio.h>
 5: #include <string.h>
 6:
 7: char global[5];
 8:
 9: int broken(void){
10:  char *dyn;
11:  char local[5];
12:
13:  /* Для начала немного перезаписать буфер */
14:  dyn = malloc(5);
15:  strcpy(dyn, "12345");
16:  printf ("1: %sn", dyn);
17:  free(dyn);
18:
19:  /* Теперь перезаписать буфер изрядно */
20:  dyn = malloc(5);
21:  strcpy(dyn, "12345678");
22:  printf("2: %sn", dyn);
23:
24:  /* Пройти перед началом выделенного с помощью malloc локального буфера */
25:  * (dyn-1) ='';
26:  printf ("3: %sn", dyn);
27:  /* обратите внимание, что указатель не освобожден! */
28:
29:  /* Теперь двинуться после переменной local */
30:  strcpy(local, "12345");
31:  printf ("4: %sn", local);
32:  local[-1] = '';
33:  printf("5: %sn", local);
34:
35:  /* Наконец, атаковать пространство данных global */
36:  strcpy(global, "12345");
37:  printf ("6: %sn", global);
38:
39:  /* И записать поверх пространства перед буфером global */
40:  global[-1] = '';
41:  printf("7: %sn", global);
42:
43:  return 0;
44: }
45:
46: int main (void) {
47:  return broken();
48: }

В этой главе мы рассмотрим проблемы в показанном выше сегменте кода. Этот код разрушает три типа областей памяти: память, выделенную из динамического пула памяти (кучи) с помощью malloc(), локальные переменные размещенные в стеке программы и глобальные переменные, хранящиеся в отдельной области памяти, которая была статически распределена при запуске программы[9]. Для каждого класса памяти эта тестовая программа выполняет запись за пределами зарезервированной области памяти (по одному байту) и также сохраняет байт непосредственно перед зарезервированной областью. К тому же в коде имеется утечка памяти, что позволит продемонстрировать, как с помощью различных средств отследить эти утечки.

Несмотря на то что в представленном коде кроется много проблем, в действительности, он работает нормально. Не означает ли это, что проблемы подобного рода не важны? Ни в коем случае! Переполнение буфера часто приводит к неправильному поведению программы задолго до фактического его переполнения, а утечки памяти в программах, работающих длительное время, приводят к пустой растрате ресурсов компьютера. Более того, переполнение буфера является классическим источником уязвимостей безопасности, как описано в главе 22.

Ниже показан пример выполнения программы.

$ gcc -Wall -о broken broken.с
$ ./broken
1: 12345
2: 12345678
3: 12345678
4: 12345
5: 12345
6: 12345
7: 12345

Оглавление книги


Генерация: 1.710. Запросов К БД/Cache: 3 / 1
поделиться
Вверх Вниз