рдЬрд┐рди рд▓реЛрдЧреЛрдВ рдХреЛ рдХрдо рд╕реЗ рдХрдо рдПрдХ рдмрд╛рд░ рдлрд╝реНрд▓рд╛рдИрд╣реИрдВрдб рдкрд░ рдХрд░реНрдиреЗрд▓ рдореЗрдВ рдХреБрдЫ рдмрджрд▓рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдХрд╛ рд╕рд╛рдордирд╛ рдХрд░рдирд╛ рдкрдбрд╝рд╛, рд╡реЗ рдЬрд╛рдирддреЗ рд╣реИрдВ рдХрд┐ рдЗрд╕ рдореБрджреНрджреЗ рдкрд░ рд╡рд┐рд╕реНрддреГрдд рдЕрдзреНрдпрдпрди рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдХрд░реНрдиреЗрд▓ рдореЗрдореЛрд░реА рдкреЗрдЬ рдЬреЛ рд╕реНрдЯреЛрд░ рдХреЛрдб рдФрд░ рдХреБрдЫ рдбреЗрдЯрд╛ рдХреЛ рдХреЗрд╡рд▓-рдкрдврд╝рдиреЗ рдХреЗ рд░реВрдк рдореЗрдВ рдЪрд┐рд╣реНрдирд┐рдд рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рд╕рдВрд░рдХреНрд╖рд┐рдд рд▓рд┐рдЦреЗ рдЬрд╛рддреЗ рд╣реИрдВ!
X86 рдХреЗ рд▓рд┐рдП, рдПрдХ рдкреНрд░рд╕рд┐рджреНрдз рд╕рдорд╛рдзрд╛рди рд░рдЬрд┐рд╕реНрдЯрд░ CR0 рдХреЗ WP рдмрд┐рдЯ рдХреЛ рд░реАрд╕реЗрдЯ рдХрд░рдХреЗ рдЕрд╕реНрдерд╛рдпреА рд░реВрдк рд╕реЗ рдкреГрд╖реНрда рд╕реБрд░рдХреНрд╖рд╛ рдХреЛ рдЕрдХреНрд╖рдо рдХрд░рдирд╛ рд╣реИред рд▓реЗрдХрд┐рди рдЖрдкрдХреЛ рд╕рд╛рд╡рдзрд╛рдиреА рдХреЗ рд╕рд╛рде рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП, рдХреНрдпреЛрдВрдХрд┐ рдкреГрд╖реНрда рд╕рдВрд░рдХреНрд╖рдг рдХрдИ рдХрд░реНрдиреЗрд▓ рддрдВрддреНрд░реЛрдВ рдХрд╛ рдЖрдзрд╛рд░ рд╣реИред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдПрд╕рдПрдордкреА-рд╕рд┐рд╕реНрдЯрдо рдкрд░ рдХрд╛рдо рдХреА рд╕реБрд╡рд┐рдзрд╛рдУрдВ рдХреЛ рдзреНрдпрд╛рди рдореЗрдВ рд░рдЦрдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реИ, рдЬрдм рд╡рд┐рднрд┐рдиреНрди рдЕрдкреНрд░рд┐рдп рдкрд░рд┐рд╕реНрдерд┐рддрд┐рдпрд╛рдВ рд╣реЛ рд╕рдХрддреА рд╣реИрдВред
рдкреГрд╖реНрда рд╕реБрд░рдХреНрд╖рд╛ рдмрдВрдж рдХрд░реЗрдВ
X86 рдЖрд░реНрдХрд┐рдЯреЗрдХреНрдЪрд░ рдореЗрдВ рдПрдХ рд╡рд┐рд╢реЗрд╖ рд░рдХреНрд╖рд╛ рддрдВрддреНрд░ рд╣реИ, рдЬрд┐рд╕рдХреЗ рдЕрдиреБрд╕рд╛рд░ рд▓рд┐рдЦрдиреЗ рдХреЗ рд▓рд┐рдП рдореЗрдореЛрд░реА-рд╕рдВрд░рдХреНрд╖рд┐рдд рдХреНрд╖реЗрддреНрд░реЛрдВ рдХреЛ рд▓рд┐рдЦрдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдЕрдкрд╡рд╛рдж рдмрди рд╕рдХрддрд╛ рд╣реИред рдЗрд╕ рддрдВрддреНрд░ рдХреЛ "рдкреГрд╖реНрда рд░рдХреНрд╖рд╛" рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ рдФрд░ рдпрд╣ рдХрдИ рдХрд░реНрдиреЗрд▓ рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХрд╛ рдЖрдзрд╛рд░ рд╣реИ, рдЬреИрд╕реЗ рдХрд┐, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП,
рдЧрд╛рдп ред рдЗрд╕ рд╕реНрдерд┐рддрд┐ рдореЗрдВ рдкреНрд░реЛрд╕реЗрд╕рд░ рдХрд╛ рд╡реНрдпрд╡рд╣рд╛рд░ CR0 рд░рдЬрд┐рд╕реНрдЯрд░ рдХреЗ WP рдмрд┐рдЯ рджреНрд╡рд╛рд░рд╛ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдФрд░ рдкреГрд╖реНрда рдХреЗ рдПрдХреНрд╕реЗрд╕ рдЕрдзрд┐рдХрд╛рд░ рдЗрд╕рдХреЗ рд╕рдВрдмрдВрдзрд┐рдд PTE рд╡рд┐рд╡рд░рдгрдХ рд╕рдВрд░рдЪрдирд╛ рдореЗрдВ рд╡рд░реНрдгрд┐рдд рд╣реИрдВред рдЬрдм рд░рдЬрд┐рд╕реНрдЯрд░ CR0 рдХрд╛ WP рдмрд┐рдЯ рд╕реЗрдЯ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рдкреНрд░реЛрд╕реЗрд╕рд░ рджреНрд╡рд╛рд░рд╛ рд╕рдВрдмрдВрдзрд┐рдд рдЕрдкрд╡рд╛рдж (#GP) рдХреА рдкреАрдврд╝реА рдХреЗ рд▓рд┐рдП рд░рд╛рдЗрдЯ-рдкреНрд░реЛрдЯреЗрдХреНрдЯреЗрдб рдкреЗрдЬ (PTE рдореЗрдВ RW рдмрд┐рдЯ рд░реАрд╕реЗрдЯ рд╣реЛрддрд╛ рд╣реИ) рдХреЛ рд▓рд┐рдЦрдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рд╣реЛрддрд╛ рд╣реИред
рдЗрд╕ рд╕рдорд╕реНрдпрд╛ рдХрд╛ рд╕рдмрд╕реЗ рд╕рд░рд▓ рд╕рдорд╛рдзрд╛рди CR0 рд░рдЬрд┐рд╕реНрдЯрд░ рдХреЗ WP рдмрд┐рдЯ рдХреЛ рд░реАрд╕реЗрдЯ рдХрд░рдХреЗ рдЕрд╕реНрдерд╛рдпреА рд░реВрдк рд╕реЗ рдкреГрд╖реНрда рд╕реБрд░рдХреНрд╖рд╛ рдХреЛ рдЕрдХреНрд╖рдо рдХрд░рдирд╛ рд╣реИред рдЗрд╕ рд╕рдорд╛рдзрд╛рди рдореЗрдВ рдПрдХ рдЬрдЧрд╣ рд╣реИ, рд▓реЗрдХрд┐рди рдЗрд╕реЗ рд╕рд╛рд╡рдзрд╛рдиреА рд╕реЗ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП, рдХреНрдпреЛрдВрдХрд┐, рдЬреИрд╕рд╛ рдХрд┐ рдиреЛрдЯ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рдкреГрд╖реНрда рддрдВрддреНрд░ рдХрдИ рдореБрдЦреНрдп рддрдВрддреНрд░реЛрдВ рдХрд╛ рдЖрдзрд╛рд░ рд╣реИред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдПрд╕рдПрдордкреА рд╕рд┐рд╕реНрдЯрдо рдкрд░, рдкреНрд░реЛрд╕реЗрд╕рд░ рдореЗрдВ рд╕реЗ рдПрдХ рдкрд░ рдЪрд▓ рд░рд╣рд╛ рдПрдХ рдзрд╛рдЧрд╛ рдФрд░ WP рдмрд┐рдЯ рдХреЛ рд╣рдЯрд╛рдиреЗ рд╕реЗ рдмрд╛рдзрд┐рдд рд╣реЛ рд╕рдХрддрд╛ рд╣реИ рдФрд░ рджреВрд╕рд░реЗ рдкреНрд░реЛрд╕реЗрд╕рд░ рдореЗрдВ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рд╣реЛ рд╕рдХрддрд╛ рд╣реИ!
рдлрд┐рд░ рднреА, рдпрджрд┐ рдЖрдк рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рддреЛ рдЖрдкрдХреЛ
рдкреВрд░реНрд╡рдирд┐рд░реНрдзрд╛рд░рдг рдХреЛ рдЕрдХреНрд╖рдо рдХрд░рдХреЗ рдРрд╕рд╛ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛
рд╣реИ :
static inline unsigned long native_pax_open_kernel(void) { unsigned long cr0; preempt_disable(); barrier(); cr0 = read_cr0() ^ X86_CR0_WP; BUG_ON(unlikely(cr0 & X86_CR0_WP)); write_cr0(cr0); return cr0 ^ X86_CR0_WP; } static inline unsigned long native_pax_close_kernel(void) { unsigned long cr0; cr0 = read_cr0() ^ X86_CR0_WP; BUG_ON(unlikely(!(cr0 & X86_CR0_WP))); write_cr0(cr0); barrier(); preempt_enable_no_resched(); return cr0 ^ X86_CR0_WP; }
рдореИрдкрд┐рдВрдЧ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛
рдПрдХ рдмреЗрд╣рддрд░ рдФрд░ рдкрд░реНрдпрд╛рдкреНрдд рд░реВрдк рд╕реЗ рд╕рд╛рд░реНрд╡рднреМрдорд┐рдХ рдЕрд╕реНрдерд╛рдпреА рдкреНрд░рджрд░реНрд╢рди рдмрдирд╛рдиреЗ рдХрд╛ рддрд░реАрдХрд╛ рд╣реИред рдПрдордПрдордпреВ рдХреА рдмрд╛рд░реАрдХрд┐рдпреЛрдВ рдХреЗ рдХрд╛рд░рдг, рдкреНрд░рддреНрдпреЗрдХ рднреМрддрд┐рдХ рдореЗрдореЛрд░реА рдлреНрд░реЗрдо рдХреЗ рд▓рд┐рдП, рдХрдИ рдбрд┐рд╕реНрдХреНрд░рд┐рдкреНрдЯрд░ рдмрдирд╛рдП рдЬрд╛ рд╕рдХрддреЗ рд╣реИрдВ рдЬрд┐рдирдХреА рдЕрд▓рдЧ-рдЕрд▓рдЧ рд╡рд┐рд╢реЗрд╖рддрд╛рдПрдБ рд╣реЛрддреА рд╣реИрдВред рдпрд╣ рдЖрдкрдХреЛ рд▓рдХреНрд╖реНрдп рдореЗрдореЛрд░реА рдХреНрд╖реЗрддреНрд░ рдХреЗ рд▓рд┐рдП рдПрдХ рд▓реЗрдЦрди рдпреЛрдЧреНрдп рдкреНрд░рджрд░реНрд╢рди рдмрдирд╛рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред рдЗрд╕ рд╡рд┐рдзрд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ
рдХреЗрд╕реНрдкреНрд▓рд┐рд╕ рдкрд░рд┐рдпреЛрдЬрдирд╛ (
рдЬреАрдердм рдкрд░
рдХрд╛рдВрдЯрд╛ ) рдореЗрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдиреАрдЪреЗ
Map_writable рдлрд╝рдВрдХреНрд╢рди рд╣реИ, рдЬреЛ рдЗрд╕ рддрд░рд╣ рдХрд╛ рдирдХреНрд╢рд╛ рдмрдирд╛рддрд╛ рд╣реИ:
static void *map_writable(void *addr, size_t len) { void *vaddr; int nr_pages = DIV_ROUND_UP(offset_in_page(addr) + len, PAGE_SIZE); struct page **pages = kmalloc(nr_pages * sizeof(*pages), GFP_KERNEL); void *page_addr = (void *)((unsigned long)addr & PAGE_MASK); int i; if (pages == NULL) return NULL; for (i = 0; i < nr_pages; i++) { if (__module_address((unsigned long)page_addr) == NULL) { pages[i] = virt_to_page(page_addr); WARN_ON(!PageReserved(pages[i])); } else { pages[i] = vmalloc_to_page(page_addr); } if (pages[i] == NULL) { kfree(pages); return NULL; } page_addr += PAGE_SIZE; } vaddr = vmap(pages, nr_pages, VM_MAP, PAGE_KERNEL); kfree(pages); if (vaddr == NULL) return NULL; return vaddr + offset_in_page(addr); }
рдЗрд╕ рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рд╕реЗ рдЖрдк рдХрд┐рд╕реА рднреА рдореЗрдореЛрд░реА рдХреНрд╖реЗрддреНрд░ рдХреЗ рд▓рд┐рдП рдПрдХ рд▓рд┐рдЦрдиреЗ рдпреЛрдЧреНрдп рдкреНрд░рджрд░реНрд╢рди рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВред рдЗрд╕ рддрд░рд╣ рд╕реЗ рдмрдирд╛рдпрд╛ рдЧрдпрд╛ рдХреНрд╖реЗрддреНрд░
vfree рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЬрд╛рд░реА рдХрд┐рдпрд╛
рдЬрд╛рддрд╛ рд╣реИ, рдЬрд┐рд╕рдХрд╛ рддрд░реНрдХ рдкреГрд╖реНрда рд╕реАрдорд╛ рд╕реЗ рдЬреБрдбрд╝рд╛ рдкрддрд╛ рдорд╛рди рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред
рдЧрд╛рдбрд╝реА рд░реЛрдХреЛ!
рдХрд░реНрдиреЗрд▓ рдХреЛрдб рд╕рдВрд╢реЛрдзрди рдХреЛ рд╕реБрд░рдХреНрд╖рд┐рдд рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдЕрдВрддрд┐рдо рддрддреНрд╡
stop_machine рддрдВрддреНрд░ рд╣реИ:
#include <linux/stop_machine.h> int stop_machine(int (*fn)(void *), void *data, const struct cpumask *cpus)
рд▓рдмреНрдмреЛрд▓реБрдЖрдм рдпрд╣ рд╣реИ рдХрд┐
stop_machine
рдирд┐рд╖реНрдкрд╛рджрди рдХреЗ рд╕рдордп рд╕рдХреНрд░рд┐рдп рдкреНрд░реЛрд╕реЗрд╕рд░ рдХреЗ рджрд┐рдП рдЧрдП рд╕реЗрдЯ рдХреЗ рд╕рд╛рде
fn
рдлрд╝рдВрдХреНрд╢рди рдХрд░рддрд╛ рд╣реИ, рдЬреЛ рд╕рдВрдмрдВрдзрд┐рдд
cpumask
рдорд╛рд╕реНрдХ рджреНрд╡рд╛рд░рд╛ рд╕реЗрдЯ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред рдпрд╣ рд╡рд╣ рд╣реИ рдЬреЛ рд╣рдореЗрдВ рдХрд░реНрдиреЗрд▓ рдХреЛрдб рдХреЛ рд╕рдВрд╢реЛрдзрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЗрд╕ рддрдВрддреНрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдЙрдкрдпреБрдХреНрдд рдорд╛рд╕реНрдХ рд╕реЗрдЯ рдХрд░рдирд╛ рдЙрди рдХрд░реНрдиреЗрд▓ рдереНрд░реЗрдб рдХреЛ рдЯреНрд░реИрдХ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдХреЛ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд░реВрдк рд╕реЗ рд╕рдорд╛рдкреНрдд рдХрд░ рджреЗрддрд╛ рд╣реИ рдЬрд┐рдирдХреЗ рдирд┐рд╖реНрдкрд╛рджрди рд╕рдВрд╢реЛрдзрд┐рдд рдХреЛрдб рдХреЛ рдкреНрд░рднрд╛рд╡рд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред
stop_machine
рдХреА рд╕реАрдорд╛рдУрдВ рдореЗрдВ рд╕реЗ
stop_machine
рдпрд╣ рдзреНрдпрд╛рди рджреЗрдиреЗ рдпреЛрдЧреНрдп рд╣реИ рдХрд┐ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдкрд░рдорд╛рдгреБ рд╕рдВрджрд░реНрдн рдореЗрдВ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП, рдЬреЛ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд░реВрдк рд╕реЗ
vmap рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдЕрд╕реНрдерд╛рдпреА рдбрд┐рд╕реНрдкреНрд▓реЗ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдкрд╣рд▓реЗ рд╕реЗ рдЪрд░реНрдЪрд╛ рдХрд┐рдП рдЧрдП рддрдВрддреНрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреА рд╕рдВрднрд╛рд╡рдирд╛ рдХреЛ рдмрд╛рд╣рд░ рдХрд░рддрд╛ рд╣реИред рд╣рд╛рд▓рд╛рдВрдХрд┐, рдпрд╣ рддрдереНрдп рдорд╣рддреНрд╡рдкреВрд░реНрдг рдирд╣реАрдВ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐
stop_machine
рдХреЙрд▓ рдХрд░рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рдЖрд╡рд╢реНрдпрдХ рдореИрдкрд┐рдВрдЧ рддреИрдпрд╛рд░ рдХреА рдЬрд╛ рд╕рдХрддреА рд╣реИред