Re: avoid W|X mappings in libffi

2016-05-23 Thread Stefan Kempf
Jeremie Courreges-Anglas wrote:
> Stuart Henderson  writes:
> 
> > This disables PROT_EXEC mappings in libffi (and thus python).
> > I'm running with it in a bulk build with the "mandatory W^X"
> > printfs that are going into snapshots and haven't triggered
> > them yet, building python itself (done 2.7 and 3.4 so far)
> > or in the ~200 py-* and py3-* things that have built already
> > (I would have had a whole stack by now otherwise).
> >
> > There are a lot of test failures when this diff is used.
> > Can anyone figure out if they're anything to worry about?
> 
> So I think the problem is simply that since the closure isn't allocated
> with PROT_EXEC permissions, you can't... execute it.
> 
> I'm kinda discovering libffi so sorry in advance if I'm mistaken, but it
> seems that the logical steps are always:
> - ffi_closure_alloc
> - ffi_prep_closure_loc
> - ffi_closure_free
> 
> ffi_prep_closure_loc being the function that actually writes machine
> code intended to be executed later.  I think we could tweak
> ffi_prep_closure_loc so that it adjusts the permissions after having
> done its work: move from PROT_READ|PROT_WRITE (what we get now with the
> closures.c diff) to PROT_READ|PROT_EXEC.
> 
> ffi_prep_closure is just a stub that calls ffi_prep_closure_loc, only
> the latter can handle different addresses for writable and executable
> user pages.  That seems to be used for situations when ffi_closure_alloc
> calls dlmmap_locked under the hood.
> 
> Here's a tentative diff, I'm not sure whether it will be the best
> solution in the end, but it doesn't seem to be worse than the current
> patch:

> [...]
 
> Index: patches/patch-src_x86_ffi64_c
> ===
> RCS file: patches/patch-src_x86_ffi64_c
> diff -N patches/patch-src_x86_ffi64_c
> --- /dev/null 1 Jan 1970 00:00:00 -
> +++ patches/patch-src_x86_ffi64_c 23 May 2016 11:46:59 -
> @@ -0,0 +1,27 @@
> +$OpenBSD$
> +--- src/x86/ffi64.c.orig Mon May 23 13:42:49 2016
>  src/x86/ffi64.c  Mon May 23 13:42:56 2016
> +@@ -27,6 +27,9 @@
> +DEALINGS IN THE SOFTWARE.
> +--- 
> */
> + 
> ++#include 
> ++#include 
> ++
> + #include 
> + #include 
> + 
> +@@ -563,6 +566,13 @@ ffi_prep_closure_loc (ffi_closure* closure,
> +   closure->cif = cif;
> +   closure->fun = fun;
> +   closure->user_data = user_data;
> ++
> ++  /* remove WRITE access on the closure */
> ++  if (mprotect(closure, sizeof(*closure), PROT_READ) == -1)
> ++  return FFI_OK;
> ++  /* ensure we have EXECUTE access on the closure */
> ++  if (mprotect(closure, sizeof(*closure), PROT_READ|PROT_EXEC) == -1)
> ++  return FFI_OK;

The second PROT_READ|PROT_EXEC mprotect should be enough.

Is ffi_closure_alloc() guaranteed to allocate a separate page, i.e. does
every closure get its own page? Because if a page can contain multiple
ffi_closures, they would all get mapped to PROT_READ|PROT_EXEC
at once => any later call of calling ffi_prep_closure_loc for those
other closures would cause a segfault.

> +   return FFI_OK;
> + }
> 
> 
> -- 
> jca | PGP : 0x1524E7EE / 5135 92C1 AD36 5293 2BDF  DDCC 0DFA 74AE 1524 E7EE
> 



devel/llvm: make clang build working static PIE programs

2016-06-27 Thread Stefan Kempf
clang currently links against /usr/lib/crt0.o when building
a binary with the -static -pie options. That makes such
programs segfault on startup (gcc 4.9 seems to have the same
problem).

When building a static PIE program, we need to link against
/usr/lib/rcrt0.o, as shown below. Bitrig has this part also
in their local llvm tree. I'll try to get it into upstream for
clang 3.9 as well.

--- tools/clang/lib/Driver/Tools.cpp.orig   Fri Feb 12 23:51:41 2016
+++ tools/clang/lib/Driver/Tools.cppSun Jun 26 20:24:44 2016
@@ -7600,6 +7600,10 @@ void openbsd::Linker::ConstructJob(Compilation &C, con
   if (Args.hasArg(options::OPT_pg))
 CmdArgs.push_back(
 Args.MakeArgString(getToolChain().GetFilePath("gcrt0.o")));
+  else if (Args.hasArg(options::OPT_static) &&
+   !Args.hasArg(options::OPT_nopie))
+CmdArgs.push_back(
+Args.MakeArgString(getToolChain().GetFilePath("rcrt0.o")));
   else
 CmdArgs.push_back(
 Args.MakeArgString(getToolChain().GetFilePath("crt0.o")));

Full diff against the ports tree below.

ok?

Index: Makefile
===
RCS file: /cvs/ports/devel/llvm/Makefile,v
retrieving revision 1.114
diff -u -p -r1.114 Makefile
--- Makefile24 May 2016 07:53:23 -  1.114
+++ Makefile27 Jun 2016 17:24:32 -
@@ -11,7 +11,7 @@ COMMENT = modular, fast C/C++/ObjC compi
 LLVM_V =   3.8.0
 DISTNAME = llvm-${LLVM_V}.src
 PKGNAME =  llvm-${LLVM_V}
-REVISION = 1
+REVISION = 2
 CATEGORIES =   devel
 DISTFILES =llvm-${LLVM_V}.src${EXTRACT_SUFX} \
cfe-${LLVM_V}.src${EXTRACT_SUFX}
Index: patches/patch-tools_clang_lib_Driver_Tools_cpp
===
RCS file: /cvs/ports/devel/llvm/patches/patch-tools_clang_lib_Driver_Tools_cpp,v
retrieving revision 1.30
diff -u -p -r1.30 patch-tools_clang_lib_Driver_Tools_cpp
--- patches/patch-tools_clang_lib_Driver_Tools_cpp  24 May 2016 07:53:23 
-  1.30
+++ patches/patch-tools_clang_lib_Driver_Tools_cpp  27 Jun 2016 17:24:32 
-
@@ -1,6 +1,5 @@
-$OpenBSD: patch-tools_clang_lib_Driver_Tools_cpp,v 1.30 2016/05/24 07:53:23 
ajacoutot Exp $
 tools/clang/lib/Driver/Tools.cpp.orig  Fri Feb 12 17:51:41 2016
-+++ tools/clang/lib/Driver/Tools.cpp   Tue May 17 14:45:22 2016
+--- tools/clang/lib/Driver/Tools.cpp.orig  Fri Feb 12 23:51:41 2016
 tools/clang/lib/Driver/Tools.cpp   Sun Jun 26 20:24:44 2016
 @@ -78,7 +78,7 @@ static const char *getSparcAsmModeForCPU(StringRef Nam
.Case("niagara2", "-Av9b")
.Case("niagara3", "-Av9d")
@@ -10,7 +9,18 @@ $OpenBSD: patch-tools_clang_lib_Driver_T
} else {
  return llvm::StringSwitch(Name)
.Case("v8", "-Av8")
-@@ -7611,15 +7611,17 @@ void openbsd::Linker::ConstructJob(Compilation &C, con
+@@ -7600,6 +7600,10 @@ void openbsd::Linker::ConstructJob(Compilation &C, con
+   if (Args.hasArg(options::OPT_pg))
+ CmdArgs.push_back(
+ Args.MakeArgString(getToolChain().GetFilePath("gcrt0.o")));
++  else if (Args.hasArg(options::OPT_static) &&
++   !Args.hasArg(options::OPT_nopie))
++CmdArgs.push_back(
++Args.MakeArgString(getToolChain().GetFilePath("rcrt0.o")));
+   else
+ CmdArgs.push_back(
+ Args.MakeArgString(getToolChain().GetFilePath("crt0.o")));
+@@ -7611,15 +7615,17 @@ void openbsd::Linker::ConstructJob(Compilation &C, con
  }
}
  



Re: devel/llvm: make clang build working static PIE programs

2016-07-04 Thread Stefan Kempf
ping?

Stefan Kempf wrote:
> clang currently links against /usr/lib/crt0.o when building
> a binary with the -static -pie options. That makes such
> programs segfault on startup (gcc 4.9 seems to have the same
> problem).
> 
> When building a static PIE program, we need to link against
> /usr/lib/rcrt0.o, as shown below. Bitrig has this part also
> in their local llvm tree. I'll try to get it into upstream for
> clang 3.9 as well.
> 
> --- tools/clang/lib/Driver/Tools.cpp.orig Fri Feb 12 23:51:41 2016
> +++ tools/clang/lib/Driver/Tools.cpp  Sun Jun 26 20:24:44 2016
> @@ -7600,6 +7600,10 @@ void openbsd::Linker::ConstructJob(Compilation &C, con
>if (Args.hasArg(options::OPT_pg))
>  CmdArgs.push_back(
>  Args.MakeArgString(getToolChain().GetFilePath("gcrt0.o")));
> +  else if (Args.hasArg(options::OPT_static) &&
> +   !Args.hasArg(options::OPT_nopie))
> +CmdArgs.push_back(
> +Args.MakeArgString(getToolChain().GetFilePath("rcrt0.o")));
>else
>  CmdArgs.push_back(
>  Args.MakeArgString(getToolChain().GetFilePath("crt0.o")));
> 
> Full diff against the ports tree below.
> 
> ok?
> 
> Index: Makefile
> ===
> RCS file: /cvs/ports/devel/llvm/Makefile,v
> retrieving revision 1.114
> diff -u -p -r1.114 Makefile
> --- Makefile  24 May 2016 07:53:23 -  1.114
> +++ Makefile  27 Jun 2016 17:24:32 -
> @@ -11,7 +11,7 @@ COMMENT =   modular, fast C/C++/ObjC compi
>  LLVM_V = 3.8.0
>  DISTNAME =   llvm-${LLVM_V}.src
>  PKGNAME =llvm-${LLVM_V}
> -REVISION =   1
> +REVISION =   2
>  CATEGORIES = devel
>  DISTFILES =  llvm-${LLVM_V}.src${EXTRACT_SUFX} \
>   cfe-${LLVM_V}.src${EXTRACT_SUFX}
> Index: patches/patch-tools_clang_lib_Driver_Tools_cpp
> ===
> RCS file: 
> /cvs/ports/devel/llvm/patches/patch-tools_clang_lib_Driver_Tools_cpp,v
> retrieving revision 1.30
> diff -u -p -r1.30 patch-tools_clang_lib_Driver_Tools_cpp
> --- patches/patch-tools_clang_lib_Driver_Tools_cpp24 May 2016 07:53:23 
> -  1.30
> +++ patches/patch-tools_clang_lib_Driver_Tools_cpp27 Jun 2016 17:24:32 
> -
> @@ -1,6 +1,5 @@
> -$OpenBSD: patch-tools_clang_lib_Driver_Tools_cpp,v 1.30 2016/05/24 07:53:23 
> ajacoutot Exp $
>  tools/clang/lib/Driver/Tools.cpp.origFri Feb 12 17:51:41 2016
> -+++ tools/clang/lib/Driver/Tools.cpp Tue May 17 14:45:22 2016
> +--- tools/clang/lib/Driver/Tools.cpp.origFri Feb 12 23:51:41 2016
>  tools/clang/lib/Driver/Tools.cpp Sun Jun 26 20:24:44 2016
>  @@ -78,7 +78,7 @@ static const char *getSparcAsmModeForCPU(StringRef Nam
> .Case("niagara2", "-Av9b")
> .Case("niagara3", "-Av9d")
> @@ -10,7 +9,18 @@ $OpenBSD: patch-tools_clang_lib_Driver_T
> } else {
>   return llvm::StringSwitch(Name)
> .Case("v8", "-Av8")
> -@@ -7611,15 +7611,17 @@ void openbsd::Linker::ConstructJob(Compilation &C, 
> con
> +@@ -7600,6 +7600,10 @@ void openbsd::Linker::ConstructJob(Compilation &C, con
> +   if (Args.hasArg(options::OPT_pg))
> + CmdArgs.push_back(
> + Args.MakeArgString(getToolChain().GetFilePath("gcrt0.o")));
> ++  else if (Args.hasArg(options::OPT_static) &&
> ++   !Args.hasArg(options::OPT_nopie))
> ++CmdArgs.push_back(
> ++Args.MakeArgString(getToolChain().GetFilePath("rcrt0.o")));
> +   else
> + CmdArgs.push_back(
> + Args.MakeArgString(getToolChain().GetFilePath("crt0.o")));
> +@@ -7611,15 +7615,17 @@ void openbsd::Linker::ConstructJob(Compilation &C, 
> con
>   }
> }
>   



Re: fix gcc 4.9 -static

2016-07-10 Thread Stefan Kempf
Tobias Ulmer wrote:
> Sync STARTFILE_SPEC, fixes egcc -static producing crashing programs
> 
> I don't expect any fallout from this (builtin spec file change only)

Checking with gcc -v, it seems to work on amd64. gcc 4.9 and our
base gcc behave the same given various -pie/-nopie/-shared/-static/-pg
combinations.
 
> OK?
> 
> ? todo.txt
> Index: Makefile
> ===
> RCS file: /home/vcs/cvs/openbsd/ports/lang/gcc/4.9/Makefile,v
> retrieving revision 1.32
> diff -u -p -r1.32 Makefile
> --- Makefile  29 Jun 2016 16:14:41 -  1.32
> +++ Makefile  9 Jul 2016 21:41:29 -
> @@ -4,8 +4,7 @@ ONLY_FOR_ARCHS = amd64 arm hppa i386 mip
>  DPB_PROPERTIES = parallel
>  
>  V = 4.9.3
> -REVISION = 7
> -REVISION-java = 8
> +REVISION = 9
>  FULL_VERSION = $V
>  FULL_PKGVERSION = $V
>  
> Index: patches/patch-gcc_config_alpha_openbsd_h
> ===
> RCS file: 
> /home/vcs/cvs/openbsd/ports/lang/gcc/4.9/patches/patch-gcc_config_alpha_openbsd_h,v
> retrieving revision 1.1.1.1
> diff -u -p -r1.1.1.1 patch-gcc_config_alpha_openbsd_h
> --- patches/patch-gcc_config_alpha_openbsd_h  26 Jun 2014 16:30:17 -  
> 1.1.1.1
> +++ patches/patch-gcc_config_alpha_openbsd_h  9 Jul 2016 21:41:29 -
> @@ -1,6 +1,6 @@
>  $OpenBSD: patch-gcc_config_alpha_openbsd_h,v 1.1.1.1 2014/06/26 16:30:17 
> pascal Exp $
>  gcc/config/alpha/openbsd.h.orig  Thu Jan 10 21:38:27 2013
> -+++ gcc/config/alpha/openbsd.h   Thu Apr 18 20:58:27 2013
> +--- gcc/config/alpha/openbsd.h.orig  Thu Jan  2 23:23:26 2014
>  gcc/config/alpha/openbsd.h   Sat Jul  9 22:13:30 2016
>  @@ -19,6 +19,28 @@ along with GCC; see the file COPYING3.  If not see
>   
>   /* Controlling the compilation driver.  */
> @@ -21,11 +21,11 @@ $OpenBSD: patch-gcc_config_alpha_openbsd
>  +/* As an elf system, we need crtbegin/crtend stuff.  */
>  +#undef STARTFILE_SPEC
>  +#define STARTFILE_SPEC "\
> -+%{!shared: %{pg:gcrt0%O%s} %{!pg:%{p:gcrt0%O%s} %{!p:crt0%O%s}} \
> -+crtbegin%O%s} %{shared:crtbeginS%O%s}"
> ++%{!shared: %{pg:gcrt0%O%s} %{!pg:%{p:gcrt0%O%s} \
> ++%{!p:%{!static:crt0%O%s} %{static:%{nopie:crt0%O%s} \
> ++%{!nopie:rcrt0%O%s crtbegin%O%s} %{shared:crtbeginS%O%s}"
>  +#undef ENDFILE_SPEC
>  +#define ENDFILE_SPEC "%{!shared:crtend%O%s} %{shared:crtendS%O%s}"
> -+
>  +
>   /* run-time target specifications */
>   #define TARGET_OS_CPP_BUILTINS()\
> Index: patches/patch-gcc_config_i386_openbsdelf_h
> ===
> RCS file: 
> /home/vcs/cvs/openbsd/ports/lang/gcc/4.9/patches/patch-gcc_config_i386_openbsdelf_h,v
> retrieving revision 1.1.1.1
> diff -u -p -r1.1.1.1 patch-gcc_config_i386_openbsdelf_h
> --- patches/patch-gcc_config_i386_openbsdelf_h26 Jun 2014 16:30:17 
> -  1.1.1.1
> +++ patches/patch-gcc_config_i386_openbsdelf_h9 Jul 2016 21:41:29 
> -
> @@ -1,7 +1,7 @@
>  $OpenBSD: patch-gcc_config_i386_openbsdelf_h,v 1.1.1.1 2014/06/26 16:30:17 
> pascal Exp $
>  gcc/config/i386/openbsdelf.h.origSun Sep  2 16:13:21 2012
> -+++ gcc/config/i386/openbsdelf.h Fri Oct 12 11:24:33 2012
> -@@ -97,10 +97,13 @@ along with GCC; see the file COPYING3.  If not see
> +--- gcc/config/i386/openbsdelf.h.origThu Jan  2 23:23:26 2014
>  gcc/config/i386/openbsdelf.h Fri Jul  8 17:18:50 2016
> +@@ -97,14 +97,17 @@ along with GCC; see the file COPYING3.  If not see
>  %{shared:-shared} %{R*} \
>  %{static:-Bstatic} \
>  %{!static:-Bdynamic} \
> @@ -10,8 +10,15 @@ $OpenBSD: patch-gcc_config_i386_openbsde
>  -dynamic-linker /usr/libexec/ld.so"
>   
>   #undef STARTFILE_SPEC
> -+
> +-#define STARTFILE_SPEC "\
> +-%{!shared: %{pg:gcrt0%O%s} %{!pg:%{p:gcrt0%O%s} %{!p:crt0%O%s}} \
> +-crtbegin%O%s} %{shared:crtbeginS%O%s}"
> + 
>  +#define SUBTARGET32_DEFAULT_CPU "i486"
> - #define STARTFILE_SPEC "\
> - %{!shared: %{pg:gcrt0%O%s} %{!pg:%{p:gcrt0%O%s} %{!p:crt0%O%s}} \
> - crtbegin%O%s} %{shared:crtbeginS%O%s}"
> ++#define STARTFILE_SPEC "\
> ++%{!shared: %{pg:gcrt0%O%s} %{!pg:%{p:gcrt0%O%s} \
> ++%{!p:%{!static:crt0%O%s} %{static:%{nopie:crt0%O%s} \
> ++%{!nopie:rcrt0%O%s crtbegin%O%s} %{shared:crtbeginS%O%s}"
> + #undef ENDFILE_SPEC
> + #define ENDFILE_SPEC "%{!shared:crtend%O%s} %{shared:crtendS%O%s}"
> + 
> Index: patches/patch-gcc_config_mips_openbsd_h
> ===
> RCS file: 
> /home/vcs/cvs/openbsd/ports/lang/gcc/4.9/patches/patch-gcc_config_mips_openbsd_h,v
> retrieving revision 1.1.1.1
> diff -u -p -r1.1.1.1 patch-gcc_config_mips_openbsd_h
> --- patches/patch-gcc_config_mips_openbsd_h   26 Jun 2014 16:30:18 -  
> 1.1.1.1
> +++ patches/patch-gcc_config_mips_openbsd_h   9 Jul 2016 21:41:29 -
> @@ -1,7 +1,7 @@
>  $OpenBSD: patch-gcc_config_mips_openbsd_h,v 1.1.1.1 2014/06/26 16:30:18 
> pas