landdown
Simple Sandboxing for shell scripts.
git clone git://mccd.space/landdown
| Log | Files | Refs | README | LICENSE |
commit 8719bfb36a7247dd2d7d4393c4a5f7ad130c58b5 parent 0ac1dad37508cd691b29c9f682dab51c28a362e4 Author: Marc <marc@coquand.email> Date: Tue, 31 Mar 2026 14:51:24 +0200 Correct stdin handling Diffstat:
| M | README.md | | | 1 | - |
| M | go.mod | | | 4 | ++-- |
| M | go.sum | | | 2 | ++ |
| M | main.go | | | 25 | ++++++++++++------------- |
4 files changed, 16 insertions(+), 16 deletions(-)
diff --git a/README.md b/README.md
@@ -86,4 +86,3 @@ curl https://www.google.com
```
Try removing `ro /etc/ssl`, `rof /etc/resolv.conf`, or `connect 443` and it should fail.
-
diff --git a/go.mod b/go.mod
@@ -1,9 +1,9 @@
module git.sr.ht/~marcc/landdown
-go 1.25
+go 1.25.0
require (
github.com/landlock-lsm/go-landlock v0.7.0 // indirect
- golang.org/x/sys v0.40.0 // indirect
+ golang.org/x/sys v0.42.0 // indirect
kernel.org/pub/linux/libs/security/libcap/psx v1.2.77 // indirect
)
diff --git a/go.sum b/go.sum
@@ -2,5 +2,7 @@ github.com/landlock-lsm/go-landlock v0.7.0 h1:gXz0+Phg3vddZjpPzXL4pQy/MgsTMHZBs+
github.com/landlock-lsm/go-landlock v0.7.0/go.mod h1:mn5GSi81Jf7yMs5WSi+SUi4sUeNLUGVdbT4Id6wXNQw=
golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ=
golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
+golang.org/x/sys v0.42.0 h1:omrd2nAlyT5ESRdCLYdm3+fMfNFE/+Rf4bDIQImRJeo=
+golang.org/x/sys v0.42.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
kernel.org/pub/linux/libs/security/libcap/psx v1.2.77 h1:Z06sMOzc0GNCwp6efaVrIrz4ywGJ1v+DP0pjVkOfDuA=
kernel.org/pub/linux/libs/security/libcap/psx v1.2.77/go.mod h1:+l6Ee2F59XiJ2I6WR5ObpC1utCQJZ/VLsEbQCD8RG24=
diff --git a/main.go b/main.go
@@ -11,6 +11,8 @@ import (
"strings"
"syscall"
+ "golang.org/x/sys/unix"
+
"github.com/landlock-lsm/go-landlock/landlock"
)
@@ -125,21 +127,18 @@ func main() {
argv := append(execCmd, extraArgs...)
env := os.Environ()
-
- // Replace file descriptor 0 with data after second shebang,
- // so the exec'd process gets the script content instead
- if len(stdinData) > 0 {
- r, w, err := os.Pipe()
+ // Create a memfile that is the content of the script
+ // we actually want to run, execute the script with that.
+ if len(stdinData) > 0 {
+ fd, err := unix.MemfdCreate("landdown", 0)
if err != nil {
- log.Fatalf("failed to create pipe: %v", err)
+ log.Fatalf("memfd_create failed: %v", err)
}
- go func() {
- w.Write(stdinData)
- w.Close()
- }()
- syscall.Dup2(int(r.Fd()), 0)
- r.Close()
- }
+ unix.Write(fd, stdinData)
+ // Rewind
+ unix.Seek(fd, 0, 0)
+ argv = append(argv, fmt.Sprintf("/dev/fd/%d", fd))
+ }
if err := syscall.Exec(fullPath, argv, env); err != nil {
log.Fatalf("failed to exec: %v", err)