рд╕реЙрдлреНрдЯрд╡реЗрдпрд░ рд╕рд┐рд╕реНрдЯрдо рдХреЗ рдХрд╛рдордХрд╛рдЬ рдореЗрдВ рдЕрдкрд╡рд╛рдж рд╣реИрдВрдбрд▓рд┐рдВрдЧ рдПрдХ рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╕реНрдерд╛рди рд░рдЦрддрд╛ рд╣реИред рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рдЕрд╕рд╛рдорд╛рдиреНрдп рдШрдЯрдирд╛рдУрдВ рдХреЗ рд▓рд┐рдП рд╕рдордп рдкрд░ рдФрд░ рд╕рд╣реА рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░рдирд╛ рдСрдкрд░реЗрдЯрд┐рдВрдЧ рд╕рд┐рд╕реНрдЯрдо рджреНрд╡рд╛рд░рд╛ рдХрд┐рдП рдЧрдП рдкреНрд░рдореБрдЦ рдХрд╛рд░реНрдпреЛрдВ рдореЗрдВ рд╕реЗ рдПрдХ рд╣реИ рдФрд░, рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ, рдЗрд╕рдХрд╛ рдореВрд▓ред рдЖрдзреБрдирд┐рдХ рд╣реЛрдиреЗ рдХреЗ рдирд╛рддреЗ, рд▓рд┐рдирдХреНрд╕ рдХрд░реНрдиреЗрд▓ рдЕрдкрд╡рд╛рджреЛрдВ рдХреЛ рд╕рдВрднрд╛рд▓рдиреЗ рдХреА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЛ рдирд┐рдпрдВрддреНрд░рд┐рдд рдХрд░рдиреЗ рдХреА рдХреНрд╖рдорддрд╛ рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдЗрд╕рдХреЗ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХреА рд╕реАрдорд╛рдУрдВ рдХреЗ рдХрд╛рд░рдг, рдпрд╣ рддрдВрддреНрд░ рдХрд░реНрдиреЗрд▓ рдореЙрдбреНрдпреВрд▓ рдХреЗ рдбреЗрд╡рд▓рдкрд░реНрд╕ рдХреЗ рдмреАрдЪ рдЖрдо рдирд╣реАрдВ рд╣реИред
рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдкреЗрдЬрдлреЙрд▓реНрдЯ рдХреЗ рдЙрджрд╛рд╣рд░рдг рдкрд░, рдЕрдкрд╡рд╛рдж рд╣реИрдВрдбрд▓рд┐рдВрдЧ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреА рдХреБрдЫ рд╡рд┐рд╢реЗрд╖рддрд╛рдУрдВ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛, рд╕рд╛рде рд╣реА рд╕рд╛рде рдЙрд╕ рд╡рд┐рдзрд┐ рдХрд╛ рд╡рд░реНрдгрди рднреА рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ рдЬреЛ рдЖрдкрдХреЛ x86 рдЖрд░реНрдХрд┐рдЯреЗрдХреНрдЪрд░ рдХреЗ рд▓рд┐рдП рд▓рд┐рдирдХреНрд╕ рдХрд░реНрдиреЗрд▓ рдореЙрдбреНрдпреВрд▓ рд╡рд┐рдХрд╕рд┐рдд рдХрд░рддреЗ рд╕рдордп рдЗрд╕ рд╕реБрд╡рд┐рдзрд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред
рдореБрдЦреНрдп рдЕрдкрд╡рд╛рдж
рдХрд░реНрдиреЗрд▓ рдореЗрдВ рдХрд╣рд╛рдБ рдФрд░ рдХреИрд╕реЗ рдЕрдкрд╡рд╛рджреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд░реВрдк рдореЗрдВ, рдХрд░реНрдиреЗрд▓ рд╕реНрдерд╛рди рдФрд░ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рд╕реНрдерд╛рди рдХреЗ рдмреАрдЪ рдбреЗрдЯрд╛ рдХреА рдкреНрд░рддрд┐рд▓рд┐рдкрд┐ рдмрдирд╛рдиреЗ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВред рдЖрдорддреМрд░ рдкрд░, рдлрд╝рдВрдХреНрд╢рдВрд╕
copy_from_user рдФрд░
copy_to_user рдЗрд╕рдХреЗ рд▓рд┐рдП рдЬрд╝рд┐рдореНрдореЗрджрд╛рд░ рд╣реЛрддреЗ рд╣реИрдВ, рдЬрд┐рд╕рдХреА рдЦрд╝рд╛рд╕рд┐рдпрдд
рдореЗрдХрдкреА рд╕реЗ рдЕрд▓рдЧ рд╣реЛрддреА рд╣реИ, рд╡реЗ рдЕрд▓рдЧ-рдЕрд▓рдЧ рдПрдбреНрд░реЗрд╕ рд╕реНрдкреЗрд╕ рдХреЗ рдмреАрдЪ рдбреЗрдЯрд╛ рдЯреНрд░рд╛рдВрд╕рдлрд░ рдХреЗ рджреМрд░рд╛рди рд╣реЛрдиреЗ рд╡рд╛рд▓реЗ рдЕрдкрд╡рд╛рджреЛрдВ рдХреЛ рд╕рд╣реА рдврдВрдЧ рд╕реЗ рд╣реИрдВрдбрд▓ рдХрд░рддреЗ рд╣реИрдВред
рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рдпрджрд┐ рд╣рдо рдЙрд╕ рд╕реНрдерд┐рддрд┐ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░рддреЗ рд╣реИрдВ, рдЬрдм рдбреЗрдЯрд╛ рдХреЛ рдХрд░реНрдиреЗрд▓ рд╕реЗ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ (
copy_to_user
рдлрд╝рдВрдХреНрд╢рди) рдореЗрдВ рдХреЙрдкреА рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЗ рдкреГрд╖реНрда рдореЗрдВ рдЬрд┐рд╕ рд╕реНрдерд┐рддрд┐ рдореЗрдВ рд▓рд┐рдЦрдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рддрдм рд╕реНрдерд┐рддрд┐ рдЙрддреНрдкрдиреНрди рд╣реЛ рд╕рдХрддреА рд╣реИ рдпрд╛ рд╕реНрд╡реИрдк рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдореЗрдВ рдЙрдкрд▓рдмреНрдз рдирд╣реАрдВ рд╣реИред рдФрд░ рдЕрдЧрд░ рдкрд╣рд▓реЗ рдорд╛рдорд▓реЗ рдореЗрдВ рд╕рдорд╕реНрдпрд╛ рдХрд╛ рд╕рд╣реА рд╕рдорд╛рдзрд╛рди рдЗрд╕ рдкреГрд╖реНрда рдХреЛ рд▓реЛрдб рдХрд░рдирд╛ рдФрд░ рдХреЙрдкреА рдХрд░рдирд╛ рдЬрд╛рд░реА рд░рдЦрдирд╛ рд╣реИ, рддреЛ рджреВрд╕рд░реЗ рдорд╛рдорд▓реЗ рдореЗрдВ рдСрдкрд░реЗрд╢рди рдХреЛ рдмрд╛рдзрд┐рдд рдХрд░рдирд╛ рдФрд░ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЛ рддреНрд░реБрдЯрд┐ рдХреЛрдб рд╡рд╛рдкрд╕ рдХрд░рдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реИ (рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП,
-EINVAL
)ред
рдЬрд╛рд╣рд┐рд░ рд╣реИ, рдХрдорд╛рдВрдб рдХрд╛ рдирд┐рд╖реНрдкрд╛рджрди рдЬреЛ рд▓рд╛рдкрддрд╛ рдкреГрд╖реНрда рдХреЗ рдЕрдиреБрд░реВрдк рдкрддреЗ рдХреЛ рд╕рдВрдмреЛрдзрд┐рдд рдХрд░рддрд╛ рд╣реИ, рдПрдХ рдЕрдкрд╡рд╛рдж рдХрд╛ рдХрд╛рд░рдг рдмрдирддрд╛ рд╣реИ, рдЕрд░реНрдерд╛рддреН,
рдкреГрд╖реНрда рдХреА рд╡рд┐рдлрд▓рддрд╛ рдпрд╛ рдкреГрд╖реНрда рджреЛрд╖ (
#PF
) рдХрд╛
#PF
ред рдЗрд╕ рд╕рдордп, рдХрд░реНрдиреЗрд▓ рд╡рд░реНрддрдорд╛рди рдХрд╛рд░реНрдп рдХреЗ рд╕рдВрджрд░реНрдн рдХреЛ рд╕рд╣реЗрдЬрддрд╛ рд╣реИ рдФрд░ рд╕рдВрдмрдВрдзрд┐рдд рд╣реИрдВрдбрд▓рд░ рдХреЗ рдХреЛрдб рдХреЛ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рддрд╛ рд╣реИ -
do_page_fault ред рдПрдХ рддрд░реАрдХрд╛ рдпрд╛ рджреВрд╕рд░рд╛, рд╕рдорд╕реНрдпрд╛ рдХреЛ рдареАрдХ рдХрд░рдирд╛, рдХрд░реНрдиреЗрд▓ рдмрд╛рдзрд┐рдд рдХрд╛рд░реНрдп рдХреЗ рд╕рдВрджрд░реНрдн рдХреЛ рдкреБрдирд░реНрд╕реНрдерд╛рдкрд┐рдд рдХрд░рддрд╛ рд╣реИред рд╣рд╛рд▓рд╛рдБрдХрд┐, рдЕрдкрд╡рд╛рдж рдХреЛ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рдиреЗ рдХреЗ рдкрд░рд┐рдгрд╛рдо рдХреЗ рдЖрдзрд╛рд░ рдкрд░, рд╡рд╛рдкрд╕реА рдкрддрд╛ рдЙрд╕ рдирд┐рд░реНрджреЗрд╢ рдХреЗ рдкрддреЗ рд╕реЗ рднрд┐рдиреНрди рд╣реЛ рд╕рдХрддрд╛ рд╣реИ рдЬреЛ рдЕрдкрд╡рд╛рдж рдХрд╛ рдХрд╛рд░рдг рдерд╛ред рджреВрд╕рд░реЗ рд╢рдмреНрджреЛрдВ рдореЗрдВ, рдХрд░реНрдиреЗрд▓ рдореЗрдВ рджрд┐рдП рдЧрдП рддрдВрддреНрд░ рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рдж, рд╕рдВрднрд╛рд╡рд┐рдд "рдЦрддрд░рдирд╛рдХ" рдирд┐рд░реНрджреЗрд╢ рдХреЗ рд▓рд┐рдП рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рдирд╛ рд╕рдВрднрд╡ рд╣реИ, рдЬрд┐рд╕рдореЗрдВ рд╕реЗ рдХрд╛рд░реНрдп рдирд┐рд╖реНрдкрд╛рджрд┐рдд рд╣реЛрдиреЗ рдкрд░ рдЕрдкрд╡рд╛рдж рдХреЛ рдлреЗрдВрдХрдиреЗ рдкрд░ рдЬрд╛рд░реА рд░рд╣реЗрдЧрд╛ред
рдЕрдкрд╡рд╛рдж рд╣реИрдВрдбрд▓рд┐рдВрдЧ рдЗрдВрдЯрд░рдлрд╝реЗрд╕
рдпрд╣ рд╕рдордЭрдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐ рд╕рдВрдХреЗрддрд┐рдд рддрдВрддреНрд░ рдХреИрд╕реЗ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдпрд╣ рдХрд░реНрдиреЗрд▓ рд╕реЗ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЛ 4 рдмрд╛рдЗрдЯреНрд╕ рдХреА рдкреНрд░рддрд┐рд▓рд┐рдкрд┐ рдмрдирд╛рдиреЗ рдХреЗ рдЖрджрд┐рдо рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░рдиреЗ рдХреЗ рд▓рд╛рдпрдХ рд╣реИ -
__put_user_4 рдлрд╝рдВрдХреНрд╢рди:
62 ENTRY(__put_user_4) 63 ENTER 64 mov TI_addr_limit(%_ASM_BX),%_ASM_BX 65 sub $3,%_ASM_BX 66 cmp %_ASM_BX,%_ASM_CX 67 jae bad_put_user 68 ASM_STAC 69 3: movl %eax,(%_ASM_CX) <- 70 xor %eax,%eax 71 EXIT 72 ENDPROC(__put_user_4) ... 89 bad_put_user: 90 CFI_STARTPROC 91 movl $-EFAULT,%eax 92 EXIT ... 98 _ASM_EXTABLE(3b,bad_put_user)
рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ, рдкрддрд╛ рд╢реНрд░реЗрдгреА рдХреА рдЬрд╛рдБрдЪ рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдпрд╣ рдлрд╝рдВрдХреНрд╢рди рд╕реАрдзреЗ рдбреЗрдЯрд╛ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░рддрд╛ рд╣реИ (рд▓рд╛рдЗрди 69 рдкрд░ рдирд┐рд░реНрджреЗрд╢)ред рдпрд╣ рд╡рд╣ рдЬрдЧрд╣ рд╣реИ рдЬрд╣рд╛рдВ рдЕрдкрд╡рд╛рдж рдХреА рдЙрдореНрдореАрдж рдХреА рдЬрд╛ рд╕рдХрддреА рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдЗрд╕ рддрдереНрдп рдХреЗ рдЕрд▓рд╛рд╡рд╛ рдХрд┐ рд▓рдХреНрд╖реНрдп рдкрддрд╛ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдЕрдВрддрд░рд┐рдХреНрд╖ рдкрддреЛрдВ рдХреА рд╢реНрд░реЗрдгреА рд╕реЗ рд╕рдВрдмрдВрдзрд┐рдд рд╣реИ, рдЗрд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЕрдзрд┐рдХ рдХреБрдЫ рдирд╣реАрдВ рдЬрд╛рдирд╛ рдЬрд╛рддрд╛ рд╣реИред рдЕрдЧрд▓рд╛, рдЖрдкрдХреЛ
_ASM_EXTABLE рдореИрдХреНрд░реЛ рдкрд░ рдзреНрдпрд╛рди рджреЗрдирд╛ рдЪрд╛рд╣рд┐рдП, рдЬреЛ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рд╣реИ:
43 # define _ASM_EXTABLE(from,to) \ 44 .pushsection "__ex_table","a" ; \ 45 .balign 8 ; \ 46 .long (from) - . ; \ 47 .long (to) - . ; \ 48 .popsection
рдЗрд╕ рдореИрдХреНрд░реЛ рдХреА рдХреНрд░рд┐рдпрд╛ рджреЛ рдорд╛рдиреЛрдВ рдХреЛ,
from
рдФрд░ рд╡рд┐рд╢реЗрд╖
__ex_table
рд╕реЗрдХреНрд╢рди рдореЗрдВ
__ex_table
, рдЬреЛ рдХрд┐, рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ, рд▓рд╛рдЗрди 69 рдкрд░ "рд╕рдВрджрд┐рдЧреНрдз" рдирд┐рд░реНрджреЗрд╢ рдХреЗ рдкрддреЗ рдХреЗ рдЕрдиреБрд░реВрдк рд╣реИ рдФрд░ рдирд┐рд░реНрджреЗрд╢ рдЬрд┐рд╕рдХреЗ рдЕрдкрд╡рд╛рдж рдХреЗ рдмрд╛рдж рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдЬрд╛рд░реА рд░рд╣реЗрдЧреАред рдЬрд┐рд╕рдХрд╛ рдирд╛рдо
bad_put_user
ред
__ex_table
рд▓рд┐рдП рдПрдХ рдкреНрд░рд╡рд┐рд╖реНрдЯрд┐ рдЬреЛрдбрд╝рдирд╛ рд╡рд┐рдлрд▓рддрд╛ рдХреЗ рдмрд┐рдВрджреБ рдХреЛ рдкреНрд░рдмрдВрдзрдиреАрдп рдмрдирд╛рддрд╛ рд╣реИ рдХреНрдпреЛрдВрдХрд┐ рдЕрдкрд╡рд╛рджреЛрдВ рдХреЛ рд╣реИрдВрдбрд▓ рдХрд░рддреЗ рд╕рдордп рдХрд░реНрдиреЗрд▓ рджреНрд╡рд╛рд░рд╛ рдЗрд╕ рддрд╛рд▓рд┐рдХрд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред
рдЕрдкрд╡рд╛рдж рддрд╛рд▓рд┐рдХрд╛рдУрдВ рдФрд░ рдЙрдирдХреЗ рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг
рдЗрд╕рд▓рд┐рдП, рдЬреИрд╕рд╛ рдХрд┐ рдЙрд▓реНрд▓реЗрдЦ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛, рдЕрдкрд╡рд╛рдж рддрд╛рд▓рд┐рдХрд╛ рдХреЗрдВрджреНрд░реАрдп рд╕реНрдерд╛рди рд╣реИ рдЬрд╣рд╛рдВ рдЙрди рдирд┐рд░реНрджреЗрд╢реЛрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЬрд╛рдирдХрд╛рд░реА рд╕рдВрдЧреНрд░рд╣реАрдд рд╣реИ, рдЬрд┐рд╕рдХреЗ рджреМрд░рд╛рди рддреНрд░реБрдЯрд┐ рдХреЛ рдЕрд▓рдЧ рд╕реЗ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред рдЖрдЧреЗ рджреЗрдЦрддреЗ рд╣реБрдП, рдпрд╣ рдзреНрдпрд╛рди рджреЗрдиреЗ рдпреЛрдЧреНрдп рд╣реИ рдХрд┐ рдХрд░реНрдиреЗрд▓ рдХреА рддрд╛рд▓рд┐рдХрд╛ рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдкреНрд░рддреНрдпреЗрдХ рдореЙрдбреНрдпреВрд▓ рдХреЗ рд▓рд┐рдП рдПрдХ рд╡реНрдпрдХреНрддрд┐рдЧрдд рддрд╛рд▓рд┐рдХрд╛ рднреА рдкреНрд░рджрд╛рди рдХреА рдЬрд╛рддреА рд╣реИред рд╣рд╛рд▓рд╛рдБрдХрд┐, рдЕрдм рдпрд╣ рдЗрд╕рдХреЗ рддрддреНрд╡ рдХреА рд╕рдВрд░рдЪрдирд╛ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░рдиреЗ рдХреЗ рд▓рд╛рдпрдХ рд╣реИ, рдЗрд╕реЗ рдЕрдкрд╡рд╛рдж_
table_entry рд╕рдВрд░рдЪрдирд╛ рджреНрд╡рд╛рд░рд╛ рд╡рд░реНрдгрд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛
рд╣реИ :
97 struct exception_table_entry { 98 int insn, fixup; 99 };
рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ, рддрд╛рд▓рд┐рдХрд╛ рддрддреНрд╡ рдХрд╛ рдкреНрд░рд╛рд░реВрдк рдореИрдХреНрд░реЛ
_ASM_EXTABLE
рдЬрд╛рдВрдЪ рдХрд░рддреЗ рд╕рдордп рд╕рд╛рдордиреЗ рдЖрдпрд╛ рдерд╛ред рдкрд╣рд▓рд╛ рддрддреНрд╡ рдирд┐рд░реНрджреЗрд╢ рдХрд╛ рд╡рд░реНрдгрди рдХрд░рддрд╛ рд╣реИ, рджреВрд╕рд░рд╛ рдЙрд╕ рдХреЛрдб рдХрд╛ рд╡рд░реНрдгрди рдХрд░рддрд╛ рд╣реИ рдЬрд┐рд╕ рдкрд░ рдирд┐рдпрдВрддреНрд░рдг рдЕрдкрд╡рд╛рдж рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред рд╣рд░ рдмрд╛рд░ рдЬрдм рдкреГрд╖реНрда рдХреА рд╡рд┐рдлрд▓рддрд╛ рдЕрдкрд╡рд╛рдж рд╣реЛрддреА рд╣реИ, рддреЛ рд▓рд┐рдирдХреНрд╕ рдХрд░реНрдиреЗрд▓ рдЕрдиреНрдп рдЪреАрдЬреЛрдВ рдХреЗ рд╕рд╛рде рдЬрд╛рдВрдЪрддрд╛ рд╣реИ, рдХрд┐ рдХреНрдпрд╛ рдЗрд╕ рдЕрдкрд╡рд╛рдж рдХреЗ рдХрд╛рд░рдг рдХрдорд╛рдВрдб рдХрд╛ рдкрддрд╛ рдХрд░реНрдиреЗрд▓
__ex_table
рддрд╛рд▓рд┐рдХрд╛ рдореЗрдВ, рдпрд╛ рд▓реЛрдб рдХрд┐рдП рдЧрдП рдореЙрдбреНрдпреВрд▓ рдХреА рдПрдХ рддрд╛рд▓рд┐рдХрд╛
__ex_table
ред рдпрджрд┐ рдРрд╕рд╛ рд░рд┐рдХреЙрд░реНрдб рдкрд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рд╕рдВрдмрдВрдзрд┐рдд рдХрд╛рд░реНрд░рд╡рд╛рдИ рдХреА рдЬрд╛рддреА рд╣реИред рдЕрдиреНрдпрдерд╛, рдХрд░реНрдиреЗрд▓ рдЕрдкрд╡рд╛рдж рдХреЛ рдкреВрд░рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХреБрдЫ рдорд╛рдирдХ рддрд░реНрдХ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рддрд╛ рд╣реИред
рдХрд░реНрдиреЗрд▓ рдореЙрдбреНрдпреВрд▓ рдХреЗ рд╡реНрдпрдХреНрддрд┐рдЧрдд рдЕрдкрд╡рд╛рдж рддрд╛рд▓рд┐рдХрд╛рдУрдВ рдХреЗ рд▓рд┐рдП, рдЗрди рддрд╛рд▓рд┐рдХрд╛рдУрдВ рдХреЗ рддрддреНрд╡реЛрдВ рдХрд╛ рдкреНрд░рд╛рд░реВрдк рдорд╛рдирдХ рд╣реИ рдФрд░ рдХрд░реНрдиреЗрд▓ рдХреЗ рд▓рд┐рдП рд╕рдВрдЧрдд рд╣реИред рдкреНрд░рддреНрдпреЗрдХ рдореЙрдбреНрдпреВрд▓ рдХреЗ рд▓рд┐рдП рдРрд╕реА рддрд╛рд▓рд┐рдХрд╛ рдХрд╛ рд▓рд┐рдВрдХ
THIS_MODULE->extable
рддрд╣рдд рдЙрдкрд▓рдмреНрдз рд╣реИ, рдЬрдмрдХрд┐ рддрд╛рд▓рд┐рдХрд╛ рддрддреНрд╡реЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛
THIS_MODULE->num_exentries
рдореЗрдВ рдирд┐рд╣рд┐рдд рд╣реИред
рд╕реНрд╡рдпрдВ THIS_MODULE рдореИрдХреНрд░реЛ рдореЙрдбреНрдпреВрд▓ рдбрд┐рд╕реНрдХреНрд░рд┐рдкреНрдЯрд░ рд╕рдВрд░рдЪрдирд╛ рдХрд╛ рд▓рд┐рдВрдХ рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИ:
223 struct module 224 { ... 276 277 unsigned int num_exentries; 278 struct exception_table_entry *extable; ... 378 };
рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдПрдХ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдХрд░реНрдиреЗрд▓ рдлрд╝рдВрдХреНрд╢рди рд╣реИ рдЬреЛ рдЙрд╕ рд╣реИрдВрдбрд▓рд░ рдХреА рдЦреЛрдЬ рдХрд░рддрд╛ рд╣реИ рдЬреЛ рдЙрд╕ рдирд┐рд░реНрджреЗрд╢ рд╕реЗ рдореЗрд▓ рдЦрд╛рддрд╛ рд╣реИ рдЬреЛ рдЕрдкрд╡рд╛рдж рдХрд╛ рдХрд╛рд░рдг рдмрдирддрд╛ рд╣реИред рдпрд╣рд╛рдБ рдЙрд╕рдХрд╛
рдХреЛрдб рд╣реИ :
50 51 const struct exception_table_entry *search_exception_tables(unsigned long addr) 52 { 53 const struct exception_table_entry *e; 54 55 e = search_extable(__start___ex_table, __stop___ex_table-1, addr); 56 if (!e) 57 e = search_module_extables(addr); 58 return e; 59 }
рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ, рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рдЦреЛрдЬ
__ex_table
рдХрд░реНрдиреЗрд▓ рдХреЗ рдмреЗрд╕ рдЯреЗрдмрд▓ рдореЗрдВ рдХреА
__ex_table
рдФрд░ рдЙрд╕рдХреЗ рдмрд╛рдж рд╣реА, рдкрд░рд┐рдгрд╛рдо рдХреЗ рдЕрднрд╛рд╡ рдореЗрдВ, рдпрд╣ рдореЙрдбреНрдпреВрд▓ рдЕрдкрд╡рд╛рдж рддрд╛рд▓рд┐рдХрд╛рдУрдВ рдХреЗ рдмреАрдЪ рдЬрд╛рд░реА рд░рд╣рддрд╛ рд╣реИред рдпрджрд┐ рдХреЛрдИ рднреА рд╣реИрдВрдбрд▓рд░ рдирд┐рд░реНрджреЗрд╢ рдкрддреЗ рд╕реЗ рдореЗрд▓ рдирд╣реАрдВ рдЦрд╛рддрд╛ рд╣реИ, рддреЛ рдЗрд╕ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рдХрд░реНрдиреЗрд▓ рдХрд╛ рдкрд░рд┐рдгрд╛рдо
NULL
рд╣реЛрдЧрд╛ред рдЕрдиреНрдпрдерд╛, рдкрд░рд┐рдгрд╛рдо рдЕрдкрд╡рд╛рдж рддрд╛рд▓рд┐рдХрд╛ рдХреЗ рд╕рдВрдмрдВрдзрд┐рдд рддрддреНрд╡ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕рдВрдХреЗрддрдХ рд╣реЛрдЧрд╛ред
рдХрд░реНрдиреЗрд▓ рдореЙрдбреНрдпреВрд▓ рдореЗрдВ рдЕрдкрд╡рд╛рдж рд╣реИрдВрдбрд▓рд┐рдВрдЧ
рдЗрд╕рд▓рд┐рдП, рдпрджрд┐ рдЕрдкрд╡рд╛рджреЛрдВ рдХреЛ рд╕рдВрднрд╛рд▓рдиреЗ рдХреА рд╕рд╛рдорд╛рдиреНрдп рдкреНрд░рдХреНрд░рд┐рдпрд╛ рд╕реНрдкрд╖реНрдЯ рд╣реИ, рддреЛ рдкреНрд░рд╢рд┐рдХреНрд╖рдг рдХреЗ рд▓рд┐рдП рдЖрдк рдПрдХ рдореЙрдбреНрдпреВрд▓ рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВ рдЬрд┐рд╕рдХрд╛ рдЙрджреНрджреЗрд╢реНрдп рдЕрдкрд╡рд╛рдж рдмрдирд╛рдирд╛ рдФрд░ рдЙрдиреНрд╣реЗрдВ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рдирд╛ рд╣реИред рдореЗрд░реЗ рджреНрд╡рд╛рд░рд╛ рдкрд╣рд▓реЗ рд╣реА
рд▓рд┐рдЦрд╛ рдЧрдпрд╛ рдХреЛрдб
рдЬреАрдердм рдкрд░ рдЙрдкрд▓рдмреНрдз рд╣реИред рдЖрдЧреЗ рдореИрдВ рдХреЛрдб рдХрд╛ рд╕рдВрдХреНрд╖рд┐рдкреНрдд рд╡рд┐рд╡рд░рдг рджреВрдВрдЧрд╛ рдФрд░ рдХреБрдЫ рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдВ рджреВрдВрдЧрд╛ред
рддреЛ, рдкреЗрдЬрдлреЙрд▓реНрдЯ рдЕрдкрд╡рд╛рджреЛрдВ рдХреА рдкреАрдврд╝реА рдХреЗ рд╕рд╛рде рдирд┐рдпрдорд┐рдд NULL рдкреЙрдЗрдВрдЯрд░ рдбрд┐рдлрд░реЗрдВрд╕ рдбреАрд▓ рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рджреЗрдВ:
static void raise_page_fault(void) { debug(" %s enter\n", __func__); ((int *)0)[0] = 0xdeadbeef; debug(" %s leave\n", __func__); }
рдЬрд╛рд╣рд┐рд░ рд╣реИ, рдЕрд╢рдХреНрдд рд╕реВрдЪрдХ рдХреЛ рд▓рд┐рдЦрдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рд╕реЗ рджреБрд░реНрдШрдЯрдирд╛ рд╣реЛ рд╕рдХрддреА рд╣реИред рдФрд░ рдпрд╣ рд╡рд╣реА рд╣реИ рдЬреЛ рдЖрдкрдХреЛ рдЪрд╛рд╣рд┐рдПред рдареАрдХ рд╕реЗ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рджреЗрдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ рдпрд╣ рдХрд░рдирд╛ рд╣реЛрдЧрд╛:
- рдЕрдкрд╡рд╛рдж рдХреЗ рдХрд╛рд░рдг рдирд┐рд░реНрджреЗрд╢ рдХрд╛ рдкрддрд╛ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░реЗрдВ
- рдПрдХ рдорд╛рдиреНрдп рддрддреНрд╡
exception_table_entry
______ рдмрдирд╛рдПрдБ - рдореЙрдбреНрдпреВрд▓ рдХреА
extable
рддрд╛рд▓рд┐рдХрд╛ рдореЗрдВ рдмрдирд╛рдпрд╛ рдЧрдпрд╛ рддрддреНрд╡ рдЬреЛрдбрд╝реЗрдВ
рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдПрдХ рдРрд╕рд╛ рдХрд╛рд░реНрдп рд╣реИ рдЬреЛ
udis86 рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ disassembly рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЙрдкрд░реЛрдХреНрдд рдХреНрд░рд┐рдпрд╛рдПрдВ рдХрд░рддрд╛ рд╣реИ:
static int fixup_page_fault(struct exception_table_entry * entry) { ud_t ud; ud_initialize(&ud, BITS_PER_LONG, \ UD_VENDOR_ANY, (void *)raise_page_fault, 128); while (ud_disassemble(&ud) && ud.mnemonic != UD_Iret) { if (ud.mnemonic == UD_Imov && \ ud.operand[0].type == UD_OP_MEM && ud.operand[1].type == UD_OP_IMM) { unsigned long address = \ (unsigned long)raise_page_fault + ud_insn_off(&ud); extable_make_insn(entry, address); extable_make_fixup(entry, address + ud_insn_len(&ud)); return 0; } } return -EINVAL; }
рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ, рдкрд╣рд▓рд╛ рдХрджрдо
raise_page_fault
рдХреЛ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд░рдирд╛ рд╣реИ (рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХреА рд╢реБрд░реБрдЖрдд рд╣реИ
raise_page_fault
)ред рдЕрдЧрд▓рд╛, рджреА рдЧрдИ рдЦреЛрдЬ рдЧрд╣рд░рд╛рдИ рдХреЗ рд╕рд╛рде, рдХрдорд╛рдВрдбреНрд╕ рдкрд░ рдкреБрдирд░рд╛рд╡реГрддрд┐ред рд╡рд╛рдВрдЫрд┐рдд рдХрдорд╛рдВрдб (рдХреНрдпрд╛ рдСрдкрд░реЗрд╢рди рдХрд╛ рдЕрдиреБрд╡рд╛рдж рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ
((int *)0)[0] = 0xdeadbeef;
) рдПрдХ рдирд┐рдпрдорд┐рдд
movl $0xdeadbeef, 0
рдкреНрд░рдХрд╛рд░ рдХреЗ рдкрд╣рд▓реЗ рдСрдкрд░реЗрдВрдб рдХреЗ рд╕рд╛рде
UD_OP_MEM
рдФрд░ рджреВрд╕рд░рд╛ рдкреНрд░рдХрд╛рд░
UD_OP_IMM
ред рдЬреИрд╕реЗ рд╣реА рдХрдорд╛рдВрдб рдПрдбреНрд░реЗрд╕ рдорд┐рд▓рддрд╛ рд╣реИ, рдЯреЗрдмрд▓ рдПрд▓рд┐рдореЗрдВрдЯ рдмрдирддрд╛ рд╣реИред рдЙрд╕реА рд╕рдордп, рдХрд╛рд░реНрдп рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВ:
static void extable_make_insn(struct exception_table_entry * entry, unsigned long addr) { #if LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0) entry->insn = (unsigned int)((addr - (unsigned long)&entry->insn)); #else entry->insn = addr; #endif } static void extable_make_fixup(struct exception_table_entry * entry, unsigned long addr) { #if LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0) entry->fixup = (unsigned int)((addr - (unsigned long)&entry->fixup)); #else entry->fixup = addr; #endif }
рдЙрдирдореЗрдВ рд╕реЗ рдкрд╣рд▓рд╛ рд╕рдВрд░рдЪрдирд╛ рдореЗрдВ рдирд┐рд░реНрджреЗрд╢ рдХрд╛ рдкрддрд╛ рдмрдирд╛рддрд╛ рд╣реИред рджреВрд╕рд░рд╛ рд╣реИ рдлрд┐рдХреНрд╕ рдПрдбреНрд░реЗрд╕, рдпрд╛рдиреА рдХрдорд╛рдВрдб рдЬрд┐рд╕ рдкрд░ рдирд┐рдпрдВрддреНрд░рдг рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред рдпрд╣ рдзреНрдпрд╛рди рд░рдЦрдирд╛ рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╣реИ рдХрд┐ рдХрд░реНрдиреЗрд▓ 3.5 рдХреЗ рд╕рд╛рде рд╢реБрд░реВ рд╣реЛрдиреЗ рдкрд░,
insn
рд╕рдВрд░рдЪрдирд╛ рдореЗрдВ рдорд╛рдореВрд▓реА рдкрд░рд┐рд╡рд░реНрддрди рд╣реБрдП рд╣реИрдВ, рдЕрд░реНрдерд╛рддреН, рдЗрд╕рдХреЗ рдХреНрд╖реЗрддреНрд░реЛрдВ рдХрд╛ рдЖрдпрд╛рдо рдХрдо рдХрд░ рджрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ - 64-рдмрд┐рдЯ рдЖрд░реНрдХрд┐рдЯреЗрдХреНрдЪрд░ рдХреЗ рд▓рд┐рдП
insn
рдФрд░
fixup
ред рдЗрд╕рдиреЗ рд╣рдореЗрдВ рдкрддреЛрдВ рдХреЛ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХ рдореЗрдореЛрд░реА рдХреЛ рдХрдо рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреА, рд▓реЗрдХрд┐рди рдЧрдгрдирд╛ рддрд░реНрдХ рдереЛрдбрд╝рд╛ рдмрджрд▓ рдЧрдпрд╛ред рддреЛ, рдХрд░реНрдиреЗрд▓ 3.5 рдХреЗ рдмрд╛рдж, рдЗрди рддрддреНрд╡реЛрдВ рдХреЗ рд╕рд╛рдкреЗрдХреНрд╖ рдСрдлрд╕реЗрдЯ рдХреЛ рд╕рдВрдмреЛрдзрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП
insn
рдФрд░
fixup
32-рдмрд┐рдЯ рдорд╛рдиреЛрдВ рдХреЛ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░рддреЗ рд╣реИрдВред рдЙрди рд▓реЛрдЧреЛрдВ рдХреЗ рд▓рд┐рдП рдЬреЛ рдПрдХ рдХрдорд┐рдЯ рд▓рд╛рдиреЗ рдореЗрдВ рджрд┐рд▓рдЪрд╕реНрдкреА рд░рдЦрддреЗ рд╣реИрдВ рдЬрд┐рдиреНрд╣реЛрдВрдиреЗ
706276543b699d80f546e45f8b12574e7b18d952 рдХреЛ рдмрд░реНрдмрд╛рдж рдХрд░ рджрд┐рдпрд╛ ред
рдирд┐рд╖реНрдХрд░реНрд╖
рдпрд╣ рдЙрджрд╛рд╣рд░рдг рдХрд░реНрдиреЗрд▓ рдореЙрдбреНрдпреВрд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд▓рд┐рдирдХреНрд╕ рдХрд░реНрдиреЗрд▓ рдореЗрдВ рдЕрдкрд╡рд╛рдж рд╣реИрдВрдбрд▓рд┐рдВрдЧ рдХреЛ рдкреНрд░рдмрдВрдзрд┐рдд рдХрд░рдиреЗ рдХреА рдХреНрд╖рдорддрд╛ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рддрд╛ рд╣реИред рдкрд░реАрдХреНрд╖рдг рдХреЗ рдЙрджрд╛рд╣рд░рдг рдореЗрдВ, рдПрдХ рдЕрдкрд╡рд╛рдж (рдкреЗрдЬрдлреЙрд▓реНрдЯ) рдХреЛ рдкреВрд░реНрд╡-рддреИрдпрд╛рд░ рд╡рд╛рддрд╛рд╡рд░рдг рдореЗрдВ рдХрд╣рд╛ рдЧрдпрд╛ рдерд╛, рдЕрд░реНрдерд╛рддреН, рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд┐рдП рдЧрдП рдореЙрдбреНрдпреВрд▓ рддрд╛рд▓рд┐рдХрд╛ рдХреЛ
exables
рд╣реИред рдмрд╛рдж рдХреА рдкрд░рд┐рд╕реНрдерд┐рддрд┐ рдиреЗ рдЕрд╕рд╛рдорд╛рдиреНрдп рд╕рдорд╛рдкреНрддрд┐ рдХреЛ рд╕рдорд╛рдкреНрдд рдХрд░рдирд╛ рдФрд░ рдЖрдкрд╛рддрдХрд╛рд▓реАрди рдирд┐рд░реНрджреЗрд╢ рдХрд╛ рдкрд╛рд▓рди рдХрд░рддреЗ рд╣реБрдП рдХрдорд╛рдВрдб рдХреЗ рд╕рд╛рде рдХрд╛рд░реНрдпрдХреНрд░рдо рдХрд╛ рдирд┐рд╖реНрдкрд╛рджрди рдЬрд╛рд░реА рд░рдЦрдирд╛ рд╕рдВрднрд╡ рдХрд░ рджрд┐рдпрд╛ред
рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рддреИрдпрд╛рд░ рдХрд┐рдП рдЧрдП
рдкрд░реАрдХреНрд╖рдг рдорд╛рдорд▓реЗ рд╕реЗ рд╣рдореЗрдВ рдХреБрдЫ рдЕрдиреНрдп рдЕрдкрд╡рд╛рджреЛрдВ рдХреЛ рд╕рдВрднрд╛рд▓рдиреЗ рдХреА рд╕рдВрднрд╛рд╡рдирд╛ рдХрд╛ рдореВрд▓реНрдпрд╛рдВрдХрди рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рдорд┐рд▓рддреА рд╣реИ, рдЬреИрд╕реЗ рдХрд┐
рд╡рд┐рднрд╛рдЬрди рддреНрд░реБрдЯрд┐ (#DE) рдФрд░
рдЕрдкрд░рд┐рднрд╛рд╖рд┐рдд opcode (#UD):
struct { const char * name; int (* fixup)(struct exception_table_entry *); void (* raise)(void); } exceptions[] = { { .name = "0x00 - div0 error (#DE)", .fixup = fixup_div0_error, .raise = raise_div0_error, }, { .name = "0x06 - undefined opcode (#UD)", .fixup = fixup_undefined_opcode, .raise = raise_undefined_opcode, }, { .name = "0x14 - page fault (#PF)", .fixup = fixup_page_fault, .raise = raise_page_fault, }, };