Skip to content

Commit 317922e

Browse files
committed
Respect the UMASK env var
When a container is launched with a UMASK value or the UMASK value is set in a launch environment then respect that value Signed-off-by: adelaney21 <[email protected]>
1 parent c3d936f commit 317922e

File tree

4 files changed

+114
-0
lines changed

4 files changed

+114
-0
lines changed

launch/launcher.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,11 @@ func (l *Launcher) LaunchProcess(self string, proc Process) error {
6969
}
7070
proc.WorkingDirectory = getProcessWorkingDirectory(proc, l.AppDir)
7171

72+
err := SetUmask(l.Env)
73+
if err != nil {
74+
return errors.Wrap(err, "umask")
75+
}
76+
7277
if proc.Direct {
7378
return l.launchDirect(proc)
7479
}

launch/umask_unix.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
//go:build unix
2+
3+
package launch
4+
5+
import (
6+
"strconv"
7+
"syscall"
8+
9+
"github.com/pkg/errors"
10+
)
11+
12+
// SetUmask on unix systems from the value in the `UMASK` environment variable
13+
func SetUmask(env Env) error {
14+
return SetUmaskWith(env, syscall.Umask)
15+
}
16+
17+
// SetUmaskWith the injected function umaskFn
18+
func SetUmaskWith(env Env, umaskFn func(int) int) error {
19+
if umask := env.Get("UMASK"); umask != "" {
20+
u, err := strconv.ParseInt(umask, 8, 0)
21+
if err != nil {
22+
return errors.Wrap(err, "invalid umask value")
23+
}
24+
umaskFn(int(u))
25+
}
26+
return nil
27+
}

launch/umask_unix_test.go

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
//go:build unix
2+
3+
package launch_test
4+
5+
import (
6+
"testing"
7+
8+
"github.com/sclevine/spec"
9+
"github.com/sclevine/spec/report"
10+
11+
"github.com/buildpacks/lifecycle/env"
12+
"github.com/buildpacks/lifecycle/launch"
13+
h "github.com/buildpacks/lifecycle/testhelpers"
14+
)
15+
16+
func TestUmask(t *testing.T) {
17+
spec.Run(t, "Umask", testUmask, spec.Report(report.Terminal{}))
18+
}
19+
20+
func testUmask(t *testing.T, when spec.G, it spec.S) {
21+
when("UMASK is set", func() {
22+
it("parses octal umask values", func() {
23+
tests := []struct {
24+
name string
25+
umask string
26+
expected int
27+
}{
28+
{"standard user umask", "0002", 2},
29+
{"restrictive umask", "0077", 63},
30+
{"permissive umask", "0000", 0},
31+
{"three digit umask", "022", 18},
32+
}
33+
34+
for _, tt := range tests {
35+
t.Run(tt.name, func(t *testing.T) {
36+
environ := env.NewLaunchEnv([]string{"UMASK=" + tt.umask}, "", "")
37+
38+
var called int
39+
spy := func(m int) int {
40+
called = m
41+
return 0
42+
}
43+
44+
err := launch.SetUmaskWith(environ, spy)
45+
46+
h.AssertNil(t, err)
47+
h.AssertEq(t, called, tt.expected)
48+
})
49+
}
50+
})
51+
52+
it("returns error for invalid umask", func() {
53+
environ := env.NewLaunchEnv([]string{"UMASK=invalid"}, "", "")
54+
55+
err := launch.SetUmaskWith(environ, func(int) int { return 0 })
56+
57+
h.AssertNotNil(t, err)
58+
})
59+
})
60+
61+
when("UMASK is unset", func() {
62+
it("does not call umask function", func() {
63+
environ := env.NewLaunchEnv([]string{}, "", "")
64+
65+
called := false
66+
spy := func(_ int) int {
67+
called = true
68+
return 0
69+
}
70+
71+
err := launch.SetUmaskWith(environ, spy)
72+
73+
h.AssertNil(t, err)
74+
h.AssertEq(t, called, false)
75+
})
76+
})
77+
}

launch/umask_windows.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package launch
2+
3+
func SetUmask(env Env) {
4+
// no operation
5+
}

0 commit comments

Comments
 (0)