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