golang: Add support for ASLR/PIE for host and target Go
authorJeffery To <jeffery.to@gmail.com>
Wed, 8 Jan 2020 11:13:44 +0000 (19:13 +0800)
committerJeffery To <jeffery.to@gmail.com>
Wed, 8 Jan 2020 11:29:54 +0000 (19:29 +0800)
This adds support to compile host and target Go as position-independent
executables.

Host Go will have PIE enabled if Go supports PIE on the host platform.

Target Go will have PIE enabled if Go supports PIE on the target
platform and CONFIG_PKG_ASLR_PIE is selected.

Go 1.13 supports PIE for x86 and arm targets; mips support is in
progress[1].

[1]: https://github.com/golang/go/issues/21222#issuecomment-542064462

Signed-off-by: Jeffery To <jeffery.to@gmail.com>
lang/golang/golang-compiler.mk
lang/golang/golang-values.mk
lang/golang/golang/Makefile

index 5e7fe689d3a2b6078fdbc7ce9b26727722b4db08..fa8f3bc9fa8a59e1155843ec317de529da89a404 100644 (file)
@@ -1,5 +1,5 @@
 #
-# Copyright (C) 2018 Jeffery To
+# Copyright (C) 2018, 2020 Jeffery To
 #
 # This is free software, licensed under the GNU General Public License v2.
 # See /LICENSE for more information.
@@ -51,6 +51,7 @@ endef
 # $(2) destination prefix
 # $(3) go version id
 # $(4) GOOS_GOARCH
+# $(5) install suffix (optional)
 define GoCompiler/Default/Install/Bin
        $(call GoCompiler/Default/Install/make-dirs,$(2),$(3))
 
@@ -73,7 +74,7 @@ define GoCompiler/Default/Install/Bin
   endif
 
        $(INSTALL_DIR) $(2)/lib/go-$(3)/pkg
-       $(CP) $(1)/pkg/$(4) $(2)/lib/go-$(3)/pkg/
+       $(CP) $(1)/pkg/$(4)$(if $(5),_$(5)) $(2)/lib/go-$(3)/pkg/
 
        $(INSTALL_DIR) $(2)/lib/go-$(3)/pkg/tool/$(4)
        $(INSTALL_BIN) -p $(1)/pkg/tool/$(4)/* $(2)/lib/go-$(3)/pkg/tool/$(4)/
@@ -141,6 +142,7 @@ endef
 # $(3) destination prefix
 # $(4) go version id
 # $(5) GOOS_GOARCH
+# $(6) install suffix (optional)
 define GoCompiler/AddProfile
 
   # $$(1) valid GOOS_GOARCH combinations
@@ -155,7 +157,7 @@ define GoCompiler/AddProfile
 
   # $$(1) override install prefix (optional)
   define GoCompiler/$(1)/Install/Bin
-       $$(call GoCompiler/Default/Install/Bin,$(2),$$(or $$(1),$(3)),$(4),$(5))
+       $$(call GoCompiler/Default/Install/Bin,$(2),$$(or $$(1),$(3)),$(4),$(5),$(6))
   endef
 
   # $$(1) override install prefix (optional)
index 873d71524621c02d57cd7265156fef776b789ca2..ee4ba7f2a319dd09d288a2aa37c503b213eb5664 100644 (file)
@@ -190,3 +190,29 @@ GO_ARCH_DEPENDS:=@(aarch64||arm||i386||i686||mips||mips64||mips64el||mipsel||pow
 GO_TARGET_PREFIX:=/usr
 GO_TARGET_VERSION_ID:=$(GO_VERSION_MAJOR_MINOR)
 GO_TARGET_ROOT:=$(GO_TARGET_PREFIX)/lib/go-$(GO_TARGET_VERSION_ID)
+
+
+# ASLR/PIE
+
+GO_PIE_SUPPORTED_OS_ARCH:= \
+  android_386 android_amd64 android_arm android_arm64 \
+  linux_386   linux_amd64   linux_arm   linux_arm64 \
+  \
+  darwin_amd64 \
+  freebsd_amd64 \
+  \
+  aix_ppc64 \
+  \
+  linux_ppc64le linux_s390x
+
+go_pie_install_suffix=$(if $(filter $(1),aix_ppc64),,shared)
+
+ifneq ($(filter $(GO_HOST_OS_ARCH),$(GO_PIE_SUPPORTED_OS_ARCH)),)
+  GO_HOST_PIE_SUPPORTED:=1
+  GO_HOST_PIE_INSTALL_SUFFIX:=$(call go_pie_install_suffix,$(GO_HOST_OS_ARCH))
+endif
+
+ifneq ($(filter $(GO_OS_ARCH),$(GO_PIE_SUPPORTED_OS_ARCH)),)
+  GO_TARGET_PIE_SUPPORTED:=1
+  GO_TARGET_PIE_INSTALL_SUFFIX:=$(call go_pie_install_suffix,$(GO_OS_ARCH))
+endif
index e7ac30cf6c819faf8b80d5679f1efebc637b40a8..75badf95331b425ba3f1a04ea31b42b59bcefb7c 100644 (file)
@@ -10,7 +10,7 @@ include ../golang-version.mk
 
 PKG_NAME:=golang
 PKG_VERSION:=$(GO_VERSION_MAJOR_MINOR)$(if $(GO_VERSION_PATCH),.$(GO_VERSION_PATCH))
-PKG_RELEASE:=1
+PKG_RELEASE:=2
 
 GO_SOURCE_URLS:=https://dl.google.com/go/ \
                 https://mirrors.ustc.edu.cn/golang/ \
@@ -92,6 +92,18 @@ BOOTSTRAP_UNPACK:=$(HOST_TAR) -C $(BOOTSTRAP_BUILD_DIR) --strip-components=1 -xz
 RSTRIP:=:
 STRIP:=:
 
+ifeq ($(CONFIG_PKG_ASLR_PIE),y)
+  ifeq ($(GO_TARGET_PIE_SUPPORTED),1)
+    PKG_GO_ENABLE_PIE:=1
+    PKG_GO_INSTALL_SUFFIX:=$(GO_TARGET_PIE_INSTALL_SUFFIX)
+  endif
+endif
+
+ifeq ($(GO_HOST_PIE_SUPPORTED),1)
+  HOST_GO_ENABLE_PIE:=1
+  HOST_GO_INSTALL_SUFFIX:=$(GO_HOST_PIE_INSTALL_SUFFIX)
+endif
+
 define Package/golang/Default
 $(call GoPackage/GoSubMenu)
   TITLE:=Go programming language
@@ -158,8 +170,8 @@ endef
 $(eval $(call Download,golang-bootstrap))
 
 $(eval $(call GoCompiler/AddProfile,Bootstrap,$(BOOTSTRAP_BUILD_DIR),,bootstrap,$(GO_HOST_OS_ARCH)))
-$(eval $(call GoCompiler/AddProfile,Host,$(HOST_BUILD_DIR),$(HOST_GO_PREFIX),$(HOST_GO_VERSION_ID),$(GO_HOST_OS_ARCH)))
-$(eval $(call GoCompiler/AddProfile,Package,$(PKG_BUILD_DIR),$(GO_TARGET_PREFIX),$(GO_TARGET_VERSION_ID),$(GO_OS_ARCH)))
+$(eval $(call GoCompiler/AddProfile,Host,$(HOST_BUILD_DIR),$(HOST_GO_PREFIX),$(HOST_GO_VERSION_ID),$(GO_HOST_OS_ARCH),$(HOST_GO_INSTALL_SUFFIX)))
+$(eval $(call GoCompiler/AddProfile,Package,$(PKG_BUILD_DIR),$(GO_TARGET_PREFIX),$(GO_TARGET_VERSION_ID),$(GO_OS_ARCH),$(PKG_GO_INSTALL_SUFFIX)))
 
 define Host/Prepare
        $(call Host/Prepare/Default)
@@ -167,6 +179,9 @@ define Host/Prepare
        $(BOOTSTRAP_UNPACK)
 endef
 
+# when https://github.com/golang/go/issues/31544 is fixed,
+# we should be able to set GO_LDFLAGS=-buildmode=pie for host make
+# instead of doing a rebuild for pie
 define Host/Compile
        $(call GoCompiler/Bootstrap/CheckHost,$(BOOTSTRAP_GO_VALID_OS_ARCH))
        $(call GoCompiler/Host/CheckHost,$(HOST_GO_VALID_OS_ARCH))
@@ -181,6 +196,21 @@ define Host/Compile
                CC=$(HOSTCC_NOCACHE) \
                CXX=$(HOSTCXX_NOCACHE) \
        )
+
+  ifneq ($(HOST_GO_ENABLE_PIE),)
+       @echo "Rebuilding host Go with PIE"
+
+       ( \
+               cd $(HOST_BUILD_DIR)/bin ; \
+               $(CP) go go-nopie ; \
+               CC=$(HOSTCC_NOCACHE) \
+               CXX=$(HOSTCXX_NOCACHE) \
+               ./go-nopie install -a -buildmode=pie std cmd ; \
+               retval=$$$$? ; \
+               rm -f go-nopie ; \
+               exit $$$$retval ; \
+       )
+  endif
 endef
 
 # if host and target os/arch are the same,
@@ -194,7 +224,7 @@ define Host/Install
 
        $(call GoCompiler/Host/Install/BinLinks,)
 
-       rm -rf $(HOST_GO_ROOT)/pkg/$(GO_HOST_OS_ARCH)
+       rm -rf $(HOST_GO_ROOT)/pkg/$(GO_HOST_OS_ARCH)$(if $(HOST_GO_INSTALL_SUFFIX),_$(HOST_GO_INSTALL_SUFFIX))
 
        $(INSTALL_DIR) $(HOST_GO_ROOT)/openwrt
        $(INSTALL_BIN) ./files/go-gcc-helper $(HOST_GO_ROOT)/openwrt/
@@ -247,7 +277,7 @@ define Build/Compile
                PKG_CONFIG=pkg-config \
                PATH=$(HOST_GO_ROOT)/openwrt:$$$$PATH \
                $(call GoPackage/Environment) \
-               ./go-host install -a -v std cmd ; \
+               ./go-host install -a $(if $(PKG_GO_ENABLE_PIE),-buildmode=pie) std cmd ; \
                retval=$$$$? ; \
                rm -f go-host ; \
                exit $$$$retval ; \