svn commit: r331252 - in head/sys/amd64: amd64 include

Oliver Pinter oliver.pinter at hardenedbsd.org
Wed Mar 21 00:29:57 UTC 2018


On Tuesday, March 20, 2018, Konstantin Belousov <kib at 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 at 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 at freebsd.org mailing list
> https://lists.freebsd.org/mailman/listinfo/svn-src-head
> To unsubscribe, send any mail to "svn-src-head-unsubscribe at freebsd.org"
>


More information about the svn-src-all mailing list