Re: avoid W|X mappings in libffi
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
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
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
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