Skip to content

Commit 7a5daa0

Browse files
Merge pull request #18492 from daw1012345/main
Ensure the consistent setting of the HOME env variable on container start
2 parents c4e648f + 01e2081 commit 7a5daa0

File tree

2 files changed

+124
-20
lines changed

2 files changed

+124
-20
lines changed

libpod/container_internal_common.go

Lines changed: 39 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -459,15 +459,9 @@ func (c *Container) generateSpec(ctx context.Context) (s *spec.Spec, cleanupFunc
459459
g.AddMount(overlayMount)
460460
}
461461

462-
hasHomeSet := false
463-
for _, s := range c.config.Spec.Process.Env {
464-
if strings.HasPrefix(s, "HOME=") {
465-
hasHomeSet = true
466-
break
467-
}
468-
}
469-
if !hasHomeSet && execUser.Home != "" {
470-
c.config.Spec.Process.Env = append(c.config.Spec.Process.Env, fmt.Sprintf("HOME=%s", execUser.Home))
462+
err = c.setHomeEnvIfNeeded()
463+
if err != nil {
464+
return nil, nil, err
471465
}
472466

473467
if c.config.User != "" {
@@ -2432,6 +2426,41 @@ func (c *Container) generateCurrentUserPasswdEntry() (string, int, int, error) {
24322426
return pwd, uid, rootless.GetRootlessGID(), nil
24332427
}
24342428

2429+
// Sets the HOME env. variable with precedence: existing home env. variable, execUser home
2430+
func (c *Container) setHomeEnvIfNeeded() error {
2431+
getExecUserHome := func() (string, error) {
2432+
overrides := c.getUserOverrides()
2433+
execUser, err := lookup.GetUserGroupInfo(c.state.Mountpoint, c.config.User, overrides)
2434+
if err != nil {
2435+
if cutil.StringInSlice(c.config.User, c.config.HostUsers) {
2436+
execUser, err = lookupHostUser(c.config.User)
2437+
}
2438+
2439+
if err != nil {
2440+
return "", err
2441+
}
2442+
}
2443+
2444+
return execUser.Home, nil
2445+
}
2446+
2447+
// Ensure HOME is not already set in Env
2448+
home := ""
2449+
for _, s := range c.config.Spec.Process.Env {
2450+
if strings.HasPrefix(s, "HOME=") {
2451+
return nil
2452+
}
2453+
}
2454+
2455+
home, err := getExecUserHome()
2456+
if err != nil {
2457+
return err
2458+
}
2459+
2460+
c.config.Spec.Process.Env = append(c.config.Spec.Process.Env, fmt.Sprintf("HOME=%s", home))
2461+
return nil
2462+
}
2463+
24352464
func (c *Container) userPasswdEntry(u *user.User) (string, error) {
24362465
// Look up the user to see if it exists in the container image.
24372466
_, err := lookup.GetUser(c.state.Mountpoint, u.Username)
@@ -2464,17 +2493,7 @@ func (c *Container) userPasswdEntry(u *user.User) (string, error) {
24642493
}
24652494
}
24662495
}
2467-
// Set HOME environment if not already set
2468-
hasHomeSet := false
2469-
for _, s := range c.config.Spec.Process.Env {
2470-
if strings.HasPrefix(s, "HOME=") {
2471-
hasHomeSet = true
2472-
break
2473-
}
2474-
}
2475-
if !hasHomeSet {
2476-
c.config.Spec.Process.Env = append(c.config.Spec.Process.Env, fmt.Sprintf("HOME=%s", homeDir))
2477-
}
2496+
24782497
if c.config.PasswdEntry != "" {
24792498
return c.passwdEntry(u.Username, u.Uid, u.Gid, u.Name, homeDir), nil
24802499
}

test/e2e/start_test.go

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,4 +249,89 @@ var _ = Describe("Podman start", func() {
249249
Expect(session1).Should(Exit(0))
250250
Expect(session1.OutputToString()).To(BeEquivalentTo(cid2))
251251
})
252+
253+
It("podman start container does not set HOME to home of caller", func() {
254+
home, err := os.UserHomeDir()
255+
Expect(err).ToNot(HaveOccurred())
256+
session := podmanTest.Podman([]string{"create", "--userns", "keep-id", "--user", "bin:bin", "--volume", fmt.Sprintf("%s:%s:ro", home, home), ALPINE, "ls"})
257+
session.WaitWithDefaultTimeout()
258+
Expect(session).Should(Exit(0))
259+
cid := session.OutputToString()
260+
261+
session = podmanTest.Podman([]string{"start", cid})
262+
session.WaitWithDefaultTimeout()
263+
Expect(session).Should(Exit(0))
264+
265+
session = podmanTest.Podman([]string{"inspect", cid, "--format", "{{.Config.Env}}"})
266+
session.WaitWithDefaultTimeout()
267+
Expect(session).Should(Exit(0))
268+
env := session.OutputToString()
269+
Expect(env).To(ContainSubstring("HOME"))
270+
Expect(env).ToNot(ContainSubstring(fmt.Sprintf("HOME=%s", home)))
271+
272+
session = podmanTest.Podman([]string{"restart", cid})
273+
session.WaitWithDefaultTimeout()
274+
Expect(session).Should(Exit(0))
275+
276+
session = podmanTest.Podman([]string{"inspect", cid, "--format", "{{.Config.Env}}"})
277+
session.WaitWithDefaultTimeout()
278+
Expect(session).Should(Exit(0))
279+
env = session.OutputToString()
280+
Expect(env).To(ContainSubstring("HOME"))
281+
Expect(env).ToNot(ContainSubstring(fmt.Sprintf("HOME=%s", home)))
282+
})
283+
284+
It("podman start container sets HOME to home of execUser", func() {
285+
session := podmanTest.Podman([]string{"create", "--userns", "keep-id", "--user", "bin:bin", ALPINE, "ls"})
286+
session.WaitWithDefaultTimeout()
287+
Expect(session).Should(Exit(0))
288+
cid := session.OutputToString()
289+
290+
session = podmanTest.Podman([]string{"start", cid})
291+
session.WaitWithDefaultTimeout()
292+
Expect(session).Should(Exit(0))
293+
294+
session = podmanTest.Podman([]string{"inspect", cid, "--format", "{{.Config.Env}}"})
295+
session.WaitWithDefaultTimeout()
296+
Expect(session).Should(Exit(0))
297+
env := session.OutputToString()
298+
Expect(env).To(ContainSubstring("HOME=/bin"))
299+
300+
session = podmanTest.Podman([]string{"restart", cid})
301+
session.WaitWithDefaultTimeout()
302+
Expect(session).Should(Exit(0))
303+
304+
session = podmanTest.Podman([]string{"inspect", cid, "--format", "{{.Config.Env}}"})
305+
session.WaitWithDefaultTimeout()
306+
Expect(session).Should(Exit(0))
307+
env = session.OutputToString()
308+
Expect(env).To(ContainSubstring("HOME=/bin"))
309+
})
310+
311+
It("podman start container retains the HOME env if present", func() {
312+
session := podmanTest.Podman([]string{"create", "--userns", "keep-id", "--user", "bin:bin", "--env=HOME=/env/is/respected", ALPINE, "ls"})
313+
session.WaitWithDefaultTimeout()
314+
Expect(session).Should(Exit(0))
315+
cid := session.OutputToString()
316+
317+
session = podmanTest.Podman([]string{"start", cid})
318+
session.WaitWithDefaultTimeout()
319+
Expect(session).Should(Exit(0))
320+
321+
session = podmanTest.Podman([]string{"inspect", cid, "--format", "{{.Config.Env}}"})
322+
session.WaitWithDefaultTimeout()
323+
Expect(session).Should(Exit(0))
324+
env := session.OutputToString()
325+
Expect(env).To(ContainSubstring("HOME=/env/is/respected"))
326+
327+
session = podmanTest.Podman([]string{"restart", cid})
328+
session.WaitWithDefaultTimeout()
329+
Expect(session).Should(Exit(0))
330+
331+
session = podmanTest.Podman([]string{"inspect", cid, "--format", "{{.Config.Env}}"})
332+
session.WaitWithDefaultTimeout()
333+
Expect(session).Should(Exit(0))
334+
env = session.OutputToString()
335+
Expect(env).To(ContainSubstring("HOME=/env/is/respected"))
336+
})
252337
})

0 commit comments

Comments
 (0)