рдПрдХрд▓ рдкреНрд░рд╡рд┐рд╖реНрдЯрд┐ рдмрд┐рдВрджреБ рдХреЗ рд╕рд╛рде LD_PRELOAD рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд╣реИрдВрдбрд▓рд┐рдВрдЧ рд╕рд┐рд╕реНрдЯрдо рдХреЙрд▓

LLVM рдкрд░ QInst рдХреЛ рдлрд┐рд░ рд╕реЗ рд▓рд╛рдЧреВ рдХрд░рддреЗ рд╕рдордп, рдореИрдВ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рд╕рдорд╕реНрдпрд╛ рдореЗрдВ рдЖрдпрд╛: QEMU рдПрдХ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЗ рдЕрдиреБрдХрд░рдг рдореЛрдб рдореЗрдВ рд╕реНрд╡рд╛рднрд╛рд╡рд┐рдХ рд░реВрдк рд╕реЗ рд╕рднреА "рдЕрддрд┐рдерд┐" рд╕рд┐рд╕реНрдЯрдо рдХреЙрд▓ рдХреЛ рд╕реНрд╡реАрдХрд╛рд░ рдХрд░рддрд╛ рд╣реИред рдирддреАрдЬрддрди, рдЗрдВрд╕реНрдЯреНрд░реВрдореЗрдВрдЯреЗрд╢рди рдкреНрд▓рдЧрдЗрди рдореЗрдВ рдЙрдирдХреЗ рдкреНрд░реАрдкреНрд░реЛрд╕реЗрд╕рд┐рдВрдЧ рдХреЗ рд▓рд┐рдП рдПрдХ рдПрдХрд▓ рдкреНрд░рд╡реЗрд╢ рдмрд┐рдВрджреБ рд╣реЛрддрд╛ рд╣реИ, рдЬрд╣рд╛рдВ SYS_* рд╕рдВрдЦреНрдпрд╛ рдФрд░ рддрд░реНрдХ рдорд╛рди рджреНрд╡рд╛рд░рд╛ рдирд┐рд░реНрдгрдп рдХрд┐рдП рдЬрд╛ рд╕рдХрддреЗ рд╣реИрдВред рдпрд╣ рдХрд╛рдлреА рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рд╣реИред рд╕рдорд╕реНрдпрд╛ рдпрд╣ рд╣реИ рдХрд┐ рд╕рднреА рд╕рд┐рд╕реНрдЯрдо рдХреЙрд▓ рдореБрдЦреНрдп рд░реВрдк рд╕реЗ libc рджреНрд╡рд╛рд░рд╛ рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВ рдФрд░, рдХреЛрдб рдХреЛ libc рд░реВрдк рд╕реЗ рдлрд┐рд░ рд╕реЗ рд▓рд┐рдЦрдирд╛, рд╣рдо рдЬреНрдпрд╛рджрд╛рддрд░ рдорд╛рдорд▓реЛрдВ рдореЗрдВ рдЗрд╕ рд╣рд┐рд╕реНрд╕реЗ рдХреЛ рдирд╣реАрдВ рдкреНрд░рд╛рдкреНрдд рдХрд░реЗрдВрдЧреЗред рдмреЗрд╢рдХ, рдХреЛрдИ ptrace рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддрд╛ рд╣реИ, рдЬреЛ рдХрд┐ рдЗрд╕рдХреЗ рд▓рд┐рдП рднреА рдбрд┐рдЬрд╝рд╛рдЗрди рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред рд▓реЗрдХрд┐рди рдлрд┐рд░ рдореБрдЭреЗ рдпрдХреАрди рдирд╣реАрдВ рд╣реИ рдХрд┐ рдпрд╣ рдПрдХ рдЕрд▓рдЧ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЗ рдмрд┐рдирд╛ рдХрд░рдирд╛ рд╕рдВрднрд╡ рд╣реЛрдЧрд╛, рдФрд░ QInst рд╢рдмреНрджрд╛рд░реНрде рдиреЗ рдПрдХ рддреБрдЪреНрдЫ "рддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ" рдЕрд╡рд░реЛрдзрди рдХрд╛ рдЕрд░реНрде рд▓рдЧрд╛рдпрд╛ - рдЖрдкрдХреЛ рдХрд┐рд╕реА рддрд░рд╣ рд╣реИрдВрдбрд▓рд░ рдХреЛ рдХреЙрд▓ рдЗрдВрдЬреЗрдХреНрдЯ рдХрд░рдирд╛ рд╣реЛрдЧрд╛, рдФрд░ рдпрд╣ рд╕рд╛рдорд╛рдиреНрдп LD_PRELOAD рддреБрд▓рдирд╛ рдореЗрдВ рдмрд╣реБрдд рдЕрдзрд┐рдХ рдЬрдЯрд┐рд▓ рд╣реИред рдЖрдк рдкреНрд░рддреНрдпреЗрдХ рд╕рд┐рд╕реНрдЯрдо рдХреЙрд▓ рдХреЛ рд▓рдкреЗрдЯ рд╕рдХрддреЗ рд╣реИрдВ - рд▓реЗрдХрд┐рди рдпрд╣ рдХрдо рд╕реЗ рдХрдо рдЕрд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рд╣реИ (рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рд╣рдо рдХреБрдЫ рдХреЛ рдЫреЛрдбрд╝ рд╕рдХрддреЗ рд╣реИрдВ, рдХреНрдпреЛрдВрдХрд┐ рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ рд╣рдо рд╕рд┐рд╕реНрдЯрдо рдХреЙрд▓ рдХреЛ рдЦреБрдж рдХреЛ рд░реЛрдХрддреЗ рдирд╣реАрдВ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдЙрдирдХреЗ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдЖрд╡рд░рдг)ред


рдХрдЯреМрддреА рдХреЗ рддрд╣рдд - рдПрдХ рд╕рдорд╛рдзрд╛рди рдЬреЛ рдПрд▓рдПрд▓рд╡реАрдПрдо рд╕реЗ рдмрдВрдзрд╛ рдирд╣реАрдВ рд╣реИ, рд▓реЗрдХрд┐рди x86_64 рдкрд░ рд▓рд┐рдирдХреНрд╕ рдХреЗ рд▓рд┐рдП рддреЗрдЬ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ (рд▓реЗрдХрд┐рди рдЕрдиреНрдп рдЖрд░реНрдХрд┐рдЯреЗрдХреНрдЪрд░ рдкрд░ рд▓рд┐рдирдХреНрд╕ рдХреЗ рд▓рд┐рдП рдЕрдиреБрдХреВрд▓рд┐рдд)ред


рдиреЛрдЯ: рдпрд╣ рд▓реЗрдЦ рдПрдХ рд╕рд╛рд░реНрд╡рднреМрдорд┐рдХ рддреИрдпрд╛рд░-рдирд┐рд░реНрдорд┐рдд рд╕рдорд╛рдзрд╛рди рдкреНрд░рд╕реНрддреБрдд рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ - рдпрд╣ рдХреЗрд╡рд▓ рдорд╛рдорд▓реЛрдВ рдХреА рдПрдХ рд╡рд┐рд╕реНрддреГрдд рд╕реВрдЪреА рдХреЗ рд▓рд┐рдП рдЙрдкрдпреБрдХреНрдд рд╣реИред рд▓реЗрдХрд┐рди рдЗрд╕ рд▓реЗрдЦ рдХреЛ рд╕рдореАрдХреНрд╖рд╛-рд╢реБрдХреНрд░рд╡рд╛рд░ рдорд╛рдирд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ: рджрд┐рд▓рдЪрд╕реНрдк (рдЙрдореНрдореАрдж рд╣реИ) рдирдпрд╛ (рдЕрдзрд┐рдХрд╛рдВрд╢ рдХреЗ рд▓рд┐рдП?) рд╕реВрдЪрдирд╛, рдкрд╛рд╢рд╡рд┐рдХ рдмрд▓ рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рдФрд░ рдХрд╛рдордХрд╛рдЬреА рдЙрджрд╛рд╣рд░рдгреЛрдВ рдХреА рдПрдХ рдЪреБрдЯрдХреАред рдФрд░ рд╣рдорд╛рд░реЗ рд╢реБрдХреНрд░рд╡рд╛рд░ рдХреЛ рдЗрд╕ рддрдереНрдп рд╕реЗ рднреА рдЕрд╕реНрдкрд╖реНрдЯ рди рд╣реЛрдиреЗ рджреЗрдВ рдХрд┐ рдЖрдЬ рдЧреБрд░реБрд╡рд╛рд░ рд╣реИ!


рд╢реБрд░реВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдЗрдП рдирд┐рд░реНрдгрдп рд▓реЗрдВ: рдЗрд╕ рд▓реЗрдЦ рдореЗрдВ, рд▓рдХреНрд╖реНрдп рдПрдВрдЯреА-рдбрд┐рдмрдЧрд┐рдВрдЧ рддрдВрддреНрд░ рдХреЛ рдмрд╛рдпрдкрд╛рд╕ рдирд╣реАрдВ рдХрд░рдирд╛ рд╣реИ, рдФрд░ рд╕рд╛рдорд╛рдиреНрдп рддреМрд░ рдкрд░ рдпрд╣ рдорд╛рдирд╛ рдЬрд╛рддрд╛ рд╣реИ рдХрд┐ рдкреНрд░реЛрдЧреНрд░рд╛рдо рд╕рд┐рд╕реНрдЯрдо рдХреЙрд▓ рдХреЗ рдЕрд╡рд░реЛрдзрди рдХрд╛ рд╡рд┐рд░реЛрдз рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИред рджреВрд╕рд░реА рдУрд░, рдореИрдиреНрдпреБрдЕрд▓ рд░реВрдк рд╕реЗ рд╕реНрд░реЛрдд рдХреЛрдб рдХреЛ рдлрд┐рд░ рд╕реЗ рд▓рд┐рдЦрдирд╛ рд╣реИ рддрд╛рдХрд┐ рдХрд╛рд░реНрдпрдХреНрд░рдо рд╣рдореЗрдВ рд╢реНрд░рдо рддреАрд╡реНрд░рддрд╛ рдХреЗ рд╕рдВрджрд░реНрдн рдореЗрдВ рд╡рд┐рд╢реБрджреНрдз рд░реВрдк рд╕реЗ рдПрдХ рддрдерд╛рдХрдерд┐рдд рд╕рдВрднрд╛рд╡рдирд╛ рд╣реИред рдЗрд╕рд▓рд┐рдП LD_PRELOAD ред рд╣рд╛рд▓рд╛рдБрдХрд┐, рдпрджрд┐ рдЖрдк рдЗрд╕ рддрд░рд╣ рдХреЗ рддрдВрддреНрд░ рдХреЛ рдЕрдкрдиреЗ рд╕реНрд╡рдпрдВ рдХреЗ рдХрд╛рд░реНрдпрдХреНрд░рдо рдореЗрдВ рд╕рдВрдХрд▓рд┐рдд рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рддреЛ LD_PRELOAD рдпрд╣рд╛рдБ рдмрд┐рд▓реНрдХреБрд▓ рдЖрд╡рд╢реНрдпрдХ рдирд╣реАрдВ рд╣реИред


рдЧреАрддрд╛рддреНрдордХ рд╡рд┐рд╖рдпрд╛рдВрддрд░: рд▓рд┐рдирдХреНрд╕ рдореЗрдВ рд╕рд┐рд╕реНрдЯрдо рдХреЙрд▓ рдХреИрд╕реЗ рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВ? рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рдХрдИ рддрд░реАрдХреЗ рд╣реИрдВред рдПрдХ рдмрд╛рд░ рдПрдХ рдкреНрд░рдХреНрд░рд┐рдпрд╛ (x86 рдкрд░) рдиреЗ рд╕рд┐рд╕реНрдЯрдо рдХреЙрд▓ рдирдВрдмрд░ рдХреЛ eax рдореЗрдВ рдбрд╛рд▓ рджрд┐рдпрд╛, eax рдореЗрдВ рдкрд╣рд▓рд╛ рддрд░реНрдХ рдФрд░ рдЗрд╕реА рддрд░рд╣, рдЗрд╕рдХреЗ рдмрд╛рдж рдпрд╣ int 0x80 рдЦреАрдВрдЪ рд▓рд┐рдпрд╛ред рдХреБрдЫ рдмрд┐рдВрджреБ рдкрд░, рдЙрдиреНрд╣реЛрдВрдиреЗ рдлреИрд╕рд▓рд╛ рдХрд┐рдпрд╛ рдХрд┐ рдпрд╣ рдпрд╛ рддреЛ рдмрд╣реБрдд рддреЗрдЬрд╝ рдирд╣реАрдВ рдерд╛, рдпрд╛ рдХреИрд╢ рдХреЗ рдЕрдиреБрдХреВрд▓ рдирд╣реАрдВ рдерд╛, рдпрд╛ рдХреБрдЫ рдФрд░, рдФрд░ рдЗрд╕реЗ рдлрд┐рд░ рд╕реЗ рдХрд░реЗрдВред рддреЛ рдлрд┐рд░ рд╕реЗред рдлрд┐рд▓рд╣рд╛рд▓, vDSO рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ - рдпрд╣ рдПрдХ рдИрдорд╛рдирджрд╛рд░ рд╕рд╛рдЭрд╛ рд╡рд╕реНрддреБ рд╣реИ рдЬрд┐рд╕реЗ рдкреНрд░рддреНрдпреЗрдХ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдореЗрдВ рдЕрдВрддрдГрдХреНрд╖рд┐рдкреНрдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЬрд┐рд╕реЗ рдЖрдк рдмрд╛рд░-рдмрд╛рд░ рд╕рд┐рд╕реНрдЯрдо рдХреЙрд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдлрд╝рдВрдХреНрд╢рди рдЦреАрдВрдЪ рд╕рдХрддреЗ рд╣реИрдВ рдЬрд┐рд╕рдореЗрдВ рд╕рдВрджрд░реНрдн рд╕реНрд╡рд┐рдЪрд┐рдВрдЧ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реЛрддреА рд╣реИ (рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, time )ред рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдЖрдк рдЗрд╕ рдкрд░ рд▓реЗрдЦ рдХреЛ рд╕рдорд╛рдкреНрдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдирд╣реАрдВ: рд▓рдЧрднрдЧ рдЪрд╛рд░ рдЕрд▓рдЧ-рдЕрд▓рдЧ рд╕рд┐рд╕реНрдЯрдо рдХреЙрд▓ рдХрд╛ рд╡рд░реНрдгрди рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ (рд╕рдЯреАрдХ рд╕рдВрдЦреНрдпрд╛ рд╕рдмрд╕реЗ рдЕрдзрд┐рдХ рд╕рдВрднрд╛рд╡рдирд╛ рдХрд░реНрдиреЗрд▓ рд╕рдВрд╕реНрдХрд░рдг рдкрд░ рдирд┐рд░реНрднрд░ рдХрд░рддреА рд╣реИ), рдФрд░ рд╡реИрд╢реНрд╡рд┐рдХ рдкреНрд░рд╡рд┐рд╖реНрдЯрд┐ рдмрд┐рдВрджреБ рдкрд░ рдХреБрдЫ рднреА рдирд╣реАрдВ рджреЗрдЦрд╛ рдЧрдпрд╛ рд╣реИ ...


рд╣рдо рдПрдХ рд╕рд╛рдорд╛рдиреНрдп рдмрд┐рдВрджреБ рдХреА рдЦреЛрдЬ рдЬрд╛рд░реА рд░рдЦ рд╕рдХрддреЗ рд╣реИрдВ рдЬреЛ рдЗрд╕ рдорд╢реАрди рдкрд░ рдирд┐рд░реНрджреЗрд╢ рдкреНрд░рдгрд╛рд▓реА рдХреЙрд▓ ( int 0x80 / sysenter / ...) рдХрд╛ рдЪрдпрди рдХрд░рддрд╛ рд╣реИ - рдпрд╛ рд╢рд╛рдпрдж рдпрд╣ рдмрд┐рд▓реНрдХреБрд▓ рднреА рдореМрдЬреВрдж рдирд╣реАрдВ рд╣реИ - рд╣рдореЗрдВ рдЗрд╕реЗ рдкрд╛рдардХ рдкрд░ рдЫреЛрдбрд╝ рджреЗрдВред рдЖрдЗрдП рд╣рдо seccomp рддрдВрддреНрд░ рдкрд░ рдмреЗрд╣рддрд░ рдзреНрдпрд╛рди рджреЗрдВ, рдЬреЛ рдлрд╝рд┐рд▓реНрдЯрд░рд┐рдВрдЧ рд╕рд┐рд╕реНрдЯрдо рдХреЙрд▓ рдХреЗ рд▓рд┐рдП рдПрдХ рдФрд░ рдорд╛рдирдХ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИред


Seccomp рд╕реБрд░рдХреНрд╖рд┐рдд рдХрдВрдкреНрдпреВрдЯрд┐рдВрдЧ рдХреЗ рд▓рд┐рдП рдЦрдбрд╝рд╛ рд╣реИ рдФрд░ рдЗрд╕рдХрд╛ рдЙрджреНрджреЗрд╢реНрдп рдиреЙрдЯ-рд╕реЛ-рдЯреНрд░рд╕реНрдЯ рдХреЛрдб рдХреЛ рд╕рдВрднрд╛рд▓рдирд╛ рд╣реИред man seccomp (2) рд╕реЗ рдЙрджреНрдзрд░рдг man seccomp (2) :


 Strict secure computing mode is useful for number-crunching applications that may need to execute untrusted byte code, perhaps obtained by reading from a pipe or socket. 

рдЦреИрд░, рдореЗрд▓реНрдЯрдбрд╛рдЙрди рдПрдВрдб рдХрдВрдкрдиреА рдХреЗ рдмрд╛рдж, рд▓реЛрдЧ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдХрдИ рдереНрд░реЗрдбреНрд╕ рдореЗрдВ рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдЪрд▓рд╛рдиреЗ рд╕реЗ рдбрд░рддреЗ рд╣реИрдВ - рдореБрдЭреЗ рдирд╣реАрдВ рдкрддрд╛ рдХрд┐ рдпрд╣ рдЕрд╡рд┐рд╢реНрд╡рд╕рдиреАрдп рдмрд╛рдЗрдирд░реА рдХреЛрдб рдХреЗ рд╕рд╛рде рдХреИрд╕реЗ рд╣реИред рд╣рд╛рд▓рд╛рдВрдХрд┐, рдЖрдВрд╢рд┐рдХ рд░реВрдк рд╕реЗ рднрд░реЛрд╕реЗрдордВрдж рд╡рд╛рддрд╛рд╡рд░рдг рдореЗрдВ рд╕реБрд░рдХреНрд╖рд╛ рдПрдХ рдЕрд▓рдЧ рдореБрджреНрджрд╛ рд╣реИ, рдФрд░ рдореИрдВ рдХреЗрд╡рд▓ рдпрд╣ рдХрд╣ рд╕рдХрддрд╛ рд╣реВрдВ рдХрд┐ рд╣рд╛рд▓рд╛рдВрдХрд┐ seccomp рдХрд╛рдо рдХрд░ рд╕рдХрддрд╛ рд╣реИ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рд╡реНрдпрдХреНрддрд┐рдЧрдд рдкреНрд░рд╡рд╛рд╣ рдХреЗ рд╕реНрддрд░ рдкрд░, рдореИрдВ рд╕реНрд╡рд╛рднрд╛рд╡рд┐рдХ рд░реВрдк рд╕реЗ рдЕрд╡рд┐рд╢реНрд╡рд╛рд╕рд┐рдд рдорд╢реАрди рдХреЛрдб рдХреЗ рд╕рд╛рде рдПрдХ рд╣реА рдПрдбреНрд░реЗрд╕ рд╕реНрдкреЗрд╕ рдореЗрдВ рдмреИрдардиреЗ рдХреА рд╣рд┐рдореНрдордд рдирд╣реАрдВ рдХрд░реВрдВрдЧрд╛ред рд╕рд╛рдорд╛рдиреНрдп рддреМрд░ рдкрд░, рдореИрд▓рд╡реЗрдпрд░ рдХреА рд╕реБрд░рдХреНрд╖рд┐рдд "рддреИрдпрд╛рд░реА" рднреА рдЗрд╕ рд▓реЗрдЦ рдХрд╛ рд╡рд┐рд╖рдп рдирд╣реАрдВ рд╣реИред


рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ, рдореБрдЭреЗ рдЗрдВрд╕реНрдЯреНрд░реВрдореЗрдВрдЯреЗрд╢рди рдХреЗ рджреГрд╖реНрдЯрд┐рдХреЛрдг рд╕реЗ рд╕рд┐рд╕реНрдЯрдо рдХреЙрд▓ рдХреЛ рдЗрдВрдЯрд░рд╕реЗрдкреНрдЯ рдХрд░рдиреЗ рдореЗрдВ рджрд┐рд▓рдЪрд╕реНрдкреА рд╣реИред рд╕реМрднрд╛рдЧреНрдп рд╕реЗ, SECCOMP_SET_MODE_STRICT рдореЛрдб рдХреЗ рдЕрд▓рд╛рд╡рд╛, read , write , _exit рдФрд░ sigreturn рдХреЛ рдЫреЛрдбрд╝рдХрд░ рдХреЛрдИ рднреА рдХреЙрд▓ рдХрд░рдиреЗ рдкрд░ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЛ рд╕рдорд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдордЬрдмреВрд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП SECCOMP_SET_MODE_FILTER - рдпрд╣ рдЖрдкрдХреЛ BPF рдкреНрд░реЛрдЧреНрд░рд╛рдо рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ рдЬреЛ рдХреЗрд╡рд▓ рд╕рд┐рд╕реНрдЯрдо рдХреЙрд▓ рдХреЛ рдмреНрдпрд╛рдЬ рдХреЗ рд▓рд┐рдП рдлрд╝рд┐рд▓реНрдЯрд░ рдХрд░реЗрдЧрд╛ред рдпрд╣рд╛рдВ, рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдмрд╣реБрдд рдЕрдзрд┐рдХ рд╡рд┐рдХрд▓реНрдк рд╣реИрдВ, рд▓реЗрдХрд┐рди рдореБрдЭреЗ рдЕрдм SECCOMP_RET_TRAP рдореЗрдВ рджрд┐рд▓рдЪрд╕реНрдкреА рд╣реИ: рдЬрдм рдпрд╣ рдлреИрд╕рд▓рд╛ SIGSYS , рддреЛ SIGSYS рдХреЛ рдПрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдереНрд░реЗрдб рдХреЗ рд▓рд┐рдП рднреЗрдЬрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЕрд░реНрдерд╛рдд, рдЖрдкрдХреЛ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдХреНрдпрд╛ рдЪрд╛рд╣рд┐рдП: рдЖрдк рдЕрдиреБрд░реЛрдз рдХреЛ рд╕рд┐рдВрдХреНрд░рдирд╛рдЗрдЬрд╝ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдирд┐рдпрдВрддреНрд░рдг рд╡рд╛рдкрд╕ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдЬреИрд╕реЗ рдХрд┐ рд╕рд┐рд╕реНрдЯрдо рдХреЙрд▓ рд╕рд╛рдорд╛рдиреНрдп рд░реВрдк рд╕реЗ рд╣реБрдЖ рдерд╛ред


рдЯреНрд░реЗрдирд┐рдВрдЧ


рд╣рдорд╛рд░реЗ рд╣реИрдВрдбрд▓рд░ рдХреЗ рд▓рд┐рдП, syscall-handler.c рдлрд╝рд╛рдЗрд▓ рдмрдирд╛рдПрдВ:


 #include <linux/seccomp.h> #include <linux/filter.h> #include <linux/audit.h> #include <linux/signal.h> #include <sys/ptrace.h> uint64_t handle_syscall(uint32_t num, uint32_t *drop_syscall, uint64_t arg1, uint64_t arg2, uint64_t arg3, uint64_t arg4, uint64_t arg5, uint64_t arg6); void initialize_handler(void) { } static void __attribute__((constructor))constr(void) { initialize_handler(); } 

рд╣рдо рдЙрд╕ рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рд╡рд░реНрдгрди рдХрд░рддреЗ рд╣реИрдВ рдЬреЛ рд╕рд┐рд╕реНрдЯрдо рдХреЙрд▓ рдХреЛ рдкреНрд░реЛрд╕реЗрд╕ рдХрд░рддрд╛ рд╣реИ - рдпрд╣ рдмрд╣реБрдд рд╕реНрдкрд╖реНрдЯ рд╣реИ: рдлрд╝рдВрдХреНрд╢рди рд╕рд┐рд╕реНрдЯрдо рдХреЙрд▓ рдХреА рд╕рдВрдЦреНрдпрд╛ рд▓реЗрддрд╛ рд╣реИ, (рдЕрдзрд┐рдХрддрдо) рдЗрд╕рдХреЗ рддрд░реНрдХреЛрдВ рдореЗрдВ рд╕реЗ рдЫрд╣, рдФрд░ (рд╡рд╛рдкрд╕реА) рд╕рдВрдХреЗрдд рджреЗрддреЗ рд╣реИрдВ рдХрд┐ рд╕рд┐рд╕реНрдЯрдо рдХреЙрд▓ рдХреЛ рди рдХреЗрд╡рд▓ рдзреНрдпрд╛рди рдореЗрдВ рд░рдЦрд╛ рдЧрдпрд╛ рдерд╛, рдмрд▓реНрдХрд┐ рдЕрдиреБрдХрд░рдг рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛, рдФрд░ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдкреНрд░рджрд░реНрд╢рди рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИред рдмрд╛рдХреА рднреА рд╕рд░рд▓ рд╣реИ: initialize_handler рдлрд╝рдВрдХреНрд╢рди рдЗрд╕ рд╕рднреА рдХреЗ рдкреНрд░реЗрд╖рдг рдХреЛ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд░реЗрдЧрд╛ред


рдФрд░ рдпрд╣ рд░рд╣рд╕реНрдпрдордп constr рдХреНрдпрд╛ рд╣реИ? рдпрд╣ рдХреЗрд╡рд▓ initialize_handler рдХреЙрд▓ рдХрд░рддрд╛ initialize_handler , рд▓реЗрдХрд┐рди рдЪреВрдВрдХрд┐ рдпрд╣ constructor рд╡рд┐рд╢реЗрд╖рддрд╛ рдХреЗ рд╕рд╛рде рдЪрд┐рд╣реНрдирд┐рдд рд╣реИ, рдЗрд╕рд▓рд┐рдП рдЗрд╕реЗ рдЗрд╕ рдлрд╝рдВрдХреНрд╢рди рд╡рд╛рд▓реЗ рд▓рд╛рдЗрдмреНрд░реЗрд░реА (рдпрд╛ рдореБрдЦреНрдп рдирд┐рд╖реНрдкрд╛рджрди рдпреЛрдЧреНрдп рдлрд╝рд╛рдЗрд▓) рдХреЗ рдкреНрд░рд╛рд░рдВрдн рдХреЗ рджреМрд░рд╛рди рдХрд╣рд╛ рдЬрд╛рдПрдЧрд╛ред рдпрджрд┐ рд╣рдо рдкреНрд░реЛрдЧреНрд░рд╛рдо рд╢реБрд░реВ рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж рдЕрд╡рд░реЛрдзрди рдХреЛ рд╕рдХреНрд╖рдо рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рддреЛ рд╣рдо constr рд╕реЗрдЯ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдореИрдиреНрдпреБрдЕрд▓ рд░реВрдк рд╕реЗ initialize_handler рдХреЙрд▓ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред


BPF рдкреНрд░реЛрдЧреНрд░рд╛рдо рд▓рд┐рдЦрдирд╛


рдЕрдм рдЖрдкрдХреЛ рдПрдХ рдмреАрдкреАрдПрдл SECCOMP_RET_TRAP рд▓рд┐рдЦрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдЬреЛ рдХреЗрд╡рд▓ SECCOMP_RET_TRAP рдЬрд╛рд░реА рдХрд░рдХреЗ рд╡рд╛рдВрдЫрд┐рдд рд╕рд┐рд╕реНрдЯрдо рдХреЙрд▓ рдирдВрдмрд░реЛрдВ рдкрд░ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ SECCOMP_RET_TRAP ред рдХрд╛рд░реНрдпрдХреНрд░рдо рдкреНрд░рд╛рд░реВрдк рдХреЗ рд▓рд┐рдП рдкреНрд░рд▓реЗрдЦрди, рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ, рджрд╕реНрддрд╛рд╡реЗрдЬрд╝реАрдХрд░рдг / рдиреЗрдЯрд╡рд░реНрдХрд┐рдВрдЧ / filter.txt рдореЗрдВ рдХрд░реНрдиреЗрд▓ рд╕реНрд░реЛрддреЛрдВ рдореЗрдВ рдирд┐рд╣рд┐рдд рд╣реИ , рдЬрдмрдХрд┐ seccomp рдХреЗ рд▓рд┐рдП рдЖрдкрдХреЛ рдкреБрд░рд╛рдиреЗ рд╕рдВрд╕реНрдХрд░рдг рдХреЛ рджреЗрдЦрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рди рдХрд┐ рдИрдПрдХреНрд╕рдкреАрдПрдлред Linux / seccomp.h , linux / filter.h рдлрд╛рдЗрд▓реЗрдВ рд╕реНрд╡рдпрдВ, рд╕рд╛рде рд╣реА рд╕рд╛рде linux / bpf_common.h рдлрд╛рдЗрд▓реЗрдВ рдЬрд┐рд╕рдХреЛ рдпрд╣ рд╕рдВрджрд░реНрднрд┐рдд рдХрд░рддрд╛ рд╣реИ, рднреА рдмрд╣реБрдд рдЙрдкрдпреЛрдЧреА рд╣реЛрдЧреАред рдпрджрд┐ рдЖрдк рдЗрди рд╕реНрд░реЛрддреЛрдВ рдХреЛ рдвреЗрд░ рдореЗрдВ рд░рдЦрддреЗ рд╣реИрдВ, рддреЛ man seccomp рд╕реЗ рдПрдХ рдЙрджрд╛рд╣рд░рдг man seccomp рдФрд░ рдЗрд╕реЗ man seccomp рд╣реИ, рдЖрдкрдХреЛ рдХреБрдЫ рдЗрд╕ рддрд░рд╣ рдорд┐рд▓рддрд╛ рд╣реИ:


 struct sock_filter filt[] = { BPF_STMT(BPF_LD | BPF_W | BPF_ABS, (offsetof(struct seccomp_data, args[5]))), BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K , MARKER, 0, 1), BPF_STMT(BPF_RET | BPF_K , SECCOMP_RET_ALLOW), BPF_STMT(BPF_RET | BPF_K , SECCOMP_RET_TRAP), }; 

рдЪреВрдВрдХрд┐ рдореИрдВрдиреЗ рдЗрд╕реЗ рдХреБрдЫ рд╣рдлреНрддреЗ рдкрд╣рд▓реЗ рд▓рд┐рдЦрд╛ рдерд╛, рдФрд░ рддрдм рднреА рдпрд╣ рдПрдХ рдЙрджрд╛рд╣рд░рдг рд╕реЗ рдПрдХ рдХреЛрдб рдерд╛, рдлрд┐рд░ рдкреБрд░рд╛рдиреА рдкрд░рдВрдкрд░рд╛ рдХреЗ рдЕрдиреБрд╕рд╛рд░ рдЪрд▓реЛ рдХрд╣рддреЗ рд╣реИрдВ рдХрд┐ рдпрд╣ рд╕реНрдкрд╖реНрдЯ рд╣реИ рдкрд╛рдардХ рдХреЛ рдПрдХ рдЕрднреНрдпрд╛рд╕ рдХреЗ рд░реВрдк рдореЗрдВ рдЫреЛрдбрд╝ рджреЗрдВред рд╕рд┐рджреНрдзрд╛рдВрдд рд░реВрдк рдореЗрдВ, рдСрдкреНрд╕реЛрдбреНрд╕ ( LD / JMP рдСрдлрд╝рд╕реЗрдЯ 0 рдФрд░ 1 / RET ), рд╕реНрдерд┐рддрд┐рдпрд╛рдВ ( JEQ ), рддрддреНрдХрд╛рд▓ рдСрдкрд░реЗрдВрдб ( BPF_K ) рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рдирд┐рд░реНрджреЗрд╢ рдпрд╣рд╛рдВ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рджрд┐рдЦрд╛рдИ рджреЗрддреЗ рд╣реИрдВ - рдЕрдзрд┐рдХ рд╡рд┐рд╡рд░рдг рдХреЗ рд▓рд┐рдП рдлрд╝рд┐рд▓реНрдЯрд░ рджреЗрдЦреЗрдВ ред рдФрд░ рдореИрдХреНрд░реЛрдЬрд╝ рдЖрдкрдХреЛ рдЯреАрдореЛрдВ рдХреЗ рд╢рдмреНрджреЛрдВ рдореЗрдВ рдпрд╣ рд╕рдм рдкреИрдХ рдХрд░рдиреЗ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╕реЛрдЪрдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рдирд╣реАрдВ рджреЗрддреЗ рд╣реИрдВред


рд╣рдореЗрдВ MARKER рд╕реНрдерд┐рд░рд╛рдВрдХ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдХреНрдпреЛрдВ рд╣реИ? рдпрд╣ рдПрдХ рдРрд╕реА рдмреИрд╕рд╛рдЦреА рд╣реИ рдЬреЛ рддрдм рднреА рдЖрдкрдХреЛ рд╕рд┐рд╕реНрдЯрдо рдХреЙрд▓ рдХреЛ рдЫреЛрдбрд╝рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрдЧрд╛ рдпрджрд┐ рд╣рдорд╛рд░реЗ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛-рдлрд╝рд┐рд▓реНрдЯрд░ рдРрд╕рд╛ рдирд┐рд░реНрдгрдп рд▓реЗрддреЗ рд╣реИрдВред рдореИрд▓рд╛, рдмреИрд╕рд╛рдЦреА - рд▓реЗрдХрд┐рди рдореИрдВрдиреЗ рдПрдХ рд╕рд╛рд░реНрд╡рднреМрдорд┐рдХ рд╕рдорд╛рдзрд╛рди рджрд┐рдЦрд╛рдиреЗ рдХрд╛ рд╡рд╛рджрд╛ рдирд╣реАрдВ рдХрд┐рдпрд╛ред рд╣рд╛рд▓рд╛рдВрдХрд┐, рдЬреНрдпрд╛рджрд╛рддрд░ рдорд╛рдорд▓реЛрдВ рдореЗрдВ рднреА рджрд┐рдЦрд╛рдпрд╛ рдЧрдпрд╛ рд╕рдорд╛рдзрд╛рди рдХрд╛рдлреА рд╕рдлрд▓рддрд╛рдкреВрд░реНрд╡рдХ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ, рдЬрдмрдХрд┐ рддреБрдЪреНрдЫ рд╡реНрдпрд╡рд╕реНрдерд╛ рдХреА рдЬрд╛рддреА рд╣реИред


рд╣рдордиреЗ рдЗрд╕реА MARKER рдХреЛ рд╕рд┐рд╕реНрдЯрдо рдХреЙрд▓ рдХреЗ рдЫрдареЗ рддрд░реНрдХ рдореЗрдВ рдЗрд╕ рдЙрдореНрдореАрдж рдореЗрдВ рд░рдЦрд╛ рдХрд┐ рдпрд╣ рдПрдХ "рдЕрддрд┐рд╢рдпреЛрдХреНрддрд┐рдкреВрд░реНрдг рд╡рд┐рд╡рд░рдг" рд╣реИ рдФрд░ рд╕рднреА рдЫрд╣ рддрд░реНрдХреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рд╢рд╛рдпрдж рд╣реА рдХрднреА рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рд╣рдо рдЕрдкрдиреЗ рдмреАрдкреАрдПрдл рдХрд╛рд░реНрдпрдХреНрд░рдо рдХреЗ рдкрд╣рд▓реЗ рдирд┐рд░реНрджреЗрд╢ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЗрд╕реЗ рдШрдЯрд╛рддреЗ рд╣реИрдВ: рдпрд╣рд╛рдВ рд╕реЗ рдпрд╣ рдПрдХ рд░рд╣рд╕реНрдпрдордп рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рд╣реИ - offsetof(struct seccomp_data, args[5]) - рдХрд░реНрдиреЗрд▓ seccomp_data рд▓рд┐рдП seccomp_data рд╕рдВрд░рдЪрдирд╛ рдХреЛ рдкрд╛рд╕ рдХрд░рддрд╛ seccomp_data (рджреЗрдЦреЗрдВ man seccomp )


 struct seccomp_data { int nr; /* System call number */ __u32 arch; /* AUDIT_ARCH_* value (see <linux/audit.h>) */ __u64 instruction_pointer; /* CPU instruction pointer */ __u64 args[6]; /* Up to 6 system call arguments */ }; 

... рдФрд░ рд╣рдо рдПрдХ рдСрдлрд╕реЗрдЯ рдХреЛ рдЖрд╡рд╢реНрдпрдХ рдСрдлрд╝рд╕реЗрдЯ рдореЗрдВ рд╕реЗ offsetof(struct seccomp_data, args[5]) : offsetof(struct seccomp_data, args[5]) ред рдпрд╣ рдЕрдиреБрдЪреНрдЫреЗрдж aol-nnov рджреНрд╡рд╛рд░рд╛ рдкреНрд░рд╛рдпреЛрдЬрд┐рдд рд╣реИ


рдпрд╣ рдХрд┐рд╕реА рддрд░рд╣ рдЗрд╕ рддрд░рд╣ рд╕реЗ рдкреНрд░рдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ:


 uint64_t handle_syscall(uint32_t num, uint32_t *drop_syscall, uint64_t arg1, uint64_t arg2, uint64_t arg3, uint64_t arg4, uint64_t arg5, uint64_t arg6) { return 0; } #define MARKER 0x12345678 static int in_handler; static void handle_sigsys(int num, siginfo_t *si, void *arg) { ucontext_t *ctx = arg; greg_t *gregs = ctx->uc_mcontext.gregs; uint32_t drop = 0; uint64_t res; if (!in_handler) { in_handler = 1; res = handle_syscall(gregs[REG_RAX], &drop, gregs[REG_RDI], gregs[REG_RSI], gregs[REG_RDX], gregs[REG_R10], gregs[REG_R8], gregs[REG_R9]); in_handler = 0; } if (!drop) { res = syscall(gregs[REG_RAX], gregs[REG_RDI], gregs[REG_RSI], gregs[REG_RDX], gregs[REG_R10], gregs[REG_R8], MARKER); } gregs[REG_RAX] = res; } void initialize_handler(void) { //  BPF-  struct sock_filter filt[] = { BPF_STMT(BPF_LD | BPF_W | BPF_ABS, (offsetof(struct seccomp_data, args[5]))), BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K , MARKER, 0, 1), BPF_STMT(BPF_RET | BPF_K , SECCOMP_RET_ALLOW), BPF_STMT(BPF_RET | BPF_K , SECCOMP_RET_TRAP), }; struct sock_fprog prog = { sizeof(filt) / sizeof(filt[0]), filt }; //  userspace- struct sigaction sig; memset(&sig, 0, sizeof(sig)); sig.sa_sigaction = handle_sigsys; sig.sa_flags = SA_SIGINFO; sigaction(SIGSYS, &sig, NULL); // ,   prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0); syscall(SYS_seccomp, SECCOMP_SET_MODE_FILTER, 0, &prog); } 

handle_sigsys рдПрдХ рдирдИ рд╢реИрд▓реА рдХрд╛ рд╕рд┐рдЧреНрдирд▓ рд╣реИрдВрдбрд▓рд░ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдмреЛрд▓рдиреЗ рдХреЗ рд▓рд┐рдП, sigaction рдлрд╝рдВрдХреНрд╢рди рдХреЗ рд╕рд╛рде рд╕рдВрдпреЛрдЬрди рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдЕрдкрдиреЗ рддреАрд╕рд░реЗ рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ, man sigaction рдХрд╣рддрд╛ рд╣реИ:


  ucontext This is a pointer to a ucontext_t structure, cast to void *. The structure pointed to by this field contains signal context information that was saved on the user-space stack by the kernel; for details, see sigreturn(2). Further information about the ucontext_t structure can be found in getcontext(3). Commonly, the handler function doesn't make any use of the third argument. 

рдЦреИрд░, рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдмрд╣реБрдд рд╕рд╛рдорд╛рдиреНрдп рдорд╛рдорд▓рд╛ рдирд╣реАрдВ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдПрдХ рдмрджрд▓рд╛рд╡ рдХреЗ рд▓рд┐рдП рд╣рдо рджреВрд╕рд░реЗ рддрд░реНрдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд░реЗрдВрдЧреЗ - рдмрд╣реБрдд рд╕реА рджрд┐рд▓рдЪрд╕реНрдк рдЪреАрдЬреЗрдВ рднреА рд╣реИрдВ, рд▓реЗрдХрд┐рди рд╕рд┐рд╕реНрдЯрдо рдХреЙрд▓ рдХреЗ рд▓рд┐рдП рдХреЛрдИ рддрд░реНрдХ рдирд╣реАрдВ рд╣реИрдВред рдпрд╣рд╛рдВ рдЯреИрдореНрдмреЛрд░рд┐рди рдХреЗ рд╕рд╛рде рдиреГрддреНрдп рд╢реБрд░реВ рд╣реЛрддрд╛ рд╣реИ, рдФрд░ рдЯреИрдореНрдмреЛрд░рд┐рди рдХреЛ рд╕рд╣реА рд╡рд╛рд╕реНрддреБрдХрд▓рд╛ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред рдпрд╣ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рд╕рдВрднрд╡ рд╣реИ рдХрд┐ libseccomp рдЗрди рд╡рд╛рд╕реНрддреБ рд╡рд┐рд╡рд░рдгреЛрдВ рдХреЛ рд╕рдлрд▓рддрд╛рдкреВрд░реНрд╡рдХ рд▓рд╛рдЧреВ рдХрд░рддрд╛ рд╣реИ, рдФрд░ рдмрд╕ рдПрдХ рддрд░реНрдХ рджреЗрддрд╛ рд╣реИ - рдФрд░ рдпрджрд┐ рдпрд╣ рдЕрднреА рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ, рддреЛ рд╕рдВрднрд╡рддрдГ рдмрд╛рдж рдореЗрдВ рд╣реЛрдЧрд╛ - рд▓реЗрдХрд┐рди рдЪреВрдВрдХрд┐ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдПрдХ рдкрд░рд┐рдЪрдпрд╛рддреНрдордХ рд▓реЗрдЦ рд╣реИ, рдЗрд╕рд▓рд┐рдП рд╣рдо рдорд╛рди рд▓реЗрдВрдЧреЗ рдХрд┐ рдРрд╕рд╛ рдирд┐рдореНрди рд╕реНрддрд░ рдмрдЧ рдирд╣реАрдВ рд╣реИ , рдФрд░ рдПрдХ рд╡рд┐рд╢реЗрд╖рддрд╛ ... рдЗрд╕рд▓рд┐рдП, рдореЗрд░реЗ рдорд╛рдорд▓реЗ x86_64 рдореЗрдВ, рдЖрд╡рд╢реНрдпрдХ рд╡рд╛рд╕реНрддреБрдХрд▓рд╛ рдХреЗ рд▓рд┐рдП рдЖрджрдореА syscall рд╕реЗ рджреВрд╕рд░реА рддрд╛рд▓рд┐рдХрд╛ рджреЗрдЦреЗрдВред


рдЙрд╕реА рд╣реИрдВрдбрд▓рд░ рдореЗрдВ, рд╣рдо рдПрдХ рдФрд░ рдордЬреЗрджрд╛рд░ рдХрд╛рд░реНрдп рджреЗрдЦрддреЗ рд╣реИрдВ: syscall - рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рдпрд╣ рдЙрд╕рд╕реЗ рдерд╛ рдХрд┐ рд╣рдо рд╕рд┐рд░реНрдл рдЖрджрдореА рдкрдврд╝рддреЗ рд╣реИрдВред рдЙрд╕реЗ рд╕рд┐рд░реНрдл рд╕рд┐рд╕реНрдЯрдо рдХреЙрд▓ рдирдВрдмрд░ рдФрд░ рджрд▓реАрд▓реЗрдВ рдорд┐рд▓рддреА рд╣реИрдВ, рдФрд░ рд╡рд╣ рдЙрд╕реЗ рдЕрдВрдЬрд╛рдо рджреЗрддреА рд╣реИред рдХреБрдЫ рдЖрд░реНрдХрд┐рдЯреЗрдХреНрдЪрд░ рдкрд░, 32-рдмрд┐рдЯ рд░рдЬрд┐рд╕реНрдЯрд░реЛрдВ рдореЗрдВ 64-рдмрд┐рдЯ рдорд╛рдиреЛрдВ рдХреЗ "рд╕рдВрд░реЗрдЦрдг" рдХреЗ рд╕рд╛рде рд╕рднреА рдкреНрд░рдХрд╛рд░ рдХреЗ рдореБрд╢реНрдХрд┐рд▓ рдПрдмреАрдЖрдИ рд╣реИрдВ (рд╕рдм рдХреБрдЫ рдПрдХ рд╣реА рдЖрджрдореА рдкреГрд╖реНрда рдореЗрдВ рдкрдврд╝рд╛ рдЬрд╛рддрд╛ рд╣реИ) - рдЪрд▓реЛ рдЖрд╢рд╛ рдХрд░рддреЗ рд╣реИрдВ рдХрд┐ рдпрд╣ x86_64 рдкрд░ рдкреНрд░рд╛рд╕рдВрдЧрд┐рдХ рдирд╣реАрдВ рд╣реИ, рдЕрдиреНрдпрдерд╛ рд╣рдореЗрдВ рд╕рдВрдЦреНрдпрд╛ рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдЗрд╕реЗ рдкрд╛рд░реНрд╕ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ рд░рдЬрд┐рд╕реНрдЯрд░реЛрдВ рдХреЛ рдШрдЯрд╛рдХрд░ рдХреЙрд▓ рдХрд░реЗрдВ, рдХреНрдпреЛрдВрдХрд┐ syscall() рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдЗрд╕ рддрд░реНрдХ рдХреЛ рдЕрдкрдиреЗ рдЖрдк рдореЗрдВ рдЫрд┐рдкрд╛ syscall() рд╣реИред рдпрд╣рд╛рдВ рдЗрд╕ рддрд░рд╣ рдХреЗ рдЕрдЬреАрдм рдорд╛рдорд▓реЛрдВ рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдЬрдм рдХреЙрд▓ рдирдВрдмрд░ рдХреЛ рдЧрддрд┐рд╢реАрд▓ рд░реВрдк рд╕реЗ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рддрдм рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдЬрдм рдХрд┐рд╕реА рдХрд╛рд░рдг рд╕реЗ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рд╕рд┐рд╕реНрдЯрдо рдХреЙрд▓ рдХреЗ рд▓рд┐рдП рдПрдХ libc-рдЖрд╡рд░рдг рди рд╣реЛред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдпрд╣ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рд╣реИ рдХрд┐ рдореИрдВ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдлрд╝рдВрдХреНрд╢рди рдореЗрдВ seccomp рдХреИрд╕реЗ рдХрд╣рддрд╛ seccomp :


  syscall(SYS_seccomp, SECCOMP_SET_MODE_FILTER, 0, &prog); 

рд╕реБрд░рдХреНрд╖рд╛ рдХрд╛рд░рдгреЛрдВ рд╕реЗ рдЗрд╕ рдЕрдЬреАрдм prctl рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ: man seccomp рдореЗрдВ рдПрдХ рдЙрджрд╛рд╣рд░рдг рд╣реИ рдЬрд╣рд╛рдБ, рдЗрд╕ рдЖрд╡рд╢реНрдпрдХрддрд╛ рдХреЗ рдмрд┐рдирд╛, рдЖрдк рдЕрд╕рд╣рд╛рдп рд╕реЗрдЯ-рдпреВрдЬрд╝рд░-рдЖрдИрдбреА рдмрд╛рдЗрдирд░реА рдХреЛ рдЖрднрд╛рд╕реА рд╡рд╛рд╕реНрддрд╡рд┐рдХрддрд╛ рдореЗрдВ рдбрд╛рд▓ рд╕рдХрддреЗ рд╣реИрдВ, рдЬрд┐рд╕рдореЗрдВ setuid рд╢реВрдиреНрдп рд╡рд╛рдкрд╕ рдЖ рдЬрд╛рдПрдЧрд╛, рд▓реЗрдХрд┐рди рдХреБрдЫ рднреА рдирд╣реАрдВ рдХрд░реЗрдЧрд╛, рдЬреЛ рджреГрд╖реНрдЯрд┐рдХреЛрдг рд╕реЗ рдмрд╣реБрдд рдЦрддрд░рдирд╛рдХ рд╣реЛрдЧрд╛ рд╡рд┐рд╢реЗрд╖рд╛рдзрд┐рдХрд╛рд░ рдЙрддреНрдерд╛рди рджреГрд╢реНрдпред


рд╣рдо рдЕрдкрдиреЗ рдкреБрд╕реНрддрдХрд╛рд▓рдп рдХрд╛ рд╕рдВрдХрд▓рди рдФрд░ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ:


 $ gcc -fPIC --shared syscall-handler.c -o syscall-handler.so $ LD_PRELOAD=syscall-handler.so ls ERROR: ld.so: object 'syscall-handler.so' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored. article.md example.c syscall-handler.c syscall-handler.so $ LD_PRELOAD=./syscall-handler.so ls article.md example.c syscall-handler.c syscall-handler.so 

рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ, рдХрдо рд╕реЗ рдХрдо рдореЗрд░реЗ рд╕рд┐рд╕реНрдЯрдо рдкрд░ рдЖрдкрдХреЛ рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдХреЗ рд▓рд┐рдП рдкрде рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рд╣рд╛рд▓рд╛рдВрдХрд┐ рд░рд┐рд╢реНрддреЗрджрд╛рд░, рд▓реЗрдХрд┐рди рдЬрд┐рд╕ рддрд░рд╣ рд╕реЗред рдпрд╣ рдЕрдЪреНрдЫрд╛ рд╣реИ рдХрд┐ рдмреВрдЯрд▓реЛрдбрд░ рдиреЗ рддреНрд░реБрдЯрд┐ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЪреЗрддрд╛рд╡рдиреА рджреА рд╣реИред рджреВрд╕рд░реЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рд╕рдм рдХреБрдЫ рдХрд╛рдо рдХрд░рдиреЗ рд▓рдЧрддрд╛ рд╣реИ ред


рдбрд┐рдмрдЧрд┐рдВрдЧ


рд╣рдо рдбрд┐рдмрдЧ рд╕рд┐рд╕реНрдЯрдо рдХреЙрд▓ рдХреИрд╕реЗ рдХрд░рддреЗ рд╣реИрдВ? рдЖрдк рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ, gdb рдореЗрдВ catch syscall рдорд╛рдзреНрдпрдо рд╕реЗ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ (рдЬреИрд╕рд╛ рдХрд┐ рдЬреНрдпрд╛рджрд╛рддрд░ рдЕрдиреНрдп, рдИрдорд╛рдирджрд╛рд░ рд╣реЛрдиреЗ рдХреЗ рд▓рд┐рдП) рдЕрджреНрднреБрдд strace рдЯреВрд▓ рд╣рдорд╛рд░реА рдорджрдж рдХрд░реЗрдВрдЧреЗ:


 strace -E LD_PRELOAD=./syscall-handler.so ls 

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


рдЖрдЙрдЯрдкреБрдЯ рдзрд╛рд░рд╛
 $ strace -E LD_PRELOAD=./syscall-handler.so ls execve("/bin/ls", ["ls"], 0x5652b17024d0 /* 61 vars */) = 0 brk(NULL) = 0x55a2f556d000 arch_prctl(0x3001 /* ARCH_??? */, 0x7fffe8e949b0) = -1 EINVAL ( ) openat(AT_FDCWD, "./syscall-handler.so", O_RDONLY|O_CLOEXEC) = 3 read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0 \21\0\0\0\0\0\0"..., 832) = 832 fstat(3, {st_mode=S_IFREG|0775, st_size=16504, ...}) = 0 mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f29f6baf000 getcwd("/home/trosinenko/some/path", 128) = 63 mmap(NULL, 16480, PROT_READ, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f29f6baa000 mmap(0x7f29f6bab000, 4096, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1000) = 0x7f29f6bab000 mmap(0x7f29f6bac000, 4096, PROT_READ, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x2000) = 0x7f29f6bac000 mmap(0x7f29f6bad000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x2000) = 0x7f29f6bad000 close(3) = 0 access("/etc/ld.so.preload", R_OK) = -1 ENOENT (    ) openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3 fstat(3, {st_mode=S_IFREG|0644, st_size=254851, ...}) = 0 mmap(NULL, 254851, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f29f6b6b000 close(3) = 0 openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libselinux.so.1", O_RDONLY|O_CLOEXEC) = 3 read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\300p\0\0\0\0\0\0"..., 832) = 832 fstat(3, {st_mode=S_IFREG|0644, st_size=163240, ...}) = 0 mmap(NULL, 174640, PROT_READ, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f29f6b40000 mprotect(0x7f29f6b46000, 135168, PROT_NONE) = 0 mmap(0x7f29f6b46000, 102400, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x6000) = 0x7f29f6b46000 mmap(0x7f29f6b5f000, 28672, PROT_READ, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1f000) = 0x7f29f6b5f000 mmap(0x7f29f6b67000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x26000) = 0x7f29f6b67000 mmap(0x7f29f6b69000, 6704, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f29f6b69000 close(3) = 0 openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3 read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\360r\2\0\0\0\0\0"..., 832) = 832 lseek(3, 64, SEEK_SET) = 64 read(3, "\6\0\0\0\4\0\0\0@\0\0\0\0\0\0\0@\0\0\0\0\0\0\0@\0\0\0\0\0\0\0"..., 784) = 784 lseek(3, 848, SEEK_SET) = 848 read(3, "\4\0\0\0\20\0\0\0\5\0\0\0GNU\0\2\0\0\300\4\0\0\0\3\0\0\0\0\0\0\0", 32) = 32 lseek(3, 880, SEEK_SET) = 880 read(3, "\4\0\0\0\24\0\0\0\3\0\0\0GNU\0!U\364U\255V\275\207\34\202%\274\312\205\356%"..., 68) = 68 fstat(3, {st_mode=S_IFREG|0755, st_size=2025032, ...}) = 0 lseek(3, 64, SEEK_SET) = 64 read(3, "\6\0\0\0\4\0\0\0@\0\0\0\0\0\0\0@\0\0\0\0\0\0\0@\0\0\0\0\0\0\0"..., 784) = 784 lseek(3, 848, SEEK_SET) = 848 read(3, "\4\0\0\0\20\0\0\0\5\0\0\0GNU\0\2\0\0\300\4\0\0\0\3\0\0\0\0\0\0\0", 32) = 32 lseek(3, 880, SEEK_SET) = 880 read(3, "\4\0\0\0\24\0\0\0\3\0\0\0GNU\0!U\364U\255V\275\207\34\202%\274\312\205\356%"..., 68) = 68 mmap(NULL, 2032984, PROT_READ, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f29f694f000 mmap(0x7f29f6974000, 1540096, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x25000) = 0x7f29f6974000 mmap(0x7f29f6aec000, 303104, PROT_READ, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x19d000) = 0x7f29f6aec000 mmap(0x7f29f6b36000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1e6000) = 0x7f29f6b36000 mmap(0x7f29f6b3c000, 13656, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f29f6b3c000 close(3) = 0 openat(AT_FDCWD, "/usr/lib/x86_64-linux-gnu/libpcre2-8.so.0", O_RDONLY|O_CLOEXEC) = 3 read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\200!\0\0\0\0\0\0"..., 832) = 832 fstat(3, {st_mode=S_IFREG|0644, st_size=539176, ...}) = 0 mmap(NULL, 541448, PROT_READ, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f29f68ca000 mmap(0x7f29f68cc000, 376832, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x2000) = 0x7f29f68cc000 mmap(0x7f29f6928000, 151552, PROT_READ, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x5e000) = 0x7f29f6928000 mmap(0x7f29f694d000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x82000) = 0x7f29f694d000 close(3) = 0 openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libdl.so.2", O_RDONLY|O_CLOEXEC) = 3 read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0 \22\0\0\0\0\0\0"..., 832) = 832 fstat(3, {st_mode=S_IFREG|0644, st_size=18816, ...}) = 0 mmap(NULL, 20752, PROT_READ, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f29f68c4000 mmap(0x7f29f68c5000, 8192, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1000) = 0x7f29f68c5000 mmap(0x7f29f68c7000, 4096, PROT_READ, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x3000) = 0x7f29f68c7000 mmap(0x7f29f68c8000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x3000) = 0x7f29f68c8000 close(3) = 0 openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libpthread.so.0", O_RDONLY|O_CLOEXEC) = 3 read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\360\201\0\0\0\0\0\0"..., 832) = 832 lseek(3, 824, SEEK_SET) = 824 read(3, "\4\0\0\0\24\0\0\0\3\0\0\0GNU\09V\4W\221\35\226\215\236\6\10\215\240\25\227\v"..., 68) = 68 fstat(3, {st_mode=S_IFREG|0755, st_size=158288, ...}) = 0 lseek(3, 824, SEEK_SET) = 824 read(3, "\4\0\0\0\24\0\0\0\3\0\0\0GNU\09V\4W\221\35\226\215\236\6\10\215\240\25\227\v"..., 68) = 68 mmap(NULL, 140448, PROT_READ, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f29f68a1000 mmap(0x7f29f68a8000, 69632, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x7000) = 0x7f29f68a8000 mmap(0x7f29f68b9000, 20480, PROT_READ, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x18000) = 0x7f29f68b9000 mmap(0x7f29f68be000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1c000) = 0x7f29f68be000 mmap(0x7f29f68c0000, 13472, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f29f68c0000 close(3) = 0 mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f29f689f000 mmap(NULL, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f29f689c000 arch_prctl(ARCH_SET_FS, 0x7f29f689c800) = 0 mprotect(0x7f29f6b36000, 12288, PROT_READ) = 0 mprotect(0x7f29f68be000, 4096, PROT_READ) = 0 mprotect(0x7f29f68c8000, 4096, PROT_READ) = 0 mprotect(0x7f29f694d000, 4096, PROT_READ) = 0 mprotect(0x7f29f6b67000, 4096, PROT_READ) = 0 mprotect(0x7f29f6bad000, 4096, PROT_READ) = 0 mprotect(0x55a2f4670000, 4096, PROT_READ) = 0 mprotect(0x7f29f6bdd000, 4096, PROT_READ) = 0 munmap(0x7f29f6b6b000, 254851) = 0 set_tid_address(0x7f29f689cad0) = 31949 set_robust_list(0x7f29f689cae0, 24) = 0 rt_sigaction(SIGRTMIN, {sa_handler=0x7f29f68a8c50, sa_mask=[], sa_flags=SA_RESTORER|SA_SIGINFO, sa_restorer=0x7f29f68b6540}, NULL, 8) = 0 rt_sigaction(SIGRT_1, {sa_handler=0x7f29f68a8cf0, sa_mask=[], sa_flags=SA_RESTORER|SA_RESTART|SA_SIGINFO, sa_restorer=0x7f29f68b6540}, NULL, 8) = 0 rt_sigprocmask(SIG_UNBLOCK, [RTMIN RT_1], NULL, 8) = 0 prlimit64(0, RLIMIT_STACK, NULL, {rlim_cur=8192*1024, rlim_max=RLIM64_INFINITY}) = 0 statfs("/sys/fs/selinux", 0x7fffe8e94900) = -1 ENOENT (    ) statfs("/selinux", 0x7fffe8e94900) = -1 ENOENT (    ) brk(NULL) = 0x55a2f556d000 brk(0x55a2f558e000) = 0x55a2f558e000 openat(AT_FDCWD, "/proc/filesystems", O_RDONLY|O_CLOEXEC) = 3 fstat(3, {st_mode=S_IFREG|0444, st_size=0, ...}) = 0 read(3, "nodev\tsysfs\nnodev\ttmpfs\nnodev\tbd"..., 1024) = 425 read(3, "", 1024) = 0 close(3) = 0 access("/etc/selinux/config", F_OK) = -1 ENOENT (    ) rt_sigaction(SIGSYS, {sa_handler=0x7f29f6bab1ff, sa_mask=[], sa_flags=SA_RESTORER|SA_SIGINFO, sa_restorer=0x7f29f6995470}, NULL, 8) = 0 prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) = 0 seccomp(SECCOMP_SET_MODE_FILTER, 0, {len=4, filter=0x7fffe8e94930}) = 0 openat(AT_FDCWD, "/usr/lib/locale/locale-archive", O_RDONLY|O_CLOEXEC) = 257 --- SIGSYS {si_signo=SIGSYS, si_code=SYS_SECCOMP, si_call_addr=0x7f29f6a6579c, si_syscall=__NR_openat, si_arch=AUDIT_ARCH_X86_64} --- openat(AT_FDCWD, "/usr/lib/locale/locale-archive", O_RDONLY|O_CLOEXEC) = 3 rt_sigreturn({mask=[]}) = 3 fstat(3, {st_mode=000, st_size=0, ...}) = 5 --- SIGSYS {si_signo=SIGSYS, si_code=SYS_SECCOMP, si_call_addr=0x7f29f6a5f7b9, si_syscall=__NR_fstat, si_arch=AUDIT_ARCH_X86_64} --- fstat(3, {st_mode=S_IFREG|0644, st_size=8994080, ...}) = 0 rt_sigreturn({mask=[]}) = 0 mmap(NULL, 8994080, PROT_READ, MAP_PRIVATE, 3, 0) = 0x9 --- SIGSYS {si_signo=SIGSYS, si_code=SYS_SECCOMP, si_call_addr=0x7f29f6a6aaf6, si_syscall=__NR_mmap, si_arch=AUDIT_ARCH_X86_64} --- mmap(NULL, 8994080, PROT_READ, MAP_PRIVATE, 3, 0x12345678) = -1 EINVAL ( ) rt_sigreturn({mask=[]}) = -1 EPERM (  ) close(3) = 3 --- SIGSYS {si_signo=SIGSYS, si_code=SYS_SECCOMP, si_call_addr=0x7f29f6a655bb, si_syscall=__NR_close, si_arch=AUDIT_ARCH_X86_64} --- close(3) = 0 rt_sigreturn({mask=[]}) = 0 openat(AT_FDCWD, "/usr/share/locale/locale.alias", O_RDONLY|O_CLOEXEC) = 257 --- SIGSYS {si_signo=SIGSYS, si_code=SYS_SECCOMP, si_call_addr=0x7f29f6a6579c, si_syscall=__NR_openat, si_arch=AUDIT_ARCH_X86_64} --- openat(AT_FDCWD, "/usr/share/locale/locale.alias", O_RDONLY|O_CLOEXEC) = 3 rt_sigreturn({mask=[]}) = 3 fstat(3, {st_mode=037, st_size=0, ...}) = 5 --- SIGSYS {si_signo=SIGSYS, si_code=SYS_SECCOMP, si_call_addr=0x7f29f6a5f7b9, si_syscall=__NR_fstat, si_arch=AUDIT_ARCH_X86_64} --- fstat(3, {st_mode=S_IFREG|0644, st_size=2995, ...}) = 0 rt_sigreturn({mask=[]}) = 0 read(3, "", 4096) = 0 --- SIGSYS {si_signo=SIGSYS, si_code=SYS_SECCOMP, si_call_addr=0x7f29f6a658d8, si_syscall=__NR_read, si_arch=AUDIT_ARCH_X86_64} --- read(3, "# Locale name alias data base.\n#"..., 4096) = 2995 rt_sigreturn({mask=[]}) = 2995 read(3, "", 4096) = 0 --- SIGSYS {si_signo=SIGSYS, si_code=SYS_SECCOMP, si_call_addr=0x7f29f6a658d8, si_syscall=__NR_read, si_arch=AUDIT_ARCH_X86_64} --- read(3, "", 4096) = 0 rt_sigreturn({mask=[]}) = 0 close(3) = 3 --- SIGSYS {si_signo=SIGSYS, si_code=SYS_SECCOMP, si_call_addr=0x7f29f6a655bb, si_syscall=__NR_close, si_arch=AUDIT_ARCH_X86_64} --- close(3) = 0 rt_sigreturn({mask=[]}) = 0 openat(AT_FDCWD, "/usr/lib/locale/ru_RU.UTF-8/LC_IDENTIFICATION", O_RDONLY|O_CLOEXEC) = 257 --- SIGSYS {si_signo=SIGSYS, si_code=SYS_SECCOMP, si_call_addr=0x7f29f6a6579c, si_syscall=__NR_openat, si_arch=AUDIT_ARCH_X86_64} --- openat(AT_FDCWD, "/usr/lib/locale/ru_RU.UTF-8/LC_IDENTIFICATION", O_RDONLY|O_CLOEXEC) = -1 ENOENT (    ) rt_sigreturn({mask=[]}) = -1 EPERM (  ) openat(AT_FDCWD, "/usr/lib/locale/ru_RU.utf8/LC_IDENTIFICATION", O_RDONLY|O_CLOEXEC) = 257 --- SIGSYS {si_signo=SIGSYS, si_code=SYS_SECCOMP, si_call_addr=0x7f29f6a6579c, si_syscall=__NR_openat, si_arch=AUDIT_ARCH_X86_64} --- openat(AT_FDCWD, "/usr/lib/locale/ru_RU.utf8/LC_IDENTIFICATION", O_RDONLY|O_CLOEXEC) = -1 ENOENT (    ) rt_sigreturn({mask=[]}) = -1 EPERM (  ) openat(AT_FDCWD, "/usr/lib/locale/ru_RU/LC_IDENTIFICATION", O_RDONLY|O_CLOEXEC) = 257 --- SIGSYS {si_signo=SIGSYS, si_code=SYS_SECCOMP, si_call_addr=0x7f29f6a6579c, si_syscall=__NR_openat, si_arch=AUDIT_ARCH_X86_64} --- openat(AT_FDCWD, "/usr/lib/locale/ru_RU/LC_IDENTIFICATION", O_RDONLY|O_CLOEXEC) = -1 ENOENT (    ) rt_sigreturn({mask=[]}) = -1 EPERM (  ) openat(AT_FDCWD, "/usr/lib/locale/ru.UTF-8/LC_IDENTIFICATION", O_RDONLY|O_CLOEXEC) = 257 --- SIGSYS {si_signo=SIGSYS, si_code=SYS_SECCOMP, si_call_addr=0x7f29f6a6579c, si_syscall=__NR_openat, si_arch=AUDIT_ARCH_X86_64} --- openat(AT_FDCWD, "/usr/lib/locale/ru.UTF-8/LC_IDENTIFICATION", O_RDONLY|O_CLOEXEC) = -1 ENOENT (    ) rt_sigreturn({mask=[]}) = -1 EPERM (  ) openat(AT_FDCWD, "/usr/lib/locale/ru.utf8/LC_IDENTIFICATION", O_RDONLY|O_CLOEXEC) = 257 --- SIGSYS {si_signo=SIGSYS, si_code=SYS_SECCOMP, si_call_addr=0x7f29f6a6579c, si_syscall=__NR_openat, si_arch=AUDIT_ARCH_X86_64} --- openat(AT_FDCWD, "/usr/lib/locale/ru.utf8/LC_IDENTIFICATION", O_RDONLY|O_CLOEXEC) = -1 ENOENT (    ) rt_sigreturn({mask=[]}) = -1 EPERM (  ) openat(AT_FDCWD, "/usr/lib/locale/ru/LC_IDENTIFICATION", O_RDONLY|O_CLOEXEC) = 257 --- SIGSYS {si_signo=SIGSYS, si_code=SYS_SECCOMP, si_call_addr=0x7f29f6a6579c, si_syscall=__NR_openat, si_arch=AUDIT_ARCH_X86_64} --- openat(AT_FDCWD, "/usr/lib/locale/ru/LC_IDENTIFICATION", O_RDONLY|O_CLOEXEC) = -1 ENOENT (    ) rt_sigreturn({mask=[]}) = -1 EPERM (  ) ioctl(1, TCGETS, {B4000000 opost -isig icanon -echo ...}) = 16 --- SIGSYS {si_signo=SIGSYS, si_code=SYS_SECCOMP, si_call_addr=0x7f29f6a65cea, si_syscall=__NR_ioctl, si_arch=AUDIT_ARCH_X86_64} --- ioctl(1, TCGETS, {B38400 opost isig icanon echo ...}) = 0 rt_sigreturn({mask=[]}) = 0 ioctl(1, TIOCGWINSZ, {ws_row=45567, ws_col=63162, ws_xpixel=32553, ws_ypixel=0}) = 16 --- SIGSYS {si_signo=SIGSYS, si_code=SYS_SECCOMP, si_call_addr=0x7f29f6a6667b, si_syscall=__NR_ioctl, si_arch=AUDIT_ARCH_X86_64} --- ioctl(1, TIOCGWINSZ, {ws_row=58, ws_col=271, ws_xpixel=0, ws_ypixel=0}) = 0 rt_sigreturn({mask=[]}) = 0 openat(AT_FDCWD, ".", O_RDONLY|O_NONBLOCK|O_CLOEXEC|O_DIRECTORY) = 257 --- SIGSYS {si_signo=SIGSYS, si_code=SYS_SECCOMP, si_call_addr=0x7f29f6a6579c, si_syscall=__NR_openat, si_arch=AUDIT_ARCH_X86_64} --- openat(AT_FDCWD, ".", O_RDONLY|O_NONBLOCK|O_CLOEXEC|O_DIRECTORY) = 3 rt_sigreturn({mask=[]}) = 3 fstat(3, {st_mode=037777777777, st_size=139818209035479, ...}) = 5 --- SIGSYS {si_signo=SIGSYS, si_code=SYS_SECCOMP, si_call_addr=0x7f29f6a5f7b9, si_syscall=__NR_fstat, si_arch=AUDIT_ARCH_X86_64} --- fstat(3, {st_mode=S_IFDIR|0775, st_size=4096, ...}) = 0 rt_sigreturn({mask=[]}) = 0 getdents64(3, /* d_reclen < offsetof(struct dirent64, d_name) */ /* 0 entries */, 32768) = 217 --- SIGSYS {si_signo=SIGSYS, si_code=SYS_SECCOMP, si_call_addr=0x7f29f6a3007b, si_syscall=__NR_getdents64, si_arch=AUDIT_ARCH_X86_64} --- getdents64(3, /* 7 entries */, 32768) = 232 rt_sigreturn({mask=[]}) = 232 getdents64(3, /* 7 entries */, 32768) = 217 --- SIGSYS {si_signo=SIGSYS, si_code=SYS_SECCOMP, si_call_addr=0x7f29f6a3007b, si_syscall=__NR_getdents64, si_arch=AUDIT_ARCH_X86_64} --- getdents64(3, /* 0 entries */, 32768) = 0 rt_sigreturn({mask=[]}) = 0 close(3) = 3 --- SIGSYS {si_signo=SIGSYS, si_code=SYS_SECCOMP, si_call_addr=0x7f29f6a655bb, si_syscall=__NR_close, si_arch=AUDIT_ARCH_X86_64} --- close(3) = 0 rt_sigreturn({mask=[]}) = 0 fstat(1, {st_mode=000, st_size=0, ...}) = 5 --- SIGSYS {si_signo=SIGSYS, si_code=SYS_SECCOMP, si_call_addr=0x7f29f6a5f7b9, si_syscall=__NR_fstat, si_arch=AUDIT_ARCH_X86_64} --- fstat(1, {st_mode=S_IFCHR|0600, st_rdev=makedev(0x88, 0x7), ...}) = 0 rt_sigreturn({mask=[]}) = 0 write(1, "article.md example.c syscall-h"..., 61) = 1 --- SIGSYS {si_signo=SIGSYS, si_code=SYS_SECCOMP, si_call_addr=0x7f29f6a60317, si_syscall=__NR_write, si_arch=AUDIT_ARCH_X86_64} --- write(1, "article.md example.c syscall-h"..., 61article.md example.c syscall-handler.c syscall-handler.so ) = 61 rt_sigreturn({mask=[]}) = 61 close(1) = 3 --- SIGSYS {si_signo=SIGSYS, si_code=SYS_SECCOMP, si_call_addr=0x7f29f6a655bb, si_syscall=__NR_close, si_arch=AUDIT_ARCH_X86_64} --- close(1) = 0 rt_sigreturn({mask=[]}) = 0 close(2) = 3 --- SIGSYS {si_signo=SIGSYS, si_code=SYS_SECCOMP, si_call_addr=0x7f29f6a655bb, si_syscall=__NR_close, si_arch=AUDIT_ARCH_X86_64} --- close(2) = 0 rt_sigreturn({mask=[]}) = 0 exit_group(0) = 231 --- SIGSYS {si_signo=SIGSYS, si_code=SYS_SECCOMP, si_call_addr=0x7f29f6a34fe6, si_syscall=__NR_exit_group, si_arch=AUDIT_ARCH_X86_64} --- exit_group(0) = ? +++ exited with 0 +++ 

(-, userspace), - , ...


 ... rt_sigaction(SIGSYS, {sa_handler=0x7f29f6bab1ff, sa_mask=[], sa_flags=SA_RESTORER|SA_SIGINFO, sa_restorer=0x7f29f6995470}, NULL, 8) = 0 prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) = 0 seccomp(SECCOMP_SET_MODE_FILTER, 0, {len=4, filter=0x7fffe8e94930}) = 0 openat(AT_FDCWD, "/usr/lib/locale/locale-archive", O_RDONLY|O_CLOEXEC) = 257 --- SIGSYS {si_signo=SIGSYS, si_code=SYS_SECCOMP, si_call_addr=0x7f29f6a6579c, si_syscall=__NR_openat, si_arch=AUDIT_ARCH_X86_64} --- openat(AT_FDCWD, "/usr/lib/locale/locale-archive", O_RDONLY|O_CLOEXEC) = 3 rt_sigreturn({mask=[]}) = 3 fstat(3, {st_mode=000, st_size=0, ...}) = 5 --- SIGSYS {si_signo=SIGSYS, si_code=SYS_SECCOMP, si_call_addr=0x7f29f6a5f7b9, si_syscall=__NR_fstat, si_arch=AUDIT_ARCH_X86_64} --- fstat(3, {st_mode=S_IFREG|0644, st_size=8994080, ...}) = 0 rt_sigreturn({mask=[]}) = 0 mmap(NULL, 8994080, PROT_READ, MAP_PRIVATE, 3, 0) = 0x9 --- SIGSYS {si_signo=SIGSYS, si_code=SYS_SECCOMP, si_call_addr=0x7f29f6a6aaf6, si_syscall=__NR_mmap, si_arch=AUDIT_ARCH_X86_64} --- mmap(NULL, 8994080, PROT_READ, MAP_PRIVATE, 3, 0x12345678) = -1 EINVAL ( ) rt_sigreturn({mask=[]}) = -1 EPERM (  ) close(3) = 3 --- SIGSYS {si_signo=SIGSYS, si_code=SYS_SECCOMP, si_call_addr=0x7f29f6a655bb, si_syscall=__NR_close, si_arch=AUDIT_ARCH_X86_64} --- close(3) = 0 rt_sigreturn({mask=[]}) = 0 openat(AT_FDCWD, "/usr/share/locale/locale.alias", O_RDONLY|O_CLOEXEC) = 257 --- SIGSYS {si_signo=SIGSYS, si_code=SYS_SECCOMP, si_call_addr=0x7f29f6a6579c, si_syscall=__NR_openat, si_arch=AUDIT_ARCH_X86_64} --- openat(AT_FDCWD, "/usr/share/locale/locale.alias", O_RDONLY|O_CLOEXEC) = 3 rt_sigreturn({mask=[]}) = 3 fstat(3, {st_mode=037, st_size=0, ...}) = 5 --- SIGSYS {si_signo=SIGSYS, si_code=SYS_SECCOMP, si_call_addr=0x7f29f6a5f7b9, si_syscall=__NR_fstat, si_arch=AUDIT_ARCH_X86_64} --- fstat(3, {st_mode=S_IFREG|0644, st_size=2995, ...}) = 0 rt_sigreturn({mask=[]}) = 0 read(3, "", 4096) = 0 --- SIGSYS {si_signo=SIGSYS, si_code=SYS_SECCOMP, si_call_addr=0x7f29f6a658d8, si_syscall=__NR_read, si_arch=AUDIT_ARCH_X86_64} --- read(3, "# Locale name alias data base.\n#"..., 4096) = 2995 ... 

, , тАФ SIGSYS , . , , fstat : тАФ !


...


, - . - : openat , libc : handle_syscall


  if (num == SYS_openat) { fprintf(stderr, "openat: %s\n", (const char *)arg2); } 

:


 $ gcc -fPIC --shared syscall-handler.c -o syscall-handler.so $ LD_PRELOAD=./syscall-handler.so ls    $ strace -E LD_PRELOAD=./syscall-handler.so ls ... rt_sigaction(SIGSYS, {sa_handler=0x7f55ef2cb24e, sa_mask=[], sa_flags=SA_RESTORER|SA_SIGINFO, sa_restorer=0x7f55ef0b5470}, NULL, 8) = 0 prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) = 0 seccomp(SECCOMP_SET_MODE_FILTER, 0, {len=4, filter=0x7ffca47b36e0}) = 0 openat(AT_FDCWD, "/usr/lib/locale/locale-archive", O_RDONLY|O_CLOEXEC) = 257 --- SIGSYS {si_signo=SIGSYS, si_code=SYS_SECCOMP, si_call_addr=0x7f55ef18579c, si_syscall=__NR_openat, si_arch=AUDIT_ARCH_X86_64} --- write(2, "openat: /usr/lib/locale/locale-a"..., 39) = 1 --- SIGSYS {si_signo=SIGSYS, si_code=SYS_SECCOMP, si_call_addr=0x7f55ef180317, si_syscall=__NR_write, si_arch=AUDIT_ARCH_X86_64} --- +++ killed by SIGSYS +++    

: SA_NODEFER , SIGSYS , deadlock. initialize_handler :


  sig.sa_flags = SA_SIGINFO | SA_NODEFER; 

 $ LD_PRELOAD=./syscall-handler.so ls openat: /usr/lib/locale/locale-archive openat: /usr/share/locale/locale.alias openat: /usr/lib/locale/ru_RU.UTF-8/LC_IDENTIFICATION openat: /usr/lib/locale/ru_RU.utf8/LC_IDENTIFICATION openat: /usr/lib/locale/ru_RU/LC_IDENTIFICATION openat: /usr/lib/locale/ru.UTF-8/LC_IDENTIFICATION openat: /usr/lib/locale/ru.utf8/LC_IDENTIFICATION openat: /usr/lib/locale/ru/LC_IDENTIFICATION openat: . article.md example.c syscall-handler.c syscall-handler.so 

...


, . mmap :) , , - .


example.c:


 #include <stdio.h> #include <stdlib.h> int main() { fprintf(stderr, "Allocating 1MB of memory\n"); void *ptr = malloc(1 << 20); fprintf(stderr, "Allocated: %p\n", ptr); } 

 $ LD_PRELOAD=./syscall-handler.so ./example Allocating 1MB of memory Allocated: 0x564fc07012a0 

тАж ?!?


 $ strace -E LD_PRELOAD=./syscall-handler.so ./example ... rt_sigaction(SIGSYS, {sa_handler=0x7fd7065cd24e, sa_mask=[], sa_flags=SA_RESTORER|SA_NODEFER|SA_SIGINFO, sa_restorer=0x7fd7063e2470}, NULL, 8) = 0 prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) = 0 seccomp(SECCOMP_SET_MODE_FILTER, 0, {len=4, filter=0x7fff8ea97810}) = 0 write(2, "Allocating 1MB of memory\n", 25) = 1 --- SIGSYS {si_signo=SIGSYS, si_code=SYS_SECCOMP, si_call_addr=0x7fd7064ad317, si_syscall=__NR_write, si_arch=AUDIT_ARCH_X86_64} --- write(2, "Allocating 1MB of memory\n", 25Allocating 1MB of memory ) = 25 rt_sigreturn({mask=[]}) = 25 brk(NULL) = 0xc --- SIGSYS {si_signo=SIGSYS, si_code=SYS_SECCOMP, si_call_addr=0x7fd7064b355b, si_syscall=__NR_brk, si_arch=AUDIT_ARCH_X86_64} --- brk(NULL) = 0x55e31f74f000 rt_sigreturn({mask=[]}) = 94433973694464 brk(0x55e31f770000) = 0xc --- SIGSYS {si_signo=SIGSYS, si_code=SYS_SECCOMP, si_call_addr=0x7fd7064b355b, si_syscall=__NR_brk, si_arch=AUDIT_ARCH_X86_64} --- brk(0x55e31f770000) = 0x55e31f770000 rt_sigreturn({mask=[]}) = 94433973829632 mmap(NULL, 1052672, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x9 --- SIGSYS {si_signo=SIGSYS, si_code=SYS_SECCOMP, si_call_addr=0x7fd7064b7af6, si_syscall=__NR_mmap, si_arch=AUDIT_ARCH_X86_64} --- mmap(NULL, 1052672, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0x12345678) = -1 EINVAL ( ) rt_sigreturn({mask=[]}) = -1 EPERM (  ) brk(0x55e31f870000) = 0xc --- SIGSYS {si_signo=SIGSYS, si_code=SYS_SECCOMP, si_call_addr=0x7fd7064b355b, si_syscall=__NR_brk, si_arch=AUDIT_ARCH_X86_64} --- brk(0x55e31f870000) = 0x55e31f870000 rt_sigreturn({mask=[]}) = 94433974878208 write(2, "Allocated: 0x55e31f74f2a0\n", 26) = 1 --- SIGSYS {si_signo=SIGSYS, si_code=SYS_SECCOMP, si_call_addr=0x7fd7064ad317, si_syscall=__NR_write, si_arch=AUDIT_ARCH_X86_64} --- write(2, "Allocated: 0x55e31f74f2a0\n", 26Allocated: 0x55e31f74f2a0 ) = 26 rt_sigreturn({mask=[]}) = 26 exit_group(0) = 231 --- SIGSYS {si_signo=SIGSYS, si_code=SYS_SECCOMP, si_call_addr=0x7fd706481fe6, si_syscall=__NR_exit_group, si_arch=AUDIT_ARCH_X86_64} --- exit_group(0) = ? +++ exited with 0 +++ 

: mmap , libc brk . ...


 #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <sys/mman.h> #include <stdio.h> #include <stdlib.h> int main() { fprintf(stderr, "Allocating 1MB of memory\n"); void *ptr = malloc(1 << 20); fprintf(stderr, "Allocated: %p\n", ptr); const char *fname = "test.bin"; int fd = open(fname, O_RDONLY); fprintf(stderr, "Mapping first 1MB of %s\n", fname); void *ptr2 = mmap(NULL, 1 << 20, PROT_READ, MAP_PRIVATE | MAP_ANONYMOUS, fd, 0); fprintf(stderr, "Mapped: %p\n", ptr2); return 0; } 

 $ gcc example.c -o example $ ./example Allocating 1MB of memory Allocated: 0x7f1aa7d09010 Mapping first 1MB of test.bin Mapped: 0x7f1aa7c09000 $ LD_PRELOAD=./syscall-handler.so ./example Allocating 1MB of memory Allocated: 0x556a51df52a0 openat: test.bin Mapping first 1MB of test.bin Mapped: 0xffffffffffffffff 

┬л! тАФ ...┬╗ 0xffffffffffffffff , -1 , MAP_FAILED .


, mmap , :


 #define ALLOW(sys) \ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, (offsetof(struct seccomp_data, nr))), \ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K , sys, 0, 1), \ BPF_STMT(BPF_RET | BPF_K , SECCOMP_RET_ALLOW), struct sock_filter filt[] = { BPF_STMT(BPF_LD | BPF_W | BPF_ABS, (offsetof(struct seccomp_data, args[5]))), BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K , MARKER, 0, 1), BPF_STMT(BPF_RET | BPF_K , SECCOMP_RET_ALLOW), ALLOW(SYS_mmap) BPF_STMT(BPF_RET | BPF_K , SECCOMP_RET_TRAP), }; 

:


 $ LD_PRELOAD=./syscall-handler.so ./example Allocating 1MB of memory Allocated: 0x7fad45a6f010 openat: test.bin Mapping first 1MB of test.bin Mapped: 0x7fad4596f000 

 #define _GNU_SOURCE #include <errno.h> #include <stddef.h> #include <stdio.h> #include <stdint.h> #include <stdlib.h> #include <unistd.h> #include <linux/audit.h> #include <linux/filter.h> #include <linux/seccomp.h> #include <sys/prctl.h> #include <unistd.h> #include <syscall.h> #include <signal.h> #include <string.h> uint64_t handle_syscall(uint32_t num, uint32_t *drop_syscall, uint64_t arg1, uint64_t arg2, uint64_t arg3, uint64_t arg4, uint64_t arg5, uint64_t arg6) { if (num == SYS_openat) { fprintf(stderr, "openat: %s\n", (const char *)arg2); } return 0; } #define MARKER 0x12345678 static int in_handler; static void handle_sigsys(int num, siginfo_t *si, void *arg) { ucontext_t *ctx = arg; greg_t *gregs = ctx->uc_mcontext.gregs; uint32_t drop = 0; uint64_t res; if (!in_handler) { in_handler = 1; res = handle_syscall(gregs[REG_RAX], &drop, gregs[REG_RDI], gregs[REG_RSI], gregs[REG_RDX], gregs[REG_R10], gregs[REG_R8], gregs[REG_R9]); in_handler = 0; } if (!drop) { res = syscall(gregs[REG_RAX], gregs[REG_RDI], gregs[REG_RSI], gregs[REG_RDX], gregs[REG_R10], gregs[REG_R8], MARKER); } gregs[REG_RAX] = res; } void initialize_handler(void) { #define ALLOW(sys) \ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, (offsetof(struct seccomp_data, nr))), \ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K , sys, 0, 1), \ BPF_STMT(BPF_RET | BPF_K , SECCOMP_RET_ALLOW), struct sock_filter filt[] = { BPF_STMT(BPF_LD | BPF_W | BPF_ABS, (offsetof(struct seccomp_data, args[5]))), BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K , MARKER, 0, 1), BPF_STMT(BPF_RET | BPF_K , SECCOMP_RET_ALLOW), ALLOW(SYS_mmap) BPF_STMT(BPF_RET | BPF_K , SECCOMP_RET_TRAP), }; struct sock_fprog prog = { sizeof(filt) / sizeof(filt[0]), filt }; struct sigaction sig; memset(&sig, 0, sizeof(sig)); sig.sa_sigaction = handle_sigsys; sig.sa_flags = SA_SIGINFO | SA_NODEFER; sigaction(SIGSYS, &sig, NULL); prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0); syscall(SYS_seccomp, SECCOMP_SET_MODE_FILTER, 0, &prog); } static void __attribute__((constructor))constr(void) { initialize_handler(); } 

Source: https://habr.com/ru/post/hi469267/


All Articles