Π§ΠΈΡ‚Π°ΠΉΡ‚Π΅ ΠΊΠ½ΠΈΠ³ΠΈ ΠΎΠ½Π»Π°ΠΉΠ½ Π½Π° Bookidrom.ru! БСсплатныС ΠΊΠ½ΠΈΠ³ΠΈ Π² ΠΎΠ΄Π½ΠΎΠΌ ΠΊΠ»ΠΈΠΊΠ΅

Π§ΠΈΡ‚Π°Ρ‚ΡŒ ΠΎΠ½Π»Π°ΠΉΠ½ Β«Π Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ Π² срСдС Linux. Π’Ρ‚ΠΎΡ€ΠΎΠ΅ ΠΈΠ·Π΄Π°Π½ΠΈΠ΅Β». Π‘Ρ‚Ρ€Π°Π½ΠΈΡ†Π° 15

Автор Майкл ДТонсон

15:  strcpy(dyn, "12345");

16:  printf ("1: %s\n", dyn);

17:  free(dyn);

18:

19:  /* Π’Π΅ΠΏΠ΅Ρ€ΡŒ ΠΏΠ΅Ρ€Π΅Π·Π°ΠΏΠΈΡΠ°Ρ‚ΡŒ Π±ΡƒΡ„Π΅Ρ€ изрядно */

20:  dyn = malloc(5);

21:  strcpy(dyn, "12345678");

22:  printf("2: %s\n", dyn);

23:

24:  /* ΠŸΡ€ΠΎΠΉΡ‚ΠΈ ΠΏΠ΅Ρ€Π΅Π΄ Π½Π°Ρ‡Π°Π»ΠΎΠΌ Π²Ρ‹Π΄Π΅Π»Π΅Π½Π½ΠΎΠ³ΠΎ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ malloc локального Π±ΡƒΡ„Π΅Ρ€Π° */

25:  * (dyn-1) ='\0';

26:  printf ("3: %s\n", dyn);

27:  /* ΠΎΠ±Ρ€Π°Ρ‚ΠΈΡ‚Π΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅, Ρ‡Ρ‚ΠΎ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ Π½Π΅ освобоТдСн! */

28:

29:  /* Π’Π΅ΠΏΠ΅Ρ€ΡŒ Π΄Π²ΠΈΠ½ΡƒΡ‚ΡŒΡΡ послС ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ local */

30:  strcpy(local, "12345");

31:  printf ("4: %s\n", local);

32:  local[-1] = '\0';

33:  printf("5: %s\n", local);

34:

35:  /* НаконСц, Π°Ρ‚Π°ΠΊΠΎΠ²Π°Ρ‚ΡŒ пространство Π΄Π°Π½Π½Ρ‹Ρ… global */

36:  strcpy(global, "12345");

37:  printf ("6: %s\n", global);

38:

39:  /* И Π·Π°ΠΏΠΈΡΠ°Ρ‚ΡŒ ΠΏΠΎΠ²Π΅Ρ€Ρ… пространства ΠΏΠ΅Ρ€Π΅Π΄ Π±ΡƒΡ„Π΅Ρ€ΠΎΠΌ global */

40:  global[-1] = '\0';

41:  printf("7: %s\n", 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

7.2. БрСдства ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ памяти, входящиС Π² состав glibc

Π‘ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° GNU Π‘ (glibc) ΠΏΡ€Π΅Π΄Π»Π°Π³Π°Π΅Ρ‚ Ρ‚Ρ€ΠΈ простых срСдства ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ памяти. ΠŸΠ΅Ρ€Π²Ρ‹Π΅ Π΄Π²Π° β€” mcheck() ΠΈ MALLOC_CHECK_ β€” Π²Ρ‹Π·Ρ‹Π²Π°ΡŽΡ‚ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΡƒ Π½Π° Π½Π΅ΠΏΡ€ΠΎΡ‚ΠΈΠ²ΠΎΡ€Π΅Ρ‡ΠΈΠ²ΠΎΡΡ‚ΡŒ структуры Π΄Π°Π½Π½Ρ‹Ρ… ΠΊΡƒΡ‡ΠΈ, Π° Ρ‚Ρ€Π΅Ρ‚ΡŒΠ΅ срСдство β€” mtrace() β€” Π²Ρ‹Π΄Π°Π΅Ρ‚ трассировку распрСдСлСния ΠΈ освобоТдСния памяти для дальнСйшСй ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ.

7.2.1. Поиск ΠΏΠΎΠ²Ρ€Π΅ΠΆΠ΄Π΅Π½ΠΈΠΉ ΠΊΡƒΡ‡ΠΈ

Когда ΠΏΠ°ΠΌΡΡ‚ΡŒ распрСдСляСтся Π² ΠΊΡƒΡ‡Π΅, функциям управлСния ΠΏΠ°ΠΌΡΡ‚ΡŒΡŽ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ мСсто для хранСния ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΠΈ ΠΎ распрСдСлСниях. Π’Π°ΠΊΠΈΠΌ мСстом являСтся сама ΠΊΡƒΡ‡Π°; это Π·Π½Π°Ρ‡ΠΈΡ‚, Ρ‡Ρ‚ΠΎ ΠΊΡƒΡ‡Π° состоит ΠΈΠ· Ρ‡Π΅Ρ€Π΅Π΄ΡƒΡŽΡ‰ΠΈΡ…ΡΡ областСй памяти, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ΡΡ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ°ΠΌΠΈ ΠΈ самим функциями управлСния ΠΏΠ°ΠΌΡΡ‚ΡŒΡŽ. Π­Ρ‚ΠΎ ΠΎΠ·Π½Π°Ρ‡Π°Π΅Ρ‚, Ρ‡Ρ‚ΠΎ пСрСполнСния ΠΈΠ»ΠΈ Π½Π΅Π΄ΠΎΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ Π±ΡƒΡ„Π΅Ρ€Π° ΠΌΠΎΠΆΠ΅Ρ‚ фактичСски ΠΏΠΎΠ²Ρ€Π΅Π΄ΠΈΡ‚ΡŒ структуру Π΄Π°Π½Π½Ρ‹Ρ…, ΠΊΠΎΡ‚ΠΎΡ€ΡƒΡŽ ΠΎΡ‚ΡΠ»Π΅ΠΆΠΈΠ²Π°ΡŽΡ‚ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ управлСния ΠΏΠ°ΠΌΡΡ‚ΡŒΡŽ. Π’ Ρ‚Π°ΠΊΠΎΠΉ ситуации Π΅ΡΡ‚ΡŒ ΠΌΠ½ΠΎΠ³ΠΎ шансов, Ρ‡Ρ‚ΠΎ сами Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ управлСния ΠΏΠ°ΠΌΡΡ‚ΡŒΡŽ, Π² ΠΊΠΎΠ½Ρ†Π΅ ΠΊΠΎΠ½Ρ†ΠΎΠ², ΠΏΡ€ΠΈΠ²Π΅Π΄ΡƒΡ‚ ΠΊ сбою ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹.

Если Π²Ρ‹ установили ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΡƒΡŽ окруТСния MALLOC_CHECK_, выбираСтся Π΄Ρ€ΡƒΠ³ΠΎΠΉ, нСсколько Π±ΠΎΠ»Π΅Π΅ ΠΌΠ΅Π΄Π»Π΅Π½Π½Ρ‹ΠΉ Π½Π°Π±ΠΎΡ€ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ управлСния ΠΏΠ°ΠΌΡΡ‚ΡŒΡŽ. Π­Ρ‚ΠΎΡ‚ Π½Π°Π±ΠΎΡ€ Π±ΠΎΠ»Π΅Π΅ устойчив ΠΊ ошибкам ΠΈ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΎΠ±Π½Π°Ρ€ΡƒΠΆΠΈΠ²Π°Ρ‚ΡŒ ситуации, ΠΊΠΎΠ³Π΄Π° free() вызываСтся Π±ΠΎΠ»Π΅Π΅ ΠΎΠ΄Π½ΠΎΠ³ΠΎ Ρ€Π°Π·Π° для ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΈ Ρ‚ΠΎΠ³ΠΎ ΠΆΠ΅ указатСля, Π° Ρ‚Π°ΠΊΠΆΠ΅ ΠΊΠΎΠ³Π΄Π° происходят ΠΎΠ΄Π½ΠΎΠ±Π°ΠΉΡ‚Π½Ρ‹Π΅ пСрСполнСния Π±ΡƒΡ„Π΅Ρ€Π°. Если MALLOC_CHECK_ установлСна Π² 0, Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ управлСния ΠΏΠ°ΠΌΡΡ‚ΡŒΡŽ просто Π±ΠΎΠ»Π΅Π΅ устойчивы ΠΊ ошибкам, Π½ΠΎ Π½Π΅ Π²Ρ‹Π΄Π°ΡŽΡ‚ Π½ΠΈΠΊΠ°ΠΊΠΈΡ… ΠΏΡ€Π΅Π΄ΡƒΠΏΡ€Π΅ΠΆΠ΄Π΅Π½ΠΈΠΉ. Если MALLOC_CHECK_ установлСна Π² 1, Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ управлСния ΠΏΠ°ΠΌΡΡ‚ΡŒΡŽ выводят прСдупрСТдСния ΠΎ стандартных ΠΎΡˆΠΈΠ±ΠΊΠ°Ρ… ΠΏΡ€ΠΈ Π·Π°ΠΌΠ΅Ρ‡Π΅Π½Π½ΠΎΠΉ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠ΅. Если MALLOC_CHECK_ установлСна Π² 2, Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ управлСния ΠΏΠ°ΠΌΡΡ‚ΡŒΡŽ Π²Ρ‹Π·Ρ‹Π²Π°ΡŽΡ‚ abort(), ΠΊΠΎΠ³Π΄Π° Π·Π°ΠΌΠ΅Ρ‡Π°ΡŽΡ‚ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡ‹.

Установка MALLOC_CHECK_ Π² 0 ΠΌΠΎΠΆΠ΅Ρ‚ ΠΎΠΊΠ°Π·Π°Ρ‚ΡŒΡΡ ΠΏΠΎΠ»Π΅Π·Π½ΠΎΠΉ, Ссли Π²Π°ΠΌ ΠΌΠ΅ΡˆΠ°Π΅Ρ‚ Π½Π°ΠΉΡ‚ΠΈ ΠΎΡˆΠΈΠ±ΠΊΡƒ Π² памяти другая ошибка, ΠΊΠΎΡ‚ΠΎΡ€ΡƒΡŽ Π² этот ΠΌΠΎΠΌΠ΅Π½Ρ‚ ΠΈΡΠΏΡ€Π°Π²ΠΈΡ‚ΡŒ Π½Π΅Ρ‚ возмоТности; эта установка позволяСт Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ с Π΄Ρ€ΡƒΠ³ΠΈΠΌΠΈ срСдствами отслСТивания ошибок памяти.

Установка MALLOC_CHECK_ Π² 1 ΠΏΠΎΠ»Π΅Π·Π½Π° Π² случаС, ΠΊΠΎΠ³Π΄Π° Π½ΠΈΠΊΠ°ΠΊΠΈΡ… ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌ Π½Π΅ Π²ΠΈΠ΄Π½ΠΎ, поэтому ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½Ρ‹Π΅ увСдомлСния ΠΌΠΎΠ³ΡƒΡ‚ ΠΏΠΎΠΌΠΎΡ‡ΡŒ.

Установка MALLOC_CHECK_ Π² 2 Π½Π°ΠΈΠ±ΠΎΠ»Π΅Π΅ ΠΏΠΎΠ»Π΅Π·Π½Π° ΠΏΡ€ΠΈ Ρ€Π°Π±ΠΎΡ‚Π΅ Π² ΠΎΡ‚Π»Π°Π΄Ρ‡ΠΈΠΊΠ΅, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ ΠΏΡ€ΠΈ Π²ΠΎΠ·Π½ΠΈΠΊΠ½ΠΎΠ²Π΅Π½ΠΈΠΈ ошибки ΠΎΠ½ позволяСт Π²Ρ‹ΠΏΠΎΠ»Π½ΠΈΡ‚ΡŒ ΠΎΠ±Ρ€Π°Ρ‚Π½ΡƒΡŽ трассировку Π²ΠΏΠ»ΠΎΡ‚ΡŒ Π΄ΠΎ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ управлСния ΠΏΠ°ΠΌΡΡ‚ΡŒΡŽ. Π’ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π΅ Π²Ρ‹ максимально ΠΏΡ€ΠΈΠ±Π»ΠΈΠ·ΠΈΡ‚Π΅ΡΡŒ ΠΊ мСсту возникновСния ошибки.

$ MALLOC_CHECK_=1 ./broken

malloc: using debugging hooks

malloc: ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ΡΡ ΠΎΡ‚Π»Π°Π΄ΠΎΡ‡Π½Ρ‹Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ

1: 12345

free(): invalid pointer 0x80ac008!

free(): нСдопустимый ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ 0x80ac008!

2: 12345678

3: 12345678

4: 12345

5: 12345

6: 12345

7: 12345

$ MALLOC_CHECK_=2 gdb ./broken

...

(gdb) run

Starting program: /usr/src/lad/code/broken

Запуск ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹: /usr/src/lad/code/broken

1: 12345

Program received signal SIGABRT, Aborted.

ΠŸΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° ΠΏΠΎΠ»ΡƒΡ‡ΠΈΠ»Π° сигнал SIGABRT, ΠΏΡ€Π΅Ρ€Π²Π°Π½Π°.

0x00 с 64 с 32 in _dl_sysinfo_int80() from/lib/ld-linux.so.2

(gdb) where

#0 0x00c64c32 in _dl_sysinfo_int80() from /lib/ld-linux.so.2

#1 0x00322969 in raise() from /lib/tls/libc.so.6

#2 0x00324322 in abort() from /lib/tls/libc.so.6

#3 0x0036d9af in free_check() from /lib/tls/libc.so.6

#4 0x0036afa5 in free() from /lib/tls/libc.so.6

#5 0x0804842b in broken() at broken.c:17

#6 0x08048520 in main() at broken.с:47

Π”Ρ€ΡƒΠ³ΠΎΠΉ способ Π·Π°ΡΡ‚Π°Π²ΠΈΡ‚ΡŒ glibc ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΈΡ‚ΡŒ ΠΊΡƒΡ‡Ρƒ Π½Π° Π½Π΅ΠΏΡ€ΠΎΡ‚ΠΈΠ²ΠΎΡ€Π΅Ρ‡ΠΈΠ²ΠΎΡΡ‚ΡŒ β€” Π²ΠΎΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒΡΡ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠ΅ΠΉ mcheck():

typedef void(*mcheck Callback)(enummcheck_status status);

void mcheck(mcheck Callback cb) ;

Π’ случаС Π²Ρ‹Π·ΠΎΠ²Π° Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ mcheck(), функция malloc() Ρ€Π°Π·ΠΌΠ΅Ρ‰Π°Π΅Ρ‚ извСстныС ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ Π±Π°ΠΉΡ‚ΠΎΠ² ΠΏΠ΅Ρ€Π΅Π΄ ΠΈ послС Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π΅Π½Π½ΠΎΠΉ области памяти, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΌΠΎΠΆΠ½ΠΎ Π±Ρ‹Π»ΠΎ ΠΎΠ±Π½Π°Ρ€ΡƒΠΆΠΈΡ‚ΡŒ ΠΏΠ΅Ρ€Π΅ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ ΠΈΠ»ΠΈ Π½Π΅Π΄ΠΎΠ³Ρ€ΡƒΠ·ΠΊΡƒ Π±ΡƒΡ„Π΅Ρ€Π°, free() ΠΈΡ‰Π΅Ρ‚ эти сигнатуры ΠΈ, Ссли ΠΎΠ½ΠΈ Π±Ρ‹Π»ΠΈ ΠΏΠΎΠ²Ρ€Π΅ΠΆΠ΄Π΅Π½Ρ‹, Π²Ρ‹Π·Ρ‹Π²Π°Π΅Ρ‚ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ, ΡƒΠΊΠ°Π·Π°Π½Π½ΡƒΡŽ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΎΠΌ cb. Если cb Ρ€Π°Π²Π΅Π½ NULL, выполняСтся Π²Ρ‹Ρ…ΠΎΠ΄. Запуск ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹, связанной с mcheck(), Π² gdb ΠΌΠΎΠΆΠ΅Ρ‚ ΠΏΠΎΠΊΠ°Π·Π°Ρ‚ΡŒ, ΠΊΠ°ΠΊΠΈΠ΅ ΠΈΠΌΠ΅Π½Π½ΠΎ области памяти Π±Ρ‹Π»ΠΈ ΠΏΠΎΠ²Ρ€Π΅ΠΆΠ΄Π΅Π½Ρ‹, Ссли Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΎΠ½ΠΈ явно ΠΎΡΠ²ΠΎΠ±ΠΎΠΆΠ΄Π°ΡŽΡ‚ΡΡ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ free(). Однако ΠΌΠ΅Ρ‚ΠΎΠ΄ mcheck() Π½Π΅ ΠΌΠΎΠΆΠ΅Ρ‚ Ρ‚ΠΎΡ‡Π½ΠΎ ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΡ‚ΡŒ мСсто ошибки; лишь программист ΠΌΠΎΠΆΠ΅Ρ‚ Π²Ρ‹Ρ‡ΠΈΡΠ»ΠΈΡ‚ΡŒ это, ΠΎΡΠ½ΠΎΠ²Ρ‹Π²Π°ΡΡΡŒ Π½Π° ΠΏΠΎΠ½ΠΈΠΌΠ°Π½ΠΈΠΈ Π»ΠΎΠ³ΠΈΠΊΠΈ Ρ€Π°Π±ΠΎΡ‚Ρ‹ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹.

Компоновка нашСй тСстовой ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ с mcheck Π΄Π°Π΅Ρ‚ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠ΅ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Ρ‹:

$ gcc -ggdb -о broken broken.с -lmcheck

$ ./broken

1: 12345

memory clobbered past end of allocated block

ΠΏΠ°ΠΌΡΡ‚ΡŒ Ρ€Π°Π·Ρ€ΡƒΡˆΠ΅Π½Π° послС ΠΊΠΎΠ½Ρ†Π° распрСдСлСнного Π±Π»ΠΎΠΊΠ°

ВслСдствиС Ρ‚ΠΎΠ³ΠΎ, Ρ‡Ρ‚ΠΎ mcheck всСго лишь Π²Ρ‹Π΄Π°Π΅Ρ‚ сообщСния ΠΎΠ± ΠΎΡˆΠΈΠ±ΠΊΠ°Ρ… ΠΈ Π·Π°Π²Π΅Ρ€ΡˆΠ°Π΅Ρ‚ Ρ€Π°Π±ΠΎΡ‚Ρƒ, Π½Π°ΠΉΡ‚ΠΈ ΠΎΡˆΠΈΠ±ΠΊΡƒ Π½Π΅Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ. Для Ρ‚ΠΎΡ‡Π½ΠΎΠ³ΠΎ обнаруТСния ошибки потрСбуСтся Π·Π°ΠΏΡƒΡΡ‚ΠΈΡ‚ΡŒ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡƒ Π²Π½ΡƒΡ‚Ρ€ΠΈ gdb ΠΈ Π·Π°ΡΡ‚Π°Π²ΠΈΡ‚ΡŒ mcheck Π²Ρ‹Π·Ρ‹Π²Π°Ρ‚ΡŒ abort() ΠΏΡ€ΠΈ ΠΎΠ±Π½Π°Ρ€ΡƒΠΆΠ΅Π½ΠΈΠΈ ошибки. МоТно просто Π²Ρ‹Π·Π²Π°Ρ‚ΡŒ mcheck() Π²Π½ΡƒΡ‚Ρ€ΠΈ gdb ΠΈΠ»ΠΈ ΠΏΠΎΠΌΠ΅ΡΡ‚ΠΈΡ‚ΡŒ mcheck(1) Π² ΠΏΠ΅Ρ€Π²ΠΎΠΉ строкС вашСй ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ (Π²Π΅Ρ€Π΅Π΄ Π²Ρ‹Π·ΠΎΠ²ΠΎΠΌ malloc()). (Π‘Π»Π΅Π΄ΡƒΠ΅Ρ‚ ΠΎΡ‚ΠΌΠ΅Ρ‚ΠΈΡ‚ΡŒ, Ρ‡Ρ‚ΠΎ mcheck() ΠΌΠΎΠΆΠ½ΠΎ Π²Ρ‹Π·Π²Π°Ρ‚ΡŒ Π² gdb Π±Π΅Π· нСобходимости ΠΊΠΎΠΌΠΏΠΎΠ½ΠΎΠ²ΠΊΠΈ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ с Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΎΠΉ mcheck.)

$ rm -f broken; make broken

$ gdb broken

...

(gdb) break main

Breakpoint 1 at 0x80483f4: file broken.c, line 14.

Π’ΠΎΡ‡ΠΊΠ° прСрывания 1 ΠΏΠΎ адрСсу 0x80483f4: Ρ„Π°ΠΉΠ» broken, с, строка 14.

(gdb) command 1

Type commands for when Breakpoint 1 is hit, one per line.

End with a line saying just "end".

НабСритС ΠΊΠΎΠΌΠ°Π½Π΄Ρ‹, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ выполнятся ΠΏΡ€ΠΈ достиТСнии Ρ‚ΠΎΡ‡ΠΊΠΈ прСрывания 1, ΠΏΠΎ ΠΎΠ΄Π½ΠΎΠΉ Π² строкС.

Π—Π°Π²Π΅Ρ€ΡˆΠΈΡ‚Π΅ строкой, содСрТащСй Ρ‚ΠΎΠ»ΡŒΠΊΠΎ "end".

> call mcheck(&abort)

> continue

> end (gdb) run

Starting program: /usr/src/lad/code/broken

Запуск ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹: /usr/src/lad/code/broken

Breakpoint 1, main () at broken.с: 14

47 return broken();

$1 = 0

1: 12345

Program received signal SIGABRT, Aborted.

ΠŸΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° ΠΏΠΎΠ»ΡƒΡ‡ΠΈΠ»Π° сигнал SIGABRT, ΠΏΡ€Π΅Ρ€Π²Π°Π½Π°.

0x00e12c32 in _dl_sysinfo_int80() from /lib/ld-linux.so.2

(gdb) where

#00x00el2c32 in _dl_sysinfo_int80() from /lib/ld-linux.so.2