Libc Heap

рд╣реАрдк рдХреА рдмреБрдирд┐рдпрд╛рджреА рдЬрд╛рдирдХрд╛рд░реА

рд╣реАрдк рд╡рд╣ рд╕реНрдерд╛рди рд╣реИ рдЬрд╣рд╛рдБ рдХрд╛рд░реНрдпрдХреНрд░рдо рдбреЗрдЯрд╛ рд╕реНрдЯреЛрд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рдХреНрд╖рдо рд╣реЛрдЧрд╛ рдЬрдм рд╡рд╣ malloc, calloc рдЬреИрд╕реА рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдХреЙрд▓ рдХрд░рдХреЗ рдбреЗрдЯрд╛ рдХрд╛ рдЕрдиреБрд░реЛрдз рдХрд░реЗрдЧрд╛ред рдЗрд╕рдХреЗ рдЕрддрд┐рд░рд┐рдХреНрдд, рдЬрдм рдпрд╣ рдореЗрдореЛрд░реА рдФрд░ рдирд╣реАрдВ рдЪрд╛рд╣рд┐рдП рд╣реЛрддреА рд╣реИ рддреЛ рдлрд╝рдВрдХреНрд╢рди free рдХреЛ рдХреЙрд▓ рдХрд░рдХреЗ рдЗрд╕реЗ рдЙрдкрд▓рдмреНрдз рдХрд░ рджрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред

рдЬреИрд╕рд╛ рдХрд┐ рджрд┐рдЦрд╛рдпрд╛ рдЧрдпрд╛ рд╣реИ, рдпрд╣ рдмрд╕ рдЙрд╕рдХреЗ рдмрд╛рдж рд╣реИ рдЬрд╣рд╛рдБ рдмрд╛рдЗрдирд░реА рдореЗрдореЛрд░реА рдореЗрдВ рд▓реЛрдб рд╣реЛ рд░рд╣рд╛ рд╣реИ (рдЪреЗрдХ рдХрд░реЗрдВ [рд╣реАрдк] рдЦрдВрдб):

рдмреБрдирд┐рдпрд╛рджреА рдЪрдВрдХ рдЖрд╡рдВрдЯрди

рдЬрдм рдХрд┐рд╕реА рдбреЗрдЯрд╛ рдХреЛ рд╣реАрдк рдореЗрдВ рд╕реНрдЯреЛрд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЕрдиреБрд░реЛрдз рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рдЙрд╕рдХреЗ рд▓рд┐рдП рд╣реАрдк рдХрд╛ рдХреБрдЫ рд╕реНрдерд╛рди рдЖрд╡рдВрдЯрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдпрд╣ рд╕реНрдерд╛рди рдПрдХ рдмрд┐рди рдХрд╛ рд╣реЛрдЧрд╛ рдФрд░ рдХреЗрд╡рд▓ рдЕрдиреБрд░реЛрдзрд┐рдд рдбреЗрдЯрд╛ + рдмрд┐рди рд╣реЗрдбрд░ рдХреЗ рд╕реНрдерд╛рди + рдиреНрдпреВрдирддрдо рдмрд┐рди рдЖрдХрд╛рд░ рдСрдлрд╕реЗрдЯ рдЪрдВрдХ рдХреЗ рд▓рд┐рдП рдЖрд░рдХреНрд╖рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред рд▓рдХреНрд╖реНрдп рдпрд╣ рд╣реИ рдХрд┐ рд╣рд░ рдЪрдВрдХ рдХреЛ рдвреВрдВрдврдирд╛ рдЬрдЯрд┐рд▓ рди рдХрд░рддреЗ рд╣реБрдП рд╕рдВрднрд╛рд╡рдирд╛ рд╣реЛ рдХрд┐ рд╕рдВрднрд╛рд╡рдирд╛ рд╣реЛ рдХрд┐ рдХреЗрд╡рд▓ рдиреНрдпреВрдирддрдо рдореЗрдореЛрд░реА рдЖрд░рдХреНрд╖рд┐рдд рдХреА рдЬрд╛рдПред рдЗрд╕рдХреЗ рд▓рд┐рдП, рдореЗрдЯрд╛рдбреЗрдЯрд╛ рдЪрдВрдХ рдЬрд╛рдирдХрд╛рд░реА рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рддрд╛рдХрд┐ рдкрддрд╛ рдЪрд▓реЗ рдХрд┐ рд╣рд░ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЧрдпрд╛/рдлреНрд░реА рдЪрдВрдХ рдХрд╣рд╛рдБ рд╣реИред

рдЖрд╡рдВрдЯрди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╡рд┐рднрд┐рдиреНрди рддрд░реАрдХреЗ рд╣реИрдВ рдЬреЛ рдореБрдЦреНрдп рд░реВрдк рд╕реЗ рдЙрдкрдпреЛрдЧ рдХрд┐рдП рдЧрдП рдмрд┐рди рдкрд░ рдирд┐рд░реНрднрд░ рдХрд░рддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдПрдХ рд╕рд╛рдорд╛рдиреНрдп рдореЗрдердбреЛрд▓реЙрдЬреА рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рд╣реИ:

  • рдкреНрд░реЛрдЧреНрд░рд╛рдо рдирд┐рд╢реНрдЪрд┐рдд рдорд╛рддреНрд░рд╛ рдореЗрдореЛрд░реА рдХрд╛ рдЕрдиреБрд░реЛрдз рдХрд░рдХреЗ рд╢реБрд░реВ рд╣реЛрддрд╛ рд╣реИред

  • рдпрджрд┐ рдЪрдВрдХреЛрдВ рдХреА рд╕реВрдЪреА рдореЗрдВ рдХреЛрдИ рдЙрдкрд▓рдмреНрдз рд╣реИ рдЬреЛ рдЕрдиреБрд░реЛрдз рдХреЛ рдкреВрд░рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкрд░реНрдпрд╛рдкреНрдд рдмрдбрд╝рд╛ рд╣реИ, рддреЛ рдЙрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛

  • рдпрд╣ рдпрд╣ рднреА рдорддрд▓рдм рд╣реЛ рд╕рдХрддрд╛ рд╣реИ рдХрд┐ рдЙрдкрд▓рдмреНрдз рдЪрдВрдХ рдХрд╛ рд╣рд┐рд╕реНрд╕рд╛ рдЗрд╕ рдЕрдиреБрд░реЛрдз рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ рдФрд░ рд╢реЗрд╖ рдЪрдВрдХреЛрдВ рд╕реВрдЪреА рдореЗрдВ рдЬреЛрдбрд╝ рджрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛

  • рдпрджрд┐ рд╕реВрдЪреА рдореЗрдВ рдХреЛрдИ рдЙрдкрд▓рдмреНрдз рдЪрдВрдХ рдирд╣реАрдВ рд╣реИ рд▓реЗрдХрд┐рди рдЖрд╡рдВрдЯрд┐рдд рд╣реАрдк рдореЗрдореЛрд░реА рдореЗрдВ рдЕрднреА рднреА рд╕реНрдерд╛рди рд╣реИ, рддреЛ рд╣реАрдк рдкреНрд░рдмрдВрдзрдХ рдПрдХ рдирдпрд╛ рдЪрдВрдХ рдмрдирд╛рддрд╛ рд╣реИ

  • рдпрджрд┐ рдирдП рдЪрдВрдХ рдХреЛ рдЖрд╡рдВрдЯрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкрд░реНрдпрд╛рдкреНрдд рд╣реАрдк рд╕реНрдерд╛рди рдирд╣реАрдВ рд╣реИ, рддреЛ рд╣реАрдк рдкреНрд░рдмрдВрдзрдХ рдХрд░реНрдирд▓ рд╕реЗ рд╣реАрдк рдХреЗ рд▓рд┐рдП рдЖрд╡рдВрдЯрд┐рдд рдореЗрдореЛрд░реА рдХреЛ рд╡рд┐рд╕реНрддрд╛рд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд╣рддрд╛ рд╣реИ рдФрд░ рдлрд┐рд░ рдЗрд╕ рдореЗрдореЛрд░реА рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдирдП рдЪрдВрдХ рдЙрддреНрдкрдиреНрди рдХрд░рддрд╛ рд╣реИ

  • рдЕрдЧрд░ рд╕рдм рдХреБрдЫ рдЕрд╕рдлрд▓ рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ malloc рдирд▓ рд▓реМрдЯрд╛рддрд╛ рд╣реИред

рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ рдпрджрд┐ рдЕрдиреБрд░реЛрдзрд┐рдд рдореЗрдореЛрд░реА рдПрдХ рдереНрд░реЗрд╢реЛрд▓реНрдб рдкрд╛рд░ рдХрд░рддреА рд╣реИ, рддреЛ mmap рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ рддрд╛рдХрд┐ рдЕрдиреБрд░реЛрдзрд┐рдд рдореЗрдореЛрд░реА рдХреЛ рдореИрдк рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХреЗред

рдПрд░реАрдирд╛

рдорд▓реНрдЯреАрдереНрд░реЗрдб рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдореЗрдВ, рд╣реАрдк рдкреНрд░рдмрдВрдзрдХ рдХреЛ рдХреНрд░реИрд╢ рдХрд░рдиреЗ рд╡рд╛рд▓реА рд░реЗрд╕ рдХрдВрдбреАрд╢рди рд╕реЗ рдмрдЪрдирд╛ рдЪрд╛рд╣рд┐рдПред рдкрд╣рд▓реЗ, рдЗрд╕реЗ рдХреЗрд╡рд▓ рдПрдХ рд╕рдордп рдореЗрдВ рдХреЗрд╡рд▓ рдПрдХ рдереНрд░реЗрдб рд╣реАрдк рддрдХ рдкрд╣реБрдВрдЪ рд╕рдХрддрд╛ рдерд╛ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдЧреНрд▓реЛрдмрд▓ рдореНрдпреВрдЯреЗрдХреНрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛, рд▓реЗрдХрд┐рди рдпрд╣ рдкреНрд░рджрд░реНрд╢рди рд╕рдорд╕реНрдпрд╛рдПрдВ рдЙрддреНрдкрдиреНрди рдХрд░рддрд╛ рдерд╛ рдХреНрдпреЛрдВрдХрд┐ рдореНрдпреВрдЯреЗрдХреНрд╕-рдЙрддреНрдкреНрд░реЗрд░рд┐рдд рдмреЙрдЯрд▓рдиреЗрдХ рдХрд╛ рдХрд╛рд░рдг рдерд╛ред

рдЗрд╕ рд╕рдорд╕реНрдпрд╛ рдХрд╛ рд╕рдорд╛рдзрд╛рди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, ptmalloc2 рд╣реАрдк рдЖрд╡рдВрдЯрдХрд░реНрддрд╛ рдиреЗ "рдПрд░реАрдирд╛" рдХрд╛ рдкрд░рд┐рдЪрдп рдХрд┐рдпрд╛, рдЬрд╣рд╛рдБ рдкреНрд░рддреНрдпреЗрдХ рдПрд░реАрдирд╛ рдПрдХ рдЕрд▓рдЧ рд╣реАрдк рдХреЗ рд░реВрдк рдореЗрдВ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ рдЬрд┐рд╕рдореЗрдВ рдЙрд╕рдХреЗ рдЕрдкрдиреЗ рдбреЗрдЯрд╛ рд╕рдВрд░рдЪрдирд╛рдПрдБ рдФрд░ рдореНрдпреВрдЯреЗрдХреНрд╕ рд╣реЛрддреЗ рд╣реИрдВ, рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ рдХрд┐ рдХрдИ рдереНрд░реЗрдб рд╣реАрдк рдСрдкрд░реЗрд╢рди рдХрд░реЗрдВ рдмрд┐рдирд╛ рдПрдХ рджреВрд╕рд░реЗ рдХреЛ рдмрд╛рдзрд┐рдд рдХрд░реЗрдВ, рдЬрдм рддрдХ рд╡реЗ рд╡рд┐рднрд┐рдиреНрди рдПрд░реАрдирд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рди рдХрд░реЗрдВред

рдбрд┐рдлрд╝реЙрд▓реНрдЯ "рдореБрдЦреНрдп" рдПрд░реАрдирд╛ рдПрдХрд▓-рдереНрд░реЗрдб рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЗ рд▓рд┐рдП рд╣реАрдк рдСрдкрд░реЗрд╢рди рдХреЛ рд╕рдВрднрд╛рд▓рддрд╛ рд╣реИред рдЬрдм рдирдП рдереНрд░реЗрдб рдЬреЛрдбрд╝реЗ рдЬрд╛рддреЗ рд╣реИрдВ, рд╣реАрдк рдкреНрд░рдмрдВрдзрдХ рдЙрдиреНрд╣реЗрдВ рдХрдо рдЯрдХрд░рд╛рд╡ рдХреЗ рд▓рд┐рдП рд╕реЗрдХреЗрдВрдбрд░реА рдПрд░реАрдирд╛ рдЕрд╕рд╛рдЗрди рдХрд░рддрд╛ рд╣реИред рдпрд╣ рдкрд╣рд▓реЗ рдкреНрд░рддреНрдпреЗрдХ рдирдП рдереНрд░реЗрдб рдХреЛ рдПрдХ рдЕрдкреНрд░рдпреБрдХреНрдд рдПрд░реАрдирд╛ рд╕реЗ рдЬреЛрдбрд╝рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░рддрд╛ рд╣реИ, рдЬрд░реВрд░рдд рдкрдбрд╝рдиреЗ рдкрд░ рдирдП рдПрд░реАрдирд╛ рдмрдирд╛рддрд╛ рд╣реИ, 32-рдмрд┐рдЯ рд╕рд┐рд╕реНрдЯрдо рдХреЗ рд▓рд┐рдП CPU рдХреЛрд░реЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ рдХрд╛ 2 рдЧреБрдгрд╛ рдФрд░ 64-рдмрд┐рдЯ рд╕рд┐рд╕реНрдЯрдо рдХреЗ рд▓рд┐рдП 8 рдЧреБрдгрд╛ рд╕реАрдорд╛ рддрдХред рдПрдХ рдмрд╛рд░ рд╕реАрдорд╛ рдкрд╣реБрдВрдЪ рдЬрд╛рддреА рд╣реИ, рдереНрд░реЗрдбреНрд╕ рдХреЛ рдПрд░реАрдирд╛ рд╕рд╛рдЭрд╛ рдХрд░рдирд╛ рдкрдбрд╝рддрд╛ рд╣реИ, рдЬреЛ рд╕рдВрдШрд░реНрд╖ рдХреА рд╕рдВрднрд╛рд╡рдирд╛ рд╣реИред

рдореБрдЦреНрдп рдПрд░реАрдирд╛ рдХреА рддрд░рд╣, рдЬреЛ brk рд╕рд┐рд╕реНрдЯрдо рдХреЙрд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд╡рд┐рд╕реНрддрд╛рд░ рд╣реЛрддрд╛ рд╣реИ, рд╕реЗрдХреЗрдВрдбрд░реА рдПрд░реАрдирд╛ mmap рдФрд░ mprotect рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ "рд╕рдмрд╣реАрдкреНрд╕" рдмрдирд╛рддреЗ рд╣реИрдВ рддрд╛рдХрд┐ рд╣реАрдк рд╡реНрдпрд╡рд╣рд╛рд░ рдХреЛ рдирдХрд▓ рдХрд░ рд╕рдХреЗрдВ, рдорд▓реНрдЯреАрдереНрд░реЗрдб рдСрдкрд░реЗрд╢рди рдХреЗ рд▓рд┐рдП рдореЗрдореЛрд░реА рдкреНрд░рдмрдВрдзрди рдореЗрдВ рд▓рдЪреАрд▓рд╛рдкрди рд╣реЛред

рд╕рдмрд╣реАрдкреНрд╕

рд╕рдмрд╣реАрдкреНрд╕ рдорд▓реНрдЯреАрдереНрд░реЗрдб рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдореЗрдВ рд╕реЗрдХреЗрдВрдбрд░реА рдПрд░реАрдирд╛ рдХреЗ рд▓рд┐рдП рдореЗрдореЛрд░реА рдЖрд░рдХреНрд╖рд┐рдд рдХрд░рддреЗ рд╣реИрдВ, рдЬрд┐рд╕рд╕реЗ рдЙрдиреНрд╣реЗрдВ рдореБрдЦреНрдп рд╣реАрдк рд╕реЗ рдЕрд▓рдЧ рд░реВрдк рд╕реЗ рдЕрдкрдиреЗ рд╣реАрдк рдХреНрд╖реЗрддреНрд░реЛрдВ рдХреЛ рдмрдврд╝рд╛рдиреЗ рдФрд░ рдкреНрд░рдмрдВрдзрд┐рдд рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рдорд┐рд▓реЗред рдпрд╣рд╛рдБ рд╕рдмрд╣реАрдкреНрд╕ рдореБрдЦреНрдп рд╣реАрдк рд╕реЗ рдХреИрд╕реЗ рднрд┐рдиреНрди рд╣реИрдВ рдФрд░ рд╡реЗ рдХреИрд╕реЗ рдХрд╛рдо рдХрд░рддреЗ рд╣реИрдВ:

  1. рдкреНрд░рд╛рд░рдВрднрд┐рдХ рд╣реАрдк vs. рд╕рдмрд╣реАрдкреНрд╕:

  • рдкреНрд░рд╛рд░рдВрднрд┐рдХ рд╣реАрдк рд╕реАрдзреЗ рдХрд╛рд░реНрдпрдХреНрд░рдо рдХреЗ рдмрд╛рдЗрдирд░реА рдХреЗ рдмрд╛рдж рд╕реНрдерд┐рдд рд╣реИ, рдФрд░ рдпрд╣ sbrk рд╕рд┐рд╕реНрдЯрдо рдХреЙрд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд╡рд┐рд╕реНрддрд╛рд░ рд╣реЛрддрд╛ рд╣реИред

  • рд╕реЗрдХреЗрдВрдбрд░реА рдПрд░реАрдирд╛ рджреНрд╡рд╛рд░рд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдП рдЬрд╛рдиреЗ рд╡рд╛рд▓реЗ рд╕рдмрд╣реАрдкреНрд╕ mmap рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдмрдирд╛рдП рдЬрд╛рддреЗ рд╣реИрдВ, рдПрдХ рд╕рд┐рд╕реНрдЯрдо рдХреЙрд▓ рдЬреЛ рдПрдХ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдореЗрдореЛрд░реА рдХреНрд╖реЗрддреНрд░ рдХреЛ рдореИрдк рдХрд░рддрд╛ рд╣реИред

  1. mmap рдХреЗ рд╕рд╛рде рдореЗрдореЛрд░реА рдЖрд░рдХреНрд╖рдг:

  • рдЬрдм рд╣реАрдк рдкреНрд░рдмрдВрдзрдХ рдПрдХ рд╕рдмрд╣реАрдк рдмрдирд╛рддрд╛ рд╣реИ, рддреЛ рд╡рд╣ mmap рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдПрдХ рдмрдбрд╝реЗ рдмреНрд▓реЙрдХ рдореЗрдореЛрд░реА рдХреЛ рдЖрд░рдХреНрд╖рд┐рдд рдХрд░рддрд╛ рд╣реИред рдпрд╣ рдЖрд░рдХреНрд╖рдг рдореЗрдореЛрд░реА рдХреЛ рддреБрд░рдВрдд рдЖрд╡рдВрдЯрд┐рдд рдирд╣реАрдВ рдХрд░рддрд╛; рдпрд╣ рдмрд╕ рдПрдХ рдХреНрд╖реЗрддреНрд░ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рддрд╛ рд╣реИ рдЬрд┐рд╕реЗ рдЕрдиреНрдп рд╕рд┐рд╕реНрдЯрдо рдкреНрд░рдХреНрд░рд┐рдпрд╛рдПрдБ рдпрд╛ рдЖрд╡рдВрдЯрди рдХрд╛ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд░ рд╕рдХрддреА рд╣реИрдВред

  • рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реВрдк рд╕реЗ, рд╕рдмрд╣реАрдкреНрд╕ рдХреЗ рд▓рд┐рдП рдЖрд░рдХреНрд╖рд┐рдд рдЖрдХрд╛рд░ 32-рдмрд┐рдЯ рдкреНрд░рдХреНрд░рд┐рдпрд╛рдУрдВ рдХреЗ рд▓рд┐рдП 1 MB рд╣реИ рдФрд░ 64-рдмрд┐рдЯ рдкреНрд░рдХреНрд░рд┐рдпрд╛рдУрдВ рдХреЗ рд▓рд┐рдП 64 MB рд╣реИред

  1. mprotect рдХреЗ рд╕рд╛рде рдзреАрд░реЗ-рдзреАрд░реЗ рд╡рд┐рд╕реНрддрд╛рд░:

  • рдЖрд░рдХреНрд╖рд┐рдд рдореЗрдореЛрд░реА рдХреНрд╖реЗрддреНрд░ рдХреЛ рдкрд╣рд▓реЗ PROT_NONE рдХреЗ рд░реВрдк рдореЗрдВ рдЪрд┐рд╣реНрдирд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЬрд┐рд╕рд╕реЗ рдХрд░реНрдирд▓ рдХреЛ рдЗрд╕ рд╕реНрдерд╛рди рдХреЗ рд▓рд┐рдП рднреМрддрд┐рдХ рдореЗрдореЛрд░реА рдХрд╛ рдЖрд╡рдВрдЯрди рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реЛрддреА рд╣реИред

  • рд╕рдмрд╣реАрдк рдХреЛ "рдмрдврд╝рд╛рдиреЗ" рдХреЗ рд▓

// From https://github.com/bminor/glibc/blob/a07e000e82cb71238259e674529c37c12dc7d423/malloc/arena.c#L837

typedef struct _heap_info
{
mstate ar_ptr; /* Arena for this heap. */
struct _heap_info *prev; /* Previous heap. */
size_t size;   /* Current size in bytes. */
size_t mprotect_size; /* Size in bytes that has been mprotected
PROT_READ|PROT_WRITE.  */
size_t pagesize; /* Page size used when allocating the arena.  */
/* Make sure the following data is properly aligned, particularly
that sizeof (heap_info) + 2 * SIZE_SZ is a multiple of
MALLOC_ALIGNMENT. */
char pad[-3 * SIZE_SZ & MALLOC_ALIGN_MASK];
} heap_info;

malloc_state

рдкреНрд░рддреНрдпреЗрдХ рд╣реАрдк (рдореБрдЦреНрдп рдПрд░реАрдирд╛ рдпрд╛ рдЕрдиреНрдп рдзрд╛рдЧреЛрдВ рдХреЗ рдПрд░реАрдирд╛) рдореЗрдВ рдПрдХ malloc_state рд╕рдВрд░рдЪрдирд╛ рд╣реЛрддреА рд╣реИред рдпрд╣ рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╣реИ рдХрд┐ рдореБрдЦреНрдп рдПрд░реАрдирд╛ malloc_state рд╕рдВрд░рдЪрдирд╛ рдПрдХ рд▓рд┐рдмреНрд╕реА рдореЗрдВ рдПрдХ рдЧреНрд▓реЛрдмрд▓ рдЪрд░ рд╣реИ (рдЗрд╕рд▓рд┐рдП рдпрд╣ рд▓рд┐рдмреНрд╕реА рдореЗрдореЛрд░реА рд╕реНрдкреЗрд╕ рдореЗрдВ рд╕реНрдерд┐рдд рд╣реИ)ред рдереНрд░реЗрдбреНрд╕ рдХреЗ рд╣реАрдк рдХреА malloc_state рд╕рдВрд░рдЪрдирд╛рдПрдВ рдХреЗрд╡рд▓ рдЕрдкрдиреЗ рдзрд╛рдЧ "рд╣реАрдк" рдореЗрдВ рд╕реНрдерд┐рдд рд╣реИрдВред

рдЗрд╕ рд╕рдВрд░рдЪрдирд╛ рд╕реЗ рдХреБрдЫ рджрд┐рд▓рдЪрд╕реНрдк рдмрд╛рддреЗрдВ рдиреЛрдЯ рдХрд░рдиреЗ рдпреЛрдЧреНрдп рд╣реИрдВ (рдиреАрдЪреЗ рджрд┐рдП рдЧрдП рд╕реА рдХреЛрдб рджреЗрдЦреЗрдВ):

  • __libc_lock_define (, mutex); рдпрд╣рд╛рдБ рдпрд╣ рд╣реИ рдХрд┐ рдЗрд╕ рд╕рдВрд░рдЪрдирд╛ рдХреЛ 1 рдзрд╛рдЧ рджреНрд╡рд╛рд░рд╛ рд╣реА рдкрд╣реБрдВрдЪрд╛ рдЬрд╛ рд╕рдХреЗ

  • рдЭрдВрдбреЗ:

#define NONCONTIGUOUS_BIT (2U)

#define contiguous(M) (((M)->flags & NONCONTIGUOUS_BIT) == 0) #define noncontiguous(M) (((M)->flags & NONCONTIGUOUS_BIT) != 0) #define set_noncontiguous(M) ((M)->flags |= NONCONTIGUOUS_BIT) #define set_contiguous(M) ((M)->flags &= ~NONCONTIGUOUS_BIT)

* `mchunkptr bins[NBINS * 2 - 2];` рдореЗрдВ **рдкреЙрдЗрдВрдЯрд░** рд╣реЛрддреЗ рд╣реИрдВ **рдЫреЛрдЯреЗ, рдмрдбрд╝реЗ рдФрд░ рдЕрдирдХреНрд░рдорд┐рдд рдмрд┐рдиреНрд╕** рдХреЗ **рдкрд╣рд▓реЗ рдФрд░ рдЖрдЦрд┐рд░реА рдЪрдВрдХреНрд╕** рдХреА рдУрд░ (рдпрд╣рд╛рдБ -2 рдЗрд╕рд▓рд┐рдП рд╣реИ рдХреНрдпреЛрдВрдХрд┐ рдЗрдВрдбреЗрдХреНрд╕ 0 рдХрд╛ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рд╣реЛрддрд╛)
* рдЗрд╕рд▓рд┐рдП, рдЗрди рдмрд┐рдиреНрд╕ рдХреЗ **рдкрд╣рд▓реЗ рдЪрдВрдХ** рдХреЗ рдкрд╛рд╕ рдЗрд╕ рд╕рдВрд░рдЪрдирд╛ рдХреЗ рд▓рд┐рдП **рдкрд┐рдЫрд▓реЗ рдХреА рдУрд░ рдкреЙрдЗрдВрдЯрд░** рд╣реЛрдЧрд╛ рдФрд░ рдЗрди рдмрд┐рдиреНрд╕ рдХреЗ **рдЖрдЦрд┐рд░реА рдЪрдВрдХ** рдХреЗ рдкрд╛рд╕ рдЗрд╕ рд╕рдВрд░рдЪрдирд╛ рдХреЗ рд▓рд┐рдП **рдЖрдЧреЗ рдХреА рдУрд░ рдкреЙрдЗрдВрдЯрд░** рд╣реЛрдЧрд╛ред рдЬрд┐рд╕рдХрд╛ рдорддрд▓рдм рд╣реИ рдХрд┐ рдЕрдЧрд░ рдЖрдк рдореБрдЦреНрдп рдПрд░реАрдирд╛ рдореЗрдВ рдЗрди рдкрддреЛрдВ рдХреЛ **рд▓реАрдХ** рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рддреЛ рдЖрдкрдХреЗ рдкрд╛рд╕ **рд▓рд┐рдмреНрд╕реА** рдореЗрдВ рд╕рдВрд░рдЪрдирд╛ рдХреЗ рд▓рд┐рдП рдПрдХ рдкреЙрдЗрдВрдЯрд░ рд╣реЛрдЧрд╛ред
* рд╕рдВрд░рдЪрдирд╛рдУрдВ `struct malloc_state *next;` рдФрд░ `struct malloc_state *next_free;` рдПрд░реАрдирд╛ рдХреА рд▓рд┐рдВрдХреНрдб рд▓рд┐рд╕реНрдЯ рд╣реИрдВ
* `рдЯреЙрдк` рдЪрдВрдХ рдЖрдЦрд┐рд░реА "рдЪрдВрдХ" рд╣реИ, рдЬреЛ рдореМрдЬреВрджрд╛ рд╣реАрдк рдмрдЪреА рд╣реБрдИ рд╕реНрдерд╛рди рд╣реИред рдЬрдм рдЯреЙрдк рдЪрдВрдХ "рдЦрд╛рд▓реА" рд╣реЛрддрд╛ рд╣реИ, рддреЛ рд╣реАрдк рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдЙрдкрдпреЛрдЧ рдХреА рдЬрд╛рддреА рд╣реИ рдФрд░ рдЗрд╕реЗ рдЕрдзрд┐рдХ рд╕реНрдерд╛рди рдХрд╛ рдЕрдиреБрд░реЛрдз рдХрд░рдирд╛ рдкрдбрд╝рддрд╛ рд╣реИред
* `рдЖрдЦрд┐рд░реА рдЕрдиреБрд╕реНрдорд╛рд░рдХ` рдЪрдВрдХ рдЙрди рдорд╛рдорд▓реЛрдВ рд╕реЗ рдЖрддрд╛ рд╣реИ рдЬрд╣рд╛рдВ рдПрдХ рд╕рдЯреАрдХ рдЖрдХрд╛рд░ рдХрд╛ рдЪрдВрдХ рдЙрдкрд▓рдмреНрдз рдирд╣реАрдВ рд╣реИ рдФрд░ рдЗрд╕рд▓рд┐рдП рдПрдХ рдмрдбрд╝рд╛ рдЪрдВрдХ рд╡рд┐рднрд╛рдЬрдХ, рдПрдХ рдкреЙрдЗрдВрдЯрд░ рд╢реЗрд╖ рд╣рд┐рд╕реНрд╕рд╛ рдпрд╣рд╛рдБ рд░рдЦрд╛ рдЬрд╛рддрд╛ рд╣реИред
```c
// From https://github.com/bminor/glibc/blob/a07e000e82cb71238259e674529c37c12dc7d423/malloc/malloc.c#L1812

struct malloc_state
{
/* Serialize access.  */
__libc_lock_define (, mutex);

/* Flags (formerly in max_fast).  */
int flags;

/* Set if the fastbin chunks contain recently inserted free blocks.  */
/* Note this is a bool but not all targets support atomics on booleans.  */
int have_fastchunks;

/* Fastbins */
mfastbinptr fastbinsY[NFASTBINS];

/* Base of the topmost chunk -- not otherwise kept in a bin */
mchunkptr top;

/* The remainder from the most recent split of a small request */
mchunkptr last_remainder;

/* Normal bins packed as described above */
mchunkptr bins[NBINS * 2 - 2];

/* Bitmap of bins */
unsigned int binmap[BINMAPSIZE];

/* Linked list */
struct malloc_state *next;

/* Linked list for free arenas.  Access to this field is serialized
by free_list_lock in arena.c.  */
struct malloc_state *next_free;

/* Number of threads attached to this arena.  0 if the arena is on
the free list.  Access to this field is serialized by
free_list_lock in arena.c.  */
INTERNAL_SIZE_T attached_threads;

/* Memory allocated from the system in this arena.  */
INTERNAL_SIZE_T system_mem;
INTERNAL_SIZE_T max_system_mem;
};

рдореИрд▓реЛрдХ_рдЪрдВрдХ

рдпрд╣ рд╕рдВрд░рдЪрдирд╛ рдПрдХ рд╡рд┐рд╢реЗрд╖ рдореЗрдореЛрд░реА рдЪрдВрдХ рдХреЛ рдкреНрд░рддрд┐рдирд┐рдзрд┐рдд рдХрд░рддреА рд╣реИред рдЖрд╡рдВрдЯрд┐рдд рдФрд░ рдЕрдкреНрд░рд╛рдкреНрдд рдЪрдВрдХ рдХреЗ рд▓рд┐рдП рд╡рд┐рднрд┐рдиреНрди рдлреАрд▓реНрдбреНрд╕ рдХрд╛ рдЕрд▓рдЧ-рдЕрд▓рдЧ рдорддрд▓рдм рд╣реЛрддрд╛ рд╣реИред

// https://github.com/bminor/glibc/blob/master/malloc/malloc.c
struct malloc_chunk {
INTERNAL_SIZE_T      mchunk_prev_size;  /* Size of previous chunk, if it is free. */
INTERNAL_SIZE_T      mchunk_size;       /* Size in bytes, including overhead. */
struct malloc_chunk* fd;                /* double links -- used only if this chunk is free. */
struct malloc_chunk* bk;
/* Only used for large blocks: pointer to next larger size.  */
struct malloc_chunk* fd_nextsize; /* double links -- used only if this chunk is free. */
struct malloc_chunk* bk_nextsize;
};

typedef struct malloc_chunk* mchunkptr;

рдЬреИрд╕рд╛ рдкрд╣рд▓реЗ рдЯрд┐рдкреНрдкрдгреА рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рдЗрди рдЪрдВрдХреНрд╕ рдореЗрдВ рдХреБрдЫ рдореЗрдЯрд╛рдбреЗрдЯрд╛ рднреА рд╣реЛрддрд╛ рд╣реИ, рдЬреЛ рдЗрд╕ рдЫрд╡рд┐ рдореЗрдВ рдмрд╣реБрдд рдЕрдЪреНрдЫреА рддрд░рд╣ рд╕реЗ рдкреНрд░рддрд┐рдирд┐рдзрд┐рдд рд╣реИ:

рдореЗрдЯрд╛рдбреЗрдЯрд╛ рдЖрдо рддреМрд░ рдкрд░ 0x08B рд╣реЛрддрд╛ рд╣реИ рдЬреЛ рд╡рд░реНрддрдорд╛рди рдЪрдВрдХ рдХрд╛ рдЖрдХрд╛рд░ рджрд░реНрд╢рд╛рддрд╛ рд╣реИ рдФрд░ рдЕрдВрддрд┐рдо 3 рдмрд┐рдЯ рдЗрд╕рдХрд╛ рджрд░реНрд╢рд╛рддреЗ рд╣реИрдВ:

  • A: рдЕрдЧрд░ 1 рд╣реИ рддреЛ рдпрд╣ рдПрдХ рд╕рдмрд╣реАрдк рд╕реЗ рдЖрдпрд╛ рд╣реИ, рдЕрдЧрд░ 0 рд╣реИ рддреЛ рдпрд╣ рдореБрдЦреНрдп рдПрд░рд┐рдирд╛ рдореЗрдВ рд╣реИ

  • M: рдЕрдЧрд░ 1 рд╣реИ, рддреЛ рдпрд╣ рдЪрдВрдХ mmap рдХреЗ рд╕рд╛рде рдЖрд╡рдВрдЯрд┐рдд рдХрд┐рдП рдЧрдП рдЕрдВрддрд░рд┐рдХреНрд╖ рдХрд╛ рд╣рд┐рд╕реНрд╕рд╛ рд╣реИ рдФрд░ рди рд╣реА рдпрд╣ рд╣реАрдк рдХрд╛ рд╣рд┐рд╕реНрд╕рд╛ рд╣реИ

  • P: рдЕрдЧрд░ 1 рд╣реИ, рддреЛ рдкрд┐рдЫрд▓рд╛ рдЪрдВрдХ рдЙрдкрдпреЛрдЧ рдореЗрдВ рд╣реИ

рдлрд┐рд░, рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдбреЗрдЯрд╛ рдХреЗ рд▓рд┐рдП рдЬрдЧрд╣, рдФрд░ рдЕрдВрдд рдореЗрдВ 0x08B рддрдХ рдкрд┐рдЫрд▓реЗ рдЪрдВрдХ рдХрд╛ рдЖрдХрд╛рд░ рджрд░реНрд╢рд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдЬрдм рдЪрдВрдХ рдЙрдкрд▓рдмреНрдз рд╣реЛрддрд╛ рд╣реИ (рдпрд╛ рдЬрдм рдпрд╣ рдЖрд╡рдВрдЯрд┐рдд рд╣реЛрддрд╛ рд╣реИ)ред

рдЗрд╕рдХреЗ рдЕрддрд┐рд░рд┐рдХреНрдд, рдЬрдм рдЙрдкрд▓рдмреНрдз рд╣реЛрддрд╛ рд╣реИ, рддреЛ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдбреЗрдЯрд╛ рдореЗрдВ рднреА рдХреБрдЫ рдбреЗрдЯрд╛ рд╢рд╛рдорд┐рд▓ рд╣реЛрддрд╛ рд╣реИ:

  • fd: рдЕрдЧрд▓реЗ рдЪрдВрдХ рдХреЗ рд▓рд┐рдП рдкреЙрдЗрдВрдЯрд░

  • bk: рдкрд┐рдЫрд▓реЗ рдЪрдВрдХ рдХреЗ рд▓рд┐рдП рдкреЙрдЗрдВрдЯрд░

  • fd_nextsize: рд╕реВрдЪреА рдореЗрдВ рдкрд╣рд▓рд╛ рдЪрдВрдХ рдЬреЛ рдЗрд╕рд╕реЗ рдЫреЛрдЯрд╛ рд╣реИ рдХреЗ рд▓рд┐рдП рдкреЙрдЗрдВрдЯрд░

  • bk_nextsize: рд╕реВрдЪреА рдореЗрдВ рдкрд╣рд▓рд╛ рдЪрдВрдХ рдЬреЛ рдЗрд╕рд╕реЗ рдмрдбрд╝рд╛ рд╣реИ рдХреЗ рд▓рд┐рдП рдкреЙрдЗрдВрдЯрд░

рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ рдЗрд╕ рддрд░рд╣ рд╕реЗ рд╕реВрдЪреА рдХреЛ рдЬреЛрдбрд╝рдиреЗ рд╕реЗ рд╣рд░ рдПрдХ рдЪрдВрдХ рдХреЛ рдкрдВрдЬреАрдХреГрдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реЛрддреА рд╣реИред

рдЪрдВрдХ рдкреЙрдЗрдВрдЯрд░

рдЬрдм malloc рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рддреЛ рдПрдХ рдкреЙрдЗрдВрдЯрд░ рд╡рд╛рдкрд╕ рд▓реМрдЯрд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдЬрд┐рд╕ рдкрд░ рд╕рд╛рдордЧреНрд░реА рд▓рд┐рдЦреА рдЬрд╛ рд╕рдХрддреА рд╣реИ (рд╣реЗрдбрд░реНрд╕ рдХреЗ рдмрд╛рдж), рд╣рд╛рд▓рд╛рдВрдХрд┐, рдЪрдВрдХ рдХреЛ рдкреНрд░рдмрдВрдзрд┐рдд рдХрд░рддреЗ рд╕рдордп, рд╣реЗрдбрд░реНрд╕ (рдореЗрдЯрд╛рдбреЗрдЯрд╛) рдХреА рд╢реБрд░реБрдЖрдд рдХреЗ рд▓рд┐рдП рдПрдХ рдкреЙрдЗрдВрдЯрд░ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред рдЗрди рдкрд░рд┐рд╡рд░реНрддрдиреЛрдВ рдХреЗ рд▓рд┐рдП рдпреЗ рдлрд╝рдВрдХреНрд╢рдиреНрд╕ рдЙрдкрдпреЛрдЧ рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВ:

// https://github.com/bminor/glibc/blob/master/malloc/malloc.c

/* Convert a chunk address to a user mem pointer without correcting the tag.  */
#define chunk2mem(p) ((void*)((char*)(p) + CHUNK_HDR_SZ))

/* Convert a user mem pointer to a chunk address and extract the right tag.  */
#define mem2chunk(mem) ((mchunkptr)tag_at (((char*)(mem) - CHUNK_HDR_SZ)))

/* The smallest possible chunk */
#define MIN_CHUNK_SIZE        (offsetof(struct malloc_chunk, fd_nextsize))

/* The smallest size we can malloc is an aligned minimal chunk */

#define MINSIZE  \
(unsigned long)(((MIN_CHUNK_SIZE+MALLOC_ALIGN_MASK) & ~MALLOC_ALIGN_MASK))

рд╕рдорд░реВрдкрдг рдФрд░ рдиреНрдпреВрдирддрдо рдЖрдХрд╛рд░

рдЪрдВрдХ рдХреЗ рдкреЙрдЗрдВрдЯрд░ рдФрд░ 0x0f рдХрд╛ рдорд╛рди 0 рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред

// From https://github.com/bminor/glibc/blob/a07e000e82cb71238259e674529c37c12dc7d423/sysdeps/generic/malloc-size.h#L61
#define MALLOC_ALIGN_MASK (MALLOC_ALIGNMENT - 1)

// https://github.com/bminor/glibc/blob/a07e000e82cb71238259e674529c37c12dc7d423/sysdeps/i386/malloc-alignment.h
#define MALLOC_ALIGNMENT 16


// https://github.com/bminor/glibc/blob/master/malloc/malloc.c
/* Check if m has acceptable alignment */
#define aligned_OK(m)  (((unsigned long)(m) & MALLOC_ALIGN_MASK) == 0)

#define misaligned_chunk(p) \
((uintptr_t)(MALLOC_ALIGNMENT == CHUNK_HDR_SZ ? (p) : chunk2mem (p)) \
& MALLOC_ALIGN_MASK)


/* pad request bytes into a usable size -- internal version */
/* Note: This must be a macro that evaluates to a compile time constant
if passed a literal constant.  */
#define request2size(req)                                         \
(((req) + SIZE_SZ + MALLOC_ALIGN_MASK < MINSIZE)  ?             \
MINSIZE :                                                      \
((req) + SIZE_SZ + MALLOC_ALIGN_MASK) & ~MALLOC_ALIGN_MASK)

/* Check if REQ overflows when padded and aligned and if the resulting
value is less than PTRDIFF_T.  Returns the requested size or
MINSIZE in case the value is less than MINSIZE, or 0 if any of the
previous checks fail.  */
static inline size_t
checked_request2size (size_t req) __nonnull (1)
{
if (__glibc_unlikely (req > PTRDIFF_MAX))
return 0;

/* When using tagged memory, we cannot share the end of the user
block with the header for the next chunk, so ensure that we
allocate blocks that are rounded up to the granule size.  Take
care not to overflow from close to MAX_SIZE_T to a small
number.  Ideally, this would be part of request2size(), but that
must be a macro that produces a compile time constant if passed
a constant literal.  */
if (__glibc_unlikely (mtag_enabled))
{
/* Ensure this is not evaluated if !mtag_enabled, see gcc PR 99551.  */
asm ("");

req = (req + (__MTAG_GRANULE_SIZE - 1)) &
~(size_t)(__MTAG_GRANULE_SIZE - 1);
}

return request2size (req);
}

рдкреНрд░рд╛рдпреЛрдЬрд┐рдд рд╕реНрдерд╛рди рдХреА рдЧрдгрдирд╛ рдХреЗ рд▓рд┐рдП рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ рдХреЗрд╡рд▓ SIZE_SZ 1 рдмрд╛рд░ рдЬреЛрдбрд╝рд╛ рдЬрд╛рддрд╛ рд╣реИ рдХреНрдпреЛрдВрдХрд┐ prev_size рдлрд╝реАрд▓реНрдб рдХрд╛ рдЙрдкрдпреЛрдЧ рдбреЗрдЯрд╛ рд╕реНрдЯреЛрд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдХреЗрд╡рд▓ рдкреНрд░рд╛рд░рдВрднрд┐рдХ рд╣реЗрдбрд░ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред

рдЪрдВрдХ рдбреЗрдЯрд╛ рдкреНрд░рд╛рдкреНрдд рдХрд░реЗрдВ рдФрд░ рдореЗрдЯрд╛рдбреЗрдЯрд╛ рдХреЛ рдмрджрд▓реЗрдВ

рдпреЗ рдлрд╝рдВрдХреНрд╢рди рдПрдХ рдЪрдВрдХ рдХреЗ рдкреЙрдЗрдВрдЯрд░ рдХреЛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдХреЗ рдХрд╛рдо рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рдореЗрдЯрд╛рдбреЗрдЯрд╛ рдХреА рдЬрд╛рдВрдЪ/рд╕реЗрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧреА рд╣реИрдВ:

  • рдЪрдВрдХ рдлрд╝реНрд▓реИрдЧ рдХреА рдЬрд╛рдВрдЪ рдХрд░реЗрдВ

// From https://github.com/bminor/glibc/blob/master/malloc/malloc.c


/* size field is or'ed with PREV_INUSE when previous adjacent chunk in use */
#define PREV_INUSE 0x1

/* extract inuse bit of previous chunk */
#define prev_inuse(p)       ((p)->mchunk_size & PREV_INUSE)


/* size field is or'ed with IS_MMAPPED if the chunk was obtained with mmap() */
#define IS_MMAPPED 0x2

/* check for mmap()'ed chunk */
#define chunk_is_mmapped(p) ((p)->mchunk_size & IS_MMAPPED)


/* size field is or'ed with NON_MAIN_ARENA if the chunk was obtained
from a non-main arena.  This is only set immediately before handing
the chunk to the user, if necessary.  */
#define NON_MAIN_ARENA 0x4

/* Check for chunk from main arena.  */
#define chunk_main_arena(p) (((p)->mchunk_size & NON_MAIN_ARENA) == 0)

/* Mark a chunk as not being on the main arena.  */
#define set_non_main_arena(p) ((p)->mchunk_size |= NON_MAIN_ARENA)
  • рдЖрдХрд╛рд░ рдФрд░ рдЕрдиреНрдп рдЪрдВрдХреНрд╕ рдХреЗ рдкреЙрдЗрдВрдЯрд░

/*
Bits to mask off when extracting size

Note: IS_MMAPPED is intentionally not masked off from size field in
macros for which mmapped chunks should never be seen. This should
cause helpful core dumps to occur if it is tried by accident by
people extending or adapting this malloc.
*/
#define SIZE_BITS (PREV_INUSE | IS_MMAPPED | NON_MAIN_ARENA)

/* Get size, ignoring use bits */
#define chunksize(p) (chunksize_nomask (p) & ~(SIZE_BITS))

/* Like chunksize, but do not mask SIZE_BITS.  */
#define chunksize_nomask(p)         ((p)->mchunk_size)

/* Ptr to next physical malloc_chunk. */
#define next_chunk(p) ((mchunkptr) (((char *) (p)) + chunksize (p)))

/* Size of the chunk below P.  Only valid if !prev_inuse (P).  */
#define prev_size(p) ((p)->mchunk_prev_size)

/* Set the size of the chunk below P.  Only valid if !prev_inuse (P).  */
#define set_prev_size(p, sz) ((p)->mchunk_prev_size = (sz))

/* Ptr to previous physical malloc_chunk.  Only valid if !prev_inuse (P).  */
#define prev_chunk(p) ((mchunkptr) (((char *) (p)) - prev_size (p)))

/* Treat space at ptr + offset as a chunk */
#define chunk_at_offset(p, s)  ((mchunkptr) (((char *) (p)) + (s)))
  • рдЗрдВрд╢реНрдпреЛ рдмрд┐рдЯ

/* extract p's inuse bit */
#define inuse(p)							      \
((((mchunkptr) (((char *) (p)) + chunksize (p)))->mchunk_size) & PREV_INUSE)

/* set/clear chunk as being inuse without otherwise disturbing */
#define set_inuse(p)							      \
((mchunkptr) (((char *) (p)) + chunksize (p)))->mchunk_size |= PREV_INUSE

#define clear_inuse(p)							      \
((mchunkptr) (((char *) (p)) + chunksize (p)))->mchunk_size &= ~(PREV_INUSE)


/* check/set/clear inuse bits in known places */
#define inuse_bit_at_offset(p, s)					      \
(((mchunkptr) (((char *) (p)) + (s)))->mchunk_size & PREV_INUSE)

#define set_inuse_bit_at_offset(p, s)					      \
(((mchunkptr) (((char *) (p)) + (s)))->mchunk_size |= PREV_INUSE)

#define clear_inuse_bit_at_offset(p, s)					      \
(((mchunkptr) (((char *) (p)) + (s)))->mchunk_size &= ~(PREV_INUSE))
  • рд╢реАрд░реНрд╖рдХ рдФрд░ рдлрд╝реБрдЯрд░ рд╕реЗрдЯ рдХрд░реЗрдВ (рдЬрдм рдЪрдВрдХ рд╕рдВрдЦреНрдпрд╛ рдЙрдкрдпреЛрдЧ рдореЗрдВ рд╣реИрдВ)

/* Set size at head, without disturbing its use bit */
#define set_head_size(p, s)  ((p)->mchunk_size = (((p)->mchunk_size & SIZE_BITS) | (s)))

/* Set size/use field */
#define set_head(p, s)       ((p)->mchunk_size = (s))

/* Set size at footer (only when chunk is not in use) */
#define set_foot(p, s)       (((mchunkptr) ((char *) (p) + (s)))->mchunk_prev_size = (s))
  • рдЪрдВрдХ рдХреЗ рдЕрдВрджрд░ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдЙрдкрдпреЛрдЧреА рдбреЗрдЯрд╛ рдХрд╛ рдЖрдХрд╛рд░ рдкреНрд░рд╛рдкреНрдд рдХрд░реЗрдВ

#pragma GCC poison mchunk_size
#pragma GCC poison mchunk_prev_size

/* This is the size of the real usable data in the chunk.  Not valid for
dumped heap chunks.  */
#define memsize(p)                                                    \
(__MTAG_GRANULE_SIZE > SIZE_SZ && __glibc_unlikely (mtag_enabled) ? \
chunksize (p) - CHUNK_HDR_SZ :                                    \
chunksize (p) - CHUNK_HDR_SZ + (chunk_is_mmapped (p) ? 0 : SIZE_SZ))

/* If memory tagging is enabled the layout changes to accommodate the granule
size, this is wasteful for small allocations so not done by default.
Both the chunk header and user data has to be granule aligned.  */
_Static_assert (__MTAG_GRANULE_SIZE <= CHUNK_HDR_SZ,
"memory tagging is not supported with large granule.");

static __always_inline void *
tag_new_usable (void *ptr)
{
if (__glibc_unlikely (mtag_enabled) && ptr)
{
mchunkptr cp = mem2chunk(ptr);
ptr = __libc_mtag_tag_region (__libc_mtag_new_tag (ptr), memsize (cp));
}
return ptr;
}

рдЙрджрд╛рд╣рд░рдг

рддреНрд╡рд░рд┐рдд рд╣реАрдк рдЙрджрд╛рд╣рд░рдг

рддреНрд╡рд░рд┐рдд рд╣реАрдк рдЙрджрд╛рд╣рд░рдг https://guyinatuxedo.github.io/25-heap/index.html рд╕реЗ, рд▓реЗрдХрд┐рди arm64 рдореЗрдВ:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void main(void)
{
char *ptr;
ptr = malloc(0x10);
strcpy(ptr, "panda");
}

рдЖрдЦрд┐рд░реА рдореБрдЦреНрдп рдХрд╛рд░реНрдп рдореЗрдВ рдмреНрд░реЗрдХрдкреЙрдЗрдВрдЯ рд╕реЗрдЯ рдХрд░реЗрдВ рдФрд░ рджреЗрдЦреЗрдВ рдХрд┐ рдЬрд╛рдирдХрд╛рд░реА рдХрд╣рд╛рдВ рд╕рдВрдЧреНрд░рд╣рд┐рдд рд╣реБрдИ рдереА:

рдпрд╣ рджреЗрдЦрдирд╛ рд╕рдВрднрд╡ рд╣реИ рдХрд┐ рд╕реНрдЯреНрд░рд┐рдВрдЧ рдкрд╛рдВрдбрд╛ рдХреЛ 0xaaaaaaac12a0 рдкрд░ рд╕рдВрдЧреНрд░рд╣рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ (рдЬреЛ x0 рдХреЗ рдЕрдВрджрд░ malloc рджреНрд╡рд╛рд░рд╛ рдЙрддреНрддрд░ рдХреЗ рд░реВрдк рдореЗрдВ рджрд┐рдпрд╛ рдЧрдпрд╛ рдкрддрд╛ рдерд╛)ред рдЗрд╕рд╕реЗ рдкрд╣рд▓реЗ рдХреЗ 0x10 рдмрд╛рдЗрдЯ рдЬрд╛рдВрдЪрдиреЗ рдкрд░ рдкрддрд╛ рдЪрд▓рддрд╛ рд╣реИ рдХрд┐ 0x0 рдпрд╣ рджрд┐рдЦрд╛рддрд╛ рд╣реИ рдХрд┐ рдкрд┐рдЫрд▓рд╛ рдЪрдВрдХ рдЙрдкрдпреЛрдЧ рдореЗрдВ рдирд╣реАрдВ рд╣реИ (рд▓рдВрдмрд╛рдИ 0) рдФрд░ рдЗрд╕ рдЪрдВрдХ рдХреА рд▓рдВрдмрд╛рдИ 0x21 рд╣реИред

рдЕрддрд┐рд░рд┐рдХреНрдд рдЬрдЧрд╣реЗрдВ рдЖрд░рдХреНрд╖рд┐рдд рдХреА рдЧрдИ рд╣реИрдВ (0x21-0x10=0x11) рдЬреЛрдбрд╝реЗ рдЧрдП рд╣реЗрдбрд░реНрд╕ (0x10) рд╕реЗ рдФрд░ 0x1 рдпрд╣ рдирд╣реАрдВ рджрд┐рдЦрд╛рддрд╛ рд╣реИ рдХрд┐ 0x21B рдЖрд░рдХреНрд╖рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛, рдмрд▓реНрдХрд┐ рд╡рд░реНрддрдорд╛рди рд╣реЗрдбрд░ рдХреА рд▓рдВрдмрд╛рдИ рдХреЗ рдЕрдВрддрд┐рдо 3 рдмрд┐рдЯреЛрдВ рдореЗрдВ рдХреБрдЫ рд╡рд┐рд╢реЗрд╖ рдЕрд░реНрде рд╣реИрдВред рдХреНрдпреЛрдВрдХрд┐ рд▓рдВрдмрд╛рдИ рд╣рдореЗрд╢рд╛ 16-рдмрд╛рдЗрдЯ рдПрд▓рд╛рдЗрди рдХреА рдЬрд╛рддреА рд╣реИ (64-рдмрд┐рдЯ рдорд╢реАрдиреЛрдВ рдореЗрдВ), рдЗрди рдмрд┐рдЯреНрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдХрднреА рднреА рд▓рдВрдмрд╛рдИ рд╕рдВрдЦреНрдпрд╛ рджреНрд╡рд╛рд░рд╛ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред

0x1:     Previous in Use     - Specifies that the chunk before it in memory is in use
0x2:     Is MMAPPED          - Specifies that the chunk was obtained with mmap()
0x4:     Non Main Arena      - Specifies that the chunk was obtained from outside of the main arena

рдорд▓реНрдЯреАрдереНрд░реЗрдбрд┐рдВрдЧ рдЙрджрд╛рд╣рд░рдг

рдорд▓реНрдЯреАрдереНрд░реЗрдб

```c #include #include #include #include #include

void* threadFuncMalloc(void* arg) { printf("Hello from thread 1\n"); char* addr = (char*) malloc(1000); printf("After malloc and before free in thread 1\n"); free(addr); printf("After free in thread 1\n"); }

void* threadFuncNoMalloc(void* arg) { printf("Hello from thread 2\n"); }

int main() { pthread_t t1; void* s; int ret; char* addr;

printf("Before creating thread 1\n"); getchar(); ret = pthread_create(&t1, NULL, threadFuncMalloc, NULL); getchar();

printf("Before creating thread 2\n"); ret = pthread_create(&t1, NULL, threadFuncNoMalloc, NULL);

printf("Before exit\n"); getchar();

return 0; }

</details>

рдкрд┐рдЫрд▓реЗ рдЙрджрд╛рд╣рд░рдг рдХреЛ рдбреАрдмрдЧ рдХрд░рдиреЗ рдкрд░ рджреЗрдЦрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдХрд┐ рд╢реБрд░реВ рдореЗрдВ рдХреЗрд╡рд▓ 1 рдПрд░реАрдирд╛ рд╣реИ:

<figure><img src="../../.gitbook/assets/image (1).png" alt=""><figcaption></figcaption></figure>

рдлрд┐рд░, рдкрд╣рд▓реЗ рдереНрд░реЗрдб рдХреЛ рдХреЙрд▓ рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж, рдЬреЛ malloc рдХреЛ рдХреЙрд▓ рдХрд░рддрд╛ рд╣реИ, рдПрдХ рдирдпрд╛ рдПрд░реАрдирд╛ рдмрдирд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ:

<figure><img src="../../.gitbook/assets/image (1) (1).png" alt=""><figcaption></figcaption></figure>

рдФрд░ рдЙрд╕рдХреЗ рдЕрдВрджрд░ рдХреБрдЫ рдЪрдВрдХреНрд╕ рдкрд╛рдП рдЬрд╛ рд╕рдХрддреЗ рд╣реИрдВ:

<figure><img src="../../.gitbook/assets/image (2).png" alt=""><figcaption></figcaption></figure>

## рдмрд┐рдиреНрд╕ рдФрд░ рдореЗрдореЛрд░реА рдЖрд╡рдВрдЯрди/рдлреНрд░реА

рдЬрд╛рдВрдЪреЗрдВ рдХрд┐ рдмрд┐рдиреНрд╕ рдХреНрдпрд╛ рд╣реИрдВ рдФрд░ рд╡реЗ рдХреИрд╕реЗ рд╕рдВрдЧрдард┐рдд рд╣реИрдВ рдФрд░ рдХреИрд╕реЗ рдореЗрдореЛрд░реА рдЖрд╡рдВрдЯрд┐рдд рдФрд░ рдлреНрд░реА рдХреА рдЬрд╛рддреА рд╣реИ:

<div data-gb-custom-block data-tag="content-ref" data-url='bins-and-memory-allocations.md'>

[bins-and-memory-allocations.md](bins-and-memory-allocations.md)

</div>

## рд╣реАрдк рдлрдВрдХреНрд╢рди рд╕реБрд░рдХреНрд╖рд╛ рдЬрд╛рдВрдЪ

рд╣реАрдк рдореЗрдВ рд╢рд╛рдорд┐рд▓ рдлрдВрдХреНрд╢рди рдЕрдкрдиреЗ рдХрд╛рд░реНрд░рд╡рд╛рдИ рдХрд░рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рдирд┐рд╢реНрдЪрд┐рдд рдЬрд╛рдВрдЪ рдХрд░реЗрдВрдЧреЗ рдХрд┐ рдХреНрдпрд╛ рд╣реАрдк рдХреЛ рдХреЛрд░рдкреНрдЯ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ:

<div data-gb-custom-block data-tag="content-ref" data-url='heap-memory-functions/heap-functions-security-checks.md'>

[heap-functions-security-checks.md](heap-memory-functions/heap-functions-security-checks.md)

</div>

## рд╕рдВрджрд░реНрдн

* [https://azeria-labs.com/heap-exploitation-part-1-understanding-the-glibc-heap-implementation/](https://azeria-labs.com/heap-exploitation-part-1-understanding-the-glibc-heap-implementation/)
* [https://azeria-labs.com/heap-exploitation-part-2-glibc-heap-free-bins/](https://azeria-labs.com/heap-exploitation-part-2-glibc-heap-free-bins/)

Last updated