Skip to content

go.mod: experimental integration of gomodjail (library sandbox) #4012

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 1, 2025

Conversation

AkihiroSuda
Copy link
Member

@AkihiroSuda AkihiroSuda commented Mar 17, 2025

https://github.com/AkihiroSuda/gomodjail

gomodjail imposes syscall restrictions on a specific set of Go modules (excepts ones that use unsafe pointers, reflections, etc.), so as to mitigate their potential vulnerabilities and supply chain attack vectors.

Usage:

gomodjail run --go-mod=./go.mod -- nerdctl run hello-world

or

gomodjail pack --go-mod=./go.mod /usr/local/bin/nerdctl
./nerdctl.gomodjail run hello-world

Hint: use git diff --word-diff for reviewing the changes in this commit

@AkihiroSuda AkihiroSuda force-pushed the gomodjail branch 2 times, most recently from 3ec186f to 295ee0f Compare March 17, 2025 18:03
@AkihiroSuda AkihiroSuda added this to the v2.x.x milestone Mar 18, 2025
@AkihiroSuda AkihiroSuda force-pushed the gomodjail branch 11 times, most recently from 98c3108 to 8587b52 Compare March 18, 2025 08:27
@fahedouch
Copy link
Member

fahedouch commented Mar 18, 2025

@AkihiroSuda in the gomodjail project is there a plan to restrict specific system calls (e.g declarative configuration) for confined modules?

@AkihiroSuda
Copy link
Member Author

@AkihiroSuda in the gomodjail project is there a plan to restrict specific system calls (e.g declarative configuration) for confined modules?

Eventually we may have fine-grained policies, but practically just having "confined" and "unconfined" might be enough to avoid complicating it

@AkihiroSuda

This comment was marked as resolved.

@AkihiroSuda AkihiroSuda force-pushed the gomodjail branch 2 times, most recently from cbaa9da to d849498 Compare May 1, 2025 07:13
@AkihiroSuda AkihiroSuda marked this pull request as ready for review May 1, 2025 07:27
@AkihiroSuda
Copy link
Member Author

The more I think about this, the more I believe any temp location is a bad idea - they will get gc-ed eventually (on logout, on reboot) and this will break.

Sure, fixed in

https://github.com/AkihiroSuda/gomodjail

gomodjail imposes syscall restrictions on a specific set of Go modules (excepts ones that use unsafe pointers, reflections, etc.),
so as to mitigate their potential vulnerabilities and supply chain attack vectors.

Usage:
```
gomodjail run --go-mod=./go.mod -- nerdctl run hello-world
```

or

```
gomodjail pack --go-mod=./go.mod /usr/local/bin/nerdctl
./nerdctl.gomodjail run hello-world
```

Hint: use `git diff --word-diff` for reviewing the changes in this commit

Signed-off-by: Akihiro Suda <akihiro.suda.cz@hco.ntt.co.jp>
@apostasie
Copy link
Contributor

apostasie commented May 1, 2025

The more I think about this, the more I believe any temp location is a bad idea - they will get gc-ed eventually (on logout, on reboot) and this will break.

Sure, fixed in

Also thinking about this: is there a reason we are using (in nerdctl) os.Executable - instead of os.Args[0] + resolve path - for the binary path?

If there is no serious reason, then we may want to use os.Args[0] indeed - that way gomodjail could just spoof the first arg - from nerdctl perspective this would be transparent, and the logger would point to the gomodjail binary without relying on any non-portable inspection of the parent or any other change in nerdctl itself.

@AkihiroSuda
Copy link
Member Author

Also thinking about this: is there a reason we are using (in nerdctl) os.Executable - instead of os.Args[0] + resolve path - for the binary path?

os.Executable is more deterministic.

Anyway, gomodjail is not specifically made for nerdctl, and should support any application that depends on os.Executable

@ktock ktock merged commit 08b4cfb into containerd:main May 1, 2025
80 of 82 checks passed
@apostasie
Copy link
Contributor

Also thinking about this: is there a reason we are using (in nerdctl) os.Executable - instead of os.Args[0] + resolve path - for the binary path?

os.Executable is more deterministic.

Anyway, gomodjail is not specifically made for nerdctl, and should support any application that depends on os.Executable

To clarify: the suggestion was not to change anything for os.Executable neither to "not support it", but to enhance things for os.Args.

Anyhow, cool to have this.

@apostasie
Copy link
Contributor

That got merged fast...

I wish we just had a few hours to review after it moved out of draft?
Will leave some comments so that hopefully things can be addressed as a follow-up.

@@ -129,6 +130,8 @@ func TestRestartWithTime(t *testing.T) {
func TestRestartWithSignal(t *testing.T) {
testCase := nerdtest.Setup()

testCase.Require = require.Not(nerdtest.Gomodjail) // FIXME
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are there details on this, and other similar disabled tests?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test now seems to pass on my laptop (aarch64).

Probably it was failing due to a flakiness or something specific to CI.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, felt like leftover.

@@ -721,13 +721,21 @@ func newBase(t *testing.T, ns string, ipv6Compatible bool, kubernetesCompatible
var err error
switch base.Target {
case Nerdctl:
base.Binary, err = exec.LookPath("nerdctl")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Curious if there was something preventing us to use the existing mechanism (-test.target=nerdctl.gomodjail) instead of adding this extra layer?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are welcome ;-).

@@ -101,6 +101,8 @@ type Helpers interface {
// a Setup or Cleanup routine, and as the basis of any type of helper.
// For more powerful use-cases outside of test cases, see below CustomizableCommand.
type TestableCommand interface {
// Binary returns what binary to execute.
Binary() string
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we should have this, at this point.
Unless I am missing something, the existing mechanism (--test.target) was meant to allow customization of the tested binary for use cases like this, without having to resort to augmentation of the TestableCommand interface.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Plus getTarget would have worked just fine instead of introducing this.

@apostasie
Copy link
Contributor

More generally, this also ignore the fact that tests do hardcode "nerdctl" when they want to bypass the default command wrapping with namespace=nerdctl-test.
This is the case specifically for completion tests.
So, currently, some tests are just not testing nerdctl.gomodjail.

These should have been modified too to accommodate for testing a differently named "nerdish-ctl" binary.

This ^ in itself is desirable (and needed) for people who want to roll their own cli, but should be done right.

if env := os.Getenv("DOCKER"); env != "" {
docker = env
}
base.Binary, err = exec.LookPath(docker)
if err != nil {
t.Fatal(err)
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The same modifications as in nerdtest/command should have been applied here (eg: exec.Command(base.Binary))

apostasie added a commit to apostasie/nerdctl that referenced this pull request May 1, 2025
Signed-off-by: apostasie <spam_blackhole@farcloser.world>
apostasie added a commit to apostasie/nerdctl that referenced this pull request May 1, 2025
Signed-off-by: apostasie <spam_blackhole@farcloser.world>
apostasie added a commit to apostasie/nerdctl that referenced this pull request May 2, 2025
Signed-off-by: apostasie <spam_blackhole@farcloser.world>
apostasie added a commit to apostasie/nerdctl that referenced this pull request May 2, 2025
Signed-off-by: apostasie <spam_blackhole@farcloser.world>
apostasie added a commit to apostasie/nerdctl that referenced this pull request May 2, 2025
Signed-off-by: apostasie <spam_blackhole@farcloser.world>
apostasie added a commit to apostasie/nerdctl that referenced this pull request May 2, 2025
Signed-off-by: apostasie <spam_blackhole@farcloser.world>
apostasie added a commit to apostasie/nerdctl that referenced this pull request May 2, 2025
Signed-off-by: apostasie <spam_blackhole@farcloser.world>
AkihiroSuda added a commit that referenced this pull request May 3, 2025
[FIX]: #4012 follow-ups (fixes and target test binaries)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants