Date: Wed, 21 Mar 2018 01:29:55 +0100 From: Oliver Pinter <oliver.pinter@hardenedbsd.org> To: Konstantin Belousov <kib@freebsd.org> Cc: "src-committers@freebsd.org" <src-committers@freebsd.org>, "svn-src-all@freebsd.org" <svn-src-all@freebsd.org>, "svn-src-head@freebsd.org" <svn-src-head@freebsd.org> Subject: Re: svn commit: r331252 - in head/sys/amd64: amd64 include Message-ID: <CAPQ4ffuoshDEN8cNqPZ5sv_v6AGPfi%2BjDRdpfgeTvP4ofpxLTw@mail.gmail.com> In-Reply-To: <201803201743.w2KHhoF9055658@repo.freebsd.org> References: <201803201743.w2KHhoF9055658@repo.freebsd.org>
next in thread | previous in thread | raw e-mail | index | archive | help
On Tuesday, March 20, 2018, Konstantin Belousov <kib@freebsd.org> wrote: > Author: kib > Date: Tue Mar 20 17:43:50 2018 > New Revision: 331252 > URL: https://svnweb.freebsd.org/changeset/base/331252 > > Log: > Provide KPI for handling of rw/ro kernel text. > > This is a pure syntax patch to create an interface to enable and later > restore write access to the kernel text and other read-only mapped > regions. It is in line with e.g. vm_fault_disable_pagefaults() by > allowing the nesting. > > Discussed with: Peter Lei <peter.lei@ieee.org> > Reviewed by: jtl > Sponsored by: The FreeBSD Foundation > MFC after: 1 week > Differential revision: https://reviews.freebsd.org/D14768 > > Modified: > head/sys/amd64/amd64/db_interface.c > head/sys/amd64/amd64/gdb_machdep.c > head/sys/amd64/amd64/machdep.c > head/sys/amd64/include/md_var.h > > Modified: head/sys/amd64/amd64/db_interface.c > ============================================================ > ================== > --- head/sys/amd64/amd64/db_interface.c Tue Mar 20 17:41:54 2018 > (r331251) > +++ head/sys/amd64/amd64/db_interface.c Tue Mar 20 17:43:50 2018 > (r331252) > @@ -37,6 +37,7 @@ __FBSDID("$FreeBSD$"); > #include <sys/pcpu.h> > > #include <machine/cpufunc.h> > +#include <machine/md_var.h> > #include <machine/specialreg.h> > > #include <ddb/ddb.h> > @@ -75,19 +76,19 @@ db_write_bytes(vm_offset_t addr, size_t size, char *da > jmp_buf jb; > void *prev_jb; > char *dst; > - u_long cr0save; > + bool old_wp; > int ret; > > - cr0save = rcr0(); > + old_wp = false; This line should be old_wp = (rcr0() & CR0_WP) ? true : false; to preserve the old behavior in ret != 0 case. > prev_jb = kdb_jmpbuf(jb); > ret = setjmp(jb); > if (ret == 0) { > - load_cr0(cr0save & ~CR0_WP); > + old_wp = disable_wp(); > dst = (char *)addr; > while (size-- > 0) > *dst++ = *data++; > } > - load_cr0(cr0save); > + restore_wp(old_wp); > (void)kdb_jmpbuf(prev_jb); > return (ret); > } > > Modified: head/sys/amd64/amd64/gdb_machdep.c > ============================================================ > ================== > --- head/sys/amd64/amd64/gdb_machdep.c Tue Mar 20 17:41:54 2018 > (r331251) > +++ head/sys/amd64/amd64/gdb_machdep.c Tue Mar 20 17:43:50 2018 > (r331252) > @@ -39,6 +39,7 @@ __FBSDID("$FreeBSD$"); > #include <machine/cpufunc.h> > #include <machine/frame.h> > #include <machine/gdb_machdep.h> > +#include <machine/md_var.h> > #include <machine/pcb.h> > #include <machine/psl.h> > #include <machine/reg.h> > @@ -127,17 +128,14 @@ gdb_cpu_signal(int type, int code) > void * > gdb_begin_write(void) > { > - u_long cr0save; > > - cr0save = rcr0(); > - load_cr0(cr0save & ~CR0_WP); > - return ((void *)cr0save); > + return (disable_wp() ? &gdb_begin_write : NULL); > } > > void > gdb_end_write(void *arg) > { > > - load_cr0((u_long)arg); > + restore_wp(arg != NULL); > } > > > Modified: head/sys/amd64/amd64/machdep.c > ============================================================ > ================== > --- head/sys/amd64/amd64/machdep.c Tue Mar 20 17:41:54 2018 > (r331251) > +++ head/sys/amd64/amd64/machdep.c Tue Mar 20 17:43:50 2018 > (r331252) > @@ -2597,6 +2597,31 @@ clear_pcb_flags(struct pcb *pcb, const u_int flags) > : "cc", "memory"); > } > > +/* > + * Enable and restore kernel text write permissions. > + * Callers must ensure that disable_wp()/restore_wp() are executed > + * without rescheduling on the same core. > + */ > +bool > +disable_wp(void) > +{ > + u_int cr0; > + > + cr0 = rcr0(); > + if ((cr0 & CR0_WP) == 0) > + return (false); > + load_cr0(cr0 & ~CR0_WP); > + return (true); > +} > + > +void > +restore_wp(bool old_wp) > +{ > + > + if (old_wp) > + load_cr0(rcr0() | CR0_WP); > +} > + > #ifdef KDB > > /* > > Modified: head/sys/amd64/include/md_var.h > ============================================================ > ================== > --- head/sys/amd64/include/md_var.h Tue Mar 20 17:41:54 2018 > (r331251) > +++ head/sys/amd64/include/md_var.h Tue Mar 20 17:43:50 2018 > (r331252) > @@ -53,6 +53,8 @@ void amd64_conf_fast_syscall(void); > void amd64_db_resume_dbreg(void); > void amd64_lower_shared_page(struct sysentvec *); > void amd64_syscall(struct thread *td, int traced); > +bool disable_wp(void); > +void restore_wp(bool old_wp); > void doreti_iret(void) __asm(__STRING(doreti_iret)); > void doreti_iret_fault(void) __asm(__STRING(doreti_iret_fault)); > void ld_ds(void) __asm(__STRING(ld_ds)); > _______________________________________________ > svn-src-head@freebsd.org mailing list > https://lists.freebsd.org/mailman/listinfo/svn-src-head > To unsubscribe, send any mail to "svn-src-head-unsubscribe@freebsd.org" >
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?CAPQ4ffuoshDEN8cNqPZ5sv_v6AGPfi%2BjDRdpfgeTvP4ofpxLTw>