tianon / gosu

Simple Go-based setuid+setgid+setgroups+exec
Apache License 2.0
4.73k stars 321 forks source link

Add build support for mips64le #69

Closed ydcool closed 4 years ago

ydcool commented 4 years ago

The CI build and test all passed. Related logs below:

Step 17/18 : RUN set -eux;  eval "GOARCH=mips64le go build $BUILD_FLAGS -o /go/bin/gosu-mips64le";  file /go/bin/gosu-mips64le 
 ---> Running in 8cbbb1faf857 
+ eval 'GOARCH=mips64le go build -v -ldflags '"'"'-d -s -w'"'"' -o /go/bin/gosu-mips64le'
+ GOARCH=mips64le go build -v -ldflags '-d -s -w' -o /go/bin/gosu-mips64le 
internal/cpu 
runtime/internal/atomic
internal/bytealg
runtime/internal/sys
internal/race
runtime/internal/math
sync/atomic
runtime
unicode
unicode/utf8
math/bits
math
internal/testlog
internal/reflectlite
sync
errors
sort
io
strconv
bytes
internal/oserror
reflect
syscall
time
internal/fmtsort
internal/syscall/unix
internal/poll
bufio
os
encoding/binary
strings
fmt
github.com/opencontainers/runc/vendor/golang.org/x/sys/unix
os/user
path/filepath
io/ioutil
context
os/exec
log
github.com/opencontainers/runc/libcontainer/user
net/url
github.com/opencontainers/runc/libcontainer/system
text/template/parse
text/template
github.com/tianon/gosu
+ file /go/bin/gosu-mips64le
/go/bin/gosu-mips64le: ELF 64-bit LSB executable, MIPS, MIPS-III version 1 (SYSV), statically linked, Go BuildID=PCP0I6kArfY7twAXF5KJ/UWD8pRH-rFMCrOMjMq5x/5471ssji3e_7Fg6xuL_g/yq6_iByPT9NUIVFtDiEs, stripped
Removing intermediate container 8cbbb1faf857
 ---> 3044274b5f97
Step 18/18 : RUN file /go/bin/gosu-*
 ---> Running in 121505a2c2fe
/go/bin/gosu-amd64:    ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, Go BuildID=F-lGSAxnibL3puMHXEHr/rSWB8qh__f9y11DTottt/WS9qLR-aSZO9HDx1Evnf/CqZIs1ctRPY4WQUXT5E3, stripped
/go/bin/gosu-arm64:    ELF 64-bit LSB executable, ARM aarch64, version 1 (SYSV), statically linked, Go BuildID=2pbs2wg67RaRQ1fnvkJ5/LV_tpYPDnoO5ySXYyhxD/O5iVG4yzBBM9rrZWGGGi/02u7bdLuzkB3-EZiblc8, stripped
/go/bin/gosu-armel:    ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), statically linked, Go BuildID=SZGBpqgYmSoYeMCT1UKN/ZbZ3phF2oEIXRnhYrU7Q/cgJI0gUvrNauzLPUiD-n/BCmUTuiI01Q449sE9Kxx, stripped
/go/bin/gosu-armhf:    ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), statically linked, Go BuildID=0OxquBpSQgH1Q5Wo9nYK/I0t6jxVo9nriFZimXXZ8/cgJI0gUvrNauzLPUiD-n/6eA-8R5__y8Oo-qoECt_, stripped
/go/bin/gosu-i386:     ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), statically linked, Go BuildID=Zvbr4ceUGpSiBNKfQZnN/tgIsBua9jPUzAPckFGR7/FFYNSu3Hb_7Xo_SHlQy3/XAhSE6i-M86kMYvvfeUO, stripped
/go/bin/gosu-mips64le: ELF 64-bit LSB executable, MIPS, MIPS-III version 1 (SYSV), statically linked, Go BuildID=PCP0I6kArfY7twAXF5KJ/UWD8pRH-rFMCrOMjMq5x/5471ssji3e_7Fg6xuL_g/yq6_iByPT9NUIVFtDiEs, stripped
/go/bin/gosu-ppc64:    ELF 64-bit MSB executable, 64-bit PowerPC or cisco 7500, version 1 (SYSV), statically linked, Go BuildID=XT12jbW5CC5yF6Tk0vcp/Biym5pAR8jsxIM2K2cW1/9BProHtIlQ9yEu1JywOL/VfYdHDT8OzbrhsAAnFJS, stripped
/go/bin/gosu-ppc64el:  ELF 64-bit LSB executable, 64-bit PowerPC or cisco 7500, version 1 (SYSV), statically linked, Go BuildID=FDNKcwpSlKlMEIYXPrK8/FlKsVkjH09dl51aVkaym/ZYdWndZO5trqgp5e4GhH/-c-WFO7jaXuvxlUU4LVt, stripped
/go/bin/gosu-s390x:    ELF 64-bit MSB executable, IBM S/390, version 1 (SYSV), statically linked, Go BuildID=t2Kf4BKTaWnfwlW3mG9M/8kWrWgVdCImnlbkWJU89/WFS7Jk1LVqvp47ZKQgVu/VPzAMFLdeCvJGGwsmwO0, stripped
Removing intermediate container 121505a2c2fe
 ---> 6c8161105d93
Successfully built 6c8161105d93
Successfully tagged gosu:latest
+rm -f 'gosu*' 'SHA256SUMS*'
+tar -xv
+docker run --rm gosu sh -c 'cd /go/bin && tar -c gosu*'
gosu-amd64
gosu-arm64
gosu-armel
gosu-armhf
gosu-i386
gosu-mips64le
gosu-ppc64
gosu-ppc64el
gosu-s390x
+tee SHA256SUMS
+sha256sum gosu-amd64 gosu-arm64 gosu-armel gosu-armhf gosu-i386 gosu-mips64le gosu-ppc64 gosu-ppc64el gosu-s390x
5ae8343f27d9882f3122a34502f15b915f273a51746ede39f26511b90476f79c  gosu-amd64
b471a3f7d01e02dc3ac063f6765933cfe8d5f444649a60602b70c430284edf3f  gosu-arm64
96d00c4ec79a2a3e6f46e52055121d7e1dba409ffb1b4e91ef5c9bd35a734516  gosu-armel
480eb6180daffee19e2a49d113bffd08bf4c534ab5ad83bb4d4532a5dd763267  gosu-armhf
4e038382cae9419402c32191d695152a131af21fb76d6a4e8e015b585053bcf0  gosu-i386
6df6361e52aa5c34e57341469caaad056e53141639feeb03e4b3898bbbce7fc7  gosu-mips64le
a7a8436b1370957bf9dbdb7ad90cde46c852271bfa52cb0f3133a757518ab1c8  gosu-ppc64
6219bdf5d4f081b6b94e6fd2762422031fe6202f79fd0ff5434a0cf704bd0e96  gosu-ppc64el
b8272c86e64a4565723fc439995d3d46cca6943dd20d389b0bf228ca4081e943  gosu-s390x
+file gosu-amd64 gosu-arm64 gosu-armel gosu-armhf gosu-i386 gosu-mips64le gosu-ppc64 gosu-ppc64el gosu-s390x
gosu-amd64:    ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, stripped
gosu-arm64:    ELF 64-bit LSB executable, ARM aarch64, version 1 (SYSV), statically linked, stripped
gosu-armel:    ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), statically linked, stripped
gosu-armhf:    ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), statically linked, stripped
gosu-i386:     ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), statically linked, stripped
gosu-mips64le: ELF 64-bit LSB executable, MIPS, MIPS-III version 1 (SYSV), statically linked, stripped
gosu-ppc64:    ELF 64-bit MSB executable, 64-bit PowerPC or cisco 7500, version 1 (SYSV), statically linked, stripped
gosu-ppc64el:  ELF 64-bit LSB executable, 64-bit PowerPC or cisco 7500, version 1 (SYSV), statically linked, stripped
gosu-s390x:    ELF 64-bit MSB executable, IBM S/390, version 1 (SYSV), statically linked, stripped
+ls -lFh gosu-amd64 gosu-arm64 gosu-armel gosu-armhf gosu-i386 gosu-mips64le gosu-ppc64 gosu-ppc64el gosu-s390x SHA256SUMS
-rwxr-xr-x 1 travis travis 2.3M Mar 13 03:30 gosu-amd64*
-rwxr-xr-x 1 travis travis 2.4M Mar 13 03:30 gosu-arm64*
-rwxr-xr-x 1 travis travis 2.2M Mar 13 03:30 gosu-armel*
-rwxr-xr-x 1 travis travis 2.1M Mar 13 03:30 gosu-armhf*
-rwxr-xr-x 1 travis travis 2.0M Mar 13 03:30 gosu-i386*
-rwxr-xr-x 1 travis travis 2.5M Mar 13 03:30 gosu-mips64le*
-rwxr-xr-x 1 travis travis 2.4M Mar 13 03:30 gosu-ppc64*
-rwxr-xr-x 1 travis travis 2.4M Mar 13 03:30 gosu-ppc64el*
-rwxr-xr-x 1 travis travis 2.5M Mar 13 03:30 gosu-s390x*
-rw-rw-r-- 1 travis travis  697 Mar 13 03:30 SHA256SUMS
++dpkg --print-architecture
+./gosu-amd64 --help
Usage: gosu-amd64 user-spec command [args]
   eg: gosu-amd64 tianon bash
       gosu-amd64 nobody:root bash -c 'whoami && id'
       gosu-amd64 1000:1 id 
gosu-amd64 version: 1.11 (go1.13.8 on linux/amd64; gc) 
gosu-amd64 license: GPL-3 (full text at https://github.com/tianon/gosu) 
The command "./build.sh" exited with 0. 
ydcool commented 4 years ago

I'm definitely happy to support this -- any chance you've tested/verified the resulting binary?

Yes, working on this

ydcool commented 4 years ago

Unfortunately test failed... ;( Since there's no alpine image avaliable for mips64el, using multiarch/debian-debootstrap:mips64el-stretch-slim instead, and modify Dockerfile.test L4:

- RUN cut -d: -f1 /etc/group | xargs -n1 addgroup nobody 
+ RUN groupadd nobody && cut -d: -f1 /etc/group | xargs -n1 addgroup nobody  

run ./test.sh gosu-mips64el on the mips64el machine, got failed at step 16:

Step 16/42 : RUN gosu-t 0:1000 '0:1000:1000' 'root:1000:1000'
 ---> Running in be6d9446b7f5
+ spec=0:1000
+ shift
+ expec=0:1000:1000
+ shift
+ gosu 0:1000 id -u
+ gosu 0:1000 id -g
+ gosu 0:1000 id -G
+ real=0:1000:1000
+ [ 0:1000:1000 = 0:1000:1000 ]
+ expec=root:1000:1000
+ shift
+ gosu 0:1000 id -un
+ gosu 0:1000 id -gn
+ gosu 0:1000 id -Gn
+ real=root:nobody:nobody
+ [ root:1000:1000 = root:nobody:nobody ]
The command '/bin/sh -c gosu-t 0:1000 '0:1000:1000' 'root:1000:1000'' returned a non-zero code: 1
++ set +x

FAILED

Edit: I built the su-exec and run ./test.sh su-exec and got the same error. So is this failure related to the base image?

Edit 2: Tested gosu-amd64 with ubuntu:18.04 base image in Dockerfile.test and failed as the same.

tianon commented 4 years ago

Hmm, that does seem more like an issue with switching the base of the test suite than with the binary -- I'll take a look and see if I can recreate a (passing) test suite on Debian or Ubuntu. :+1:

tianon commented 4 years ago

Merged in https://github.com/tianon/gosu/pull/72! If you rebase on that, you should be able to run something like ./test.sh --debian gosu-mips64el :+1:

ydcool commented 4 years ago

hello, I tested the latest revision both on amd64 and mips64el using --debian but still got failed:

Step 40/43 : RUN ! gosu bogus true
 ---> Running in db72233bf92f
error: failed switching to "bogus": unable to find user bogus: no matching entries in passwd file
Removing intermediate container db72233bf92f
 ---> f8a6bce01e33
Step 41/43 : RUN ! gosu 0day true
 ---> Running in 1652ded42da4
error: failed switching to "0day": unable to find user 0day: no matching entries in passwd file
Removing intermediate container 1652ded42da4
 ---> cea9e3a811a4
Step 42/43 : RUN ! gosu 0:bogus true
 ---> Running in a3c6133a1294
error: failed switching to "0:bogus": unable to find group bogus: no matching entries in group file
Removing intermediate container a3c6133a1294
 ---> 9e5a1de892ff
Step 43/43 : RUN ! gosu 0:0day true
 ---> Running in 5220cf226e2f
error: failed switching to "0:0day": unable to find group 0day: no matching entries in group file
Removing intermediate container 5220cf226e2f
 ---> 55732d77cd05
Successfully built 55732d77cd05
Successfully tagged gosu-test:gosu-test-DenBOFL1X8
+ rm -rf /tmp/gosu-test-DenBOFL1X8
+ trap - EXIT
+ trap 'docker rm -f '\''gosu-test-DenBOFL1X8'\'' > /dev/null; docker rmi -f '\''gosu-test:gosu-test-DenBOFL1X8'\'' > /dev/null' EXIT
+ docker run -d --name gosu-test-DenBOFL1X8 gosu-test:gosu-test-DenBOFL1X8 gosu root sleep 1000
fb00417c5e0b78c0810814433627c81f8f1dcf501f8062a1f09f416687c6ac21
+ sleep 1
++ docker top gosu-test-DenBOFL1X8
++ wc -l
+ '[' 3 = 2 ']'
++ set +x

FAILED
tianon commented 4 years ago

Interesting, that seems like either a quirk of how sleep works on mips64le (which seems really unlikely), or that the Docker daemon is running with --init (which would add /dev/init as PID 1 inside the container).

If it turns out to be the latter, I should probably adjust that test to allow for that possibility (or explicitly run it with --init so we force that situation and can account for it accordingly).

Edit: this seemed like a sane change regardless, so it's done in 789b12e :innocent: :+1:

ydcool commented 4 years ago

All tests passed! 👍🎉 That failure before because the base image has tini set as default entrypoint...

[root@master3 gosu]# ./test.sh --debian gosu-mips64el 
++ mktemp -d -t gosu-test-XXXXXXXXXX
+ dir=/tmp/gosu-test-RMo6ciNXE2
++ basename /tmp/gosu-test-RMo6ciNXE2
+ base=gosu-test-RMo6ciNXE2
+ img=gosu-test:gosu-test-RMo6ciNXE2
+ trap 'rm -rf '\''/tmp/gosu-test-RMo6ciNXE2'\''' EXIT
+ cp -T Dockerfile.test-debian /tmp/gosu-test-RMo6ciNXE2/Dockerfile
+ cp -T gosu-mips64el /tmp/gosu-test-RMo6ciNXE2/gosu
+ docker build -t gosu-test:gosu-test-RMo6ciNXE2 /tmp/gosu-test-RMo6ciNXE2
Sending build context to Docker daemon  2.627MB
Step 1/43 : FROM registry.icp.com:5000/library/os/inspur-debian-stretch-mips64el:5.0.0
 ---> ce7b02d8592c
Step 2/43 : RUN cut -d: -f1 /etc/group | xargs -n1 -I'{}' usermod -aG '{}' nobody
 ---> Using cache
 ---> e58016aa74c6
Step 3/43 : RUN usermod -aG users games
 ---> Using cache
 ---> 26ecdc6708ac
Step 4/43 : RUN {       echo '#!/bin/sh';       echo 'set -ex';         echo;       echo 'spec="$1"; shift';        echo;       echo 'expec="$1"; shift';       echo 'real="$(gosu "$spec" id -u):$(gosu "$spec" id -g):$(gosu "$spec" id -G)"';        echo '[ "$expec" = "$real" ]';      echo;       echo 'expec="$1"; shift';       echo 'real="$(gosu "$spec" id -un):$(gosu "$spec" id -gn):$(gosu "$spec" id -Gn)" || true';         echo '[ "$expec" = "$real" ]';  } > /usr/local/bin/gosu-t   && chmod +x /usr/local/bin/gosu-t
 ---> Using cache
 ---> 4a97d132cc30
Step 5/43 : COPY gosu /usr/local/bin/
 ---> Using cache
 ---> f7d7fef16a43
Step 6/43 : RUN chgrp nogroup /usr/local/bin/gosu   && chmod +s /usr/local/bin/gosu
 ---> Using cache
 ---> bb30dad9c07b
Step 7/43 : USER nobody
 ---> Using cache
 ---> 986bf03f1c50
Step 8/43 : ENV HOME /omg/really/gosu/nowhere
 ---> Using cache
 ---> 7108cf7f1f29
Step 9/43 : RUN id
 ---> Using cache
 ---> 6295a18935d4
Step 10/43 : RUN gosu-t 0 "0:0:$(id -G root)" "root:root:$(id -Gn root)"
 ---> Using cache
 ---> 5fe7d636ff0c
Step 11/43 : RUN gosu-t 0:0 '0:0:0' 'root:root:root'
 ---> Using cache
 ---> 5785eb30fe65
Step 12/43 : RUN gosu-t root "0:0:$(id -G root)" "root:root:$(id -Gn root)"
 ---> Using cache
 ---> 984f31633d26
Step 13/43 : RUN gosu-t 0:root '0:0:0' 'root:root:root'
 ---> Using cache
 ---> a60d1936a2e5
Step 14/43 : RUN gosu-t root:0 '0:0:0' 'root:root:root'
 ---> Using cache
 ---> 20ad6a624c22
Step 15/43 : RUN gosu-t root:root '0:0:0' 'root:root:root'
 ---> Using cache
 ---> bc234927de38
Step 16/43 : RUN gosu-t 1000 "1000:$(id -g):$(id -g)" "1000:$(id -gn):$(id -gn)"
 ---> Using cache
 ---> f5acb94d501e
Step 17/43 : RUN gosu-t 0:1000 '0:1000:1000' 'root:1000:1000'
 ---> Using cache
 ---> c4ccdca25635
Step 18/43 : RUN gosu-t 1000:1000 '1000:1000:1000' '1000:1000:1000'
 ---> Using cache
 ---> e95fc214c561
Step 19/43 : RUN gosu-t root:1000 '0:1000:1000' 'root:1000:1000'
 ---> Using cache
 ---> f8c0da0a29ae
Step 20/43 : RUN gosu-t 1000:root '1000:0:0' '1000:root:root'
 ---> Using cache
 ---> 0e7e19d3e2fd
Step 21/43 : RUN gosu-t 1000:daemon "1000:$(id -g daemon):$(id -g daemon)" '1000:daemon:daemon'
 ---> Using cache
 ---> 081626e4ad78
Step 22/43 : RUN gosu-t games "$(id -u games):$(id -g games):$(id -G games)" 'games:games:games users'
 ---> Using cache
 ---> c6f99f58e2c9
Step 23/43 : RUN gosu-t games:daemon "$(id -u games):$(id -g daemon):$(id -g daemon)" 'games:daemon:daemon'
 ---> Using cache
 ---> a0f06aaa2a25
Step 24/43 : RUN gosu-t 0: "0:0:$(id -G root)" "root:root:$(id -Gn root)"
 ---> Using cache
 ---> 513afe237395
Step 25/43 : RUN gosu-t '' "$(id -u):$(id -g):$(id -G)" "$(id -un):$(id -gn):$(id -Gn)"
 ---> Using cache
 ---> ba60d597a4e0
Step 26/43 : RUN gosu-t ':0' "$(id -u):0:0" "$(id -un):root:root"
 ---> Using cache
 ---> e14849a070cf
Step 27/43 : RUN [ "$(gosu 0 env | grep '^HOME=')" = 'HOME=/root' ]
 ---> Using cache
 ---> 8a90cc9b6cf3
Step 28/43 : RUN [ "$(gosu 0:0 env | grep '^HOME=')" = 'HOME=/root' ]
 ---> Using cache
 ---> 122d6e964bb2
Step 29/43 : RUN [ "$(gosu root env | grep '^HOME=')" = 'HOME=/root' ]
 ---> Using cache
 ---> 7a9e49b30fbd
Step 30/43 : RUN [ "$(gosu 0:root env | grep '^HOME=')" = 'HOME=/root' ]
 ---> Using cache
 ---> 52f56a96f6f4
Step 31/43 : RUN [ "$(gosu root:0 env | grep '^HOME=')" = 'HOME=/root' ]
 ---> Using cache
 ---> da818f495b2c
Step 32/43 : RUN [ "$(gosu root:root env | grep '^HOME=')" = 'HOME=/root' ]
 ---> Using cache
 ---> c84b370f7827
Step 33/43 : RUN [ "$(gosu 0:1000 env | grep '^HOME=')" = 'HOME=/root' ]
 ---> Using cache
 ---> 090bf39f673a
Step 34/43 : RUN [ "$(gosu root:1000 env | grep '^HOME=')" = 'HOME=/root' ]
 ---> Using cache
 ---> bb58fa0eaf00
Step 35/43 : RUN [ "$(gosu 1000 env | grep '^HOME=')" = 'HOME=/' ]
 ---> Using cache
 ---> 2f1b40255878
Step 36/43 : RUN [ "$(gosu 1000:0 env | grep '^HOME=')" = 'HOME=/' ]
 ---> Using cache
 ---> c57a132dea2d
Step 37/43 : RUN [ "$(gosu 1000:root env | grep '^HOME=')" = 'HOME=/' ]
 ---> Using cache
 ---> 307174ccc60c
Step 38/43 : RUN [ "$(gosu games env | grep '^HOME=')" = 'HOME=/usr/games' ]
 ---> Using cache
 ---> ba5a4e81e59c
Step 39/43 : RUN [ "$(gosu games:daemon env | grep '^HOME=')" = 'HOME=/usr/games' ]
 ---> Using cache
 ---> 05044fec163f
Step 40/43 : RUN ! gosu bogus true
 ---> Using cache
 ---> af91c195b13a
Step 41/43 : RUN ! gosu 0day true
 ---> Using cache
 ---> ece7fc4a7a46
Step 42/43 : RUN ! gosu 0:bogus true
 ---> Using cache
 ---> 44cfc5566a29
Step 43/43 : RUN ! gosu 0:0day true
 ---> Using cache
 ---> 7c666ed107e6
Successfully built 7c666ed107e6
Successfully tagged gosu-test:gosu-test-RMo6ciNXE2
+ rm -rf /tmp/gosu-test-RMo6ciNXE2
+ trap - EXIT
+ trap 'docker rm -f '\''gosu-test-RMo6ciNXE2'\'' > /dev/null; docker rmi -f '\''gosu-test:gosu-test-RMo6ciNXE2'\'' > /dev/null' EXIT
+ docker run -d --init=false --entrypoint= --name gosu-test-RMo6ciNXE2 gosu-test:gosu-test-RMo6ciNXE2 gosu root sleep 1000
b791a15b7d6d117ea411cade289d48243cc0b9ecc0a964a07ce8a0c1c0f43b9c
+ sleep 1
++ docker top gosu-test-RMo6ciNXE2
++ wc -l
+ '[' 2 = 2 ']'
+ docker rm -f gosu-test-RMo6ciNXE2
+ docker rmi -f gosu-test:gosu-test-RMo6ciNXE2