summaryrefslogtreecommitdiff
path: root/libpod/container_internal_linux.go
diff options
context:
space:
mode:
authorPaul Holzinger <pholzing@redhat.com>2022-04-29 14:41:33 +0200
committerPaul Holzinger <pholzing@redhat.com>2022-04-29 15:30:55 +0200
commit5198209269eb8248eb001e02d39b3dd0dfce6c19 (patch)
treeaf0062125f903ee7ed87fa9751699d441d632ccd /libpod/container_internal_linux.go
parentab3e072a0c3d321fd12cbd1f6ef8e322c6d9214a (diff)
downloadpodman-5198209269eb8248eb001e02d39b3dd0dfce6c19.tar.gz
podman-5198209269eb8248eb001e02d39b3dd0dfce6c19.tar.bz2
podman-5198209269eb8248eb001e02d39b3dd0dfce6c19.zip
fix incorrect permissions for /etc/resolv.conf in userns
The files /etc/hosts, /etc/hostname and /etc/resolv.conf should always be owned by the root user in the container. This worked correct for /etc/hostname and /etc/hosts but not for /etc/resolv.conf. A container run with --userns keep-id would have the reolv.conf file owned by the current container user which is wrong. Consolidate some common code in a new helper function to make the code more cleaner. Signed-off-by: Paul Holzinger <pholzing@redhat.com>
Diffstat (limited to 'libpod/container_internal_linux.go')
-rw-r--r--libpod/container_internal_linux.go49
1 files changed, 21 insertions, 28 deletions
diff --git a/libpod/container_internal_linux.go b/libpod/container_internal_linux.go
index 31edff762..af6e7417b 100644
--- a/libpod/container_internal_linux.go
+++ b/libpod/container_internal_linux.go
@@ -2113,15 +2113,9 @@ func (c *Container) makeBindMounts() error {
}
} else {
if !c.config.UseImageResolvConf {
- newResolv, err := c.generateResolvConf()
- if err != nil {
+ if err := c.generateResolvConf(); err != nil {
return errors.Wrapf(err, "error creating resolv.conf for container %s", c.ID())
}
- err = c.mountIntoRootDirs("/etc/resolv.conf", newResolv)
-
- if err != nil {
- return errors.Wrapf(err, "error assigning mounts to container %s", c.ID())
- }
}
if !c.config.UseImageHosts {
@@ -2278,7 +2272,7 @@ rootless=%d
}
// generateResolvConf generates a containers resolv.conf
-func (c *Container) generateResolvConf() (string, error) {
+func (c *Container) generateResolvConf() error {
var (
nameservers []string
networkNameServers []string
@@ -2294,7 +2288,7 @@ func (c *Container) generateResolvConf() (string, error) {
if err == nil {
resolvConf = definedPath
} else if !os.IsNotExist(err) {
- return "", err
+ return err
}
}
break
@@ -2304,7 +2298,7 @@ func (c *Container) generateResolvConf() (string, error) {
contents, err := ioutil.ReadFile(resolvConf)
// resolv.conf doesn't have to exists
if err != nil && !os.IsNotExist(err) {
- return "", err
+ return err
}
ns := resolvconf.GetNameservers(contents)
@@ -2314,7 +2308,7 @@ func (c *Container) generateResolvConf() (string, error) {
resolvedContents, err := ioutil.ReadFile("/run/systemd/resolve/resolv.conf")
if err != nil {
if !os.IsNotExist(err) {
- return "", errors.Wrapf(err, "detected that systemd-resolved is in use, but could not locate real resolv.conf")
+ return errors.Wrapf(err, "detected that systemd-resolved is in use, but could not locate real resolv.conf")
}
} else {
contents = resolvedContents
@@ -2337,21 +2331,21 @@ func (c *Container) generateResolvConf() (string, error) {
ipv6, err := c.checkForIPv6(netStatus)
if err != nil {
- return "", err
+ return err
}
// Ensure that the container's /etc/resolv.conf is compatible with its
// network configuration.
resolv, err := resolvconf.FilterResolvDNS(contents, ipv6, c.config.CreateNetNS)
if err != nil {
- return "", errors.Wrapf(err, "error parsing host resolv.conf")
+ return errors.Wrapf(err, "error parsing host resolv.conf")
}
dns := make([]net.IP, 0, len(c.runtime.config.Containers.DNSServers)+len(c.config.DNSServer))
for _, i := range c.runtime.config.Containers.DNSServers {
result := net.ParseIP(i)
if result == nil {
- return "", errors.Wrapf(define.ErrInvalidArg, "invalid IP address %s", i)
+ return errors.Wrapf(define.ErrInvalidArg, "invalid IP address %s", i)
}
dns = append(dns, result)
}
@@ -2402,20 +2396,15 @@ func (c *Container) generateResolvConf() (string, error) {
destPath := filepath.Join(c.state.RunDir, "resolv.conf")
if err := os.Remove(destPath); err != nil && !os.IsNotExist(err) {
- return "", errors.Wrapf(err, "container %s", c.ID())
+ return errors.Wrapf(err, "container %s", c.ID())
}
// Build resolv.conf
if _, err = resolvconf.Build(destPath, nameservers, search, options); err != nil {
- return "", errors.Wrapf(err, "error building resolv.conf for container %s", c.ID())
+ return errors.Wrapf(err, "error building resolv.conf for container %s", c.ID())
}
- // Relabel resolv.conf for the container
- if err := c.relabel(destPath, c.config.MountLabel, true); err != nil {
- return "", err
- }
-
- return destPath, nil
+ return c.bindMountRootFile(destPath, "/etc/resolv.conf")
}
// Check if a container uses IPv6.
@@ -2590,17 +2579,21 @@ func (c *Container) createHosts() error {
return err
}
- if err := os.Chown(targetFile, c.RootUID(), c.RootGID()); err != nil {
+ return c.bindMountRootFile(targetFile, config.DefaultHostsFile)
+}
+
+// bindMountRootFile will chown and relabel the source file to make it usable in the container.
+// It will also add the path to the container bind mount map.
+// source is the path on the host, dest is the path in the container.
+func (c *Container) bindMountRootFile(source, dest string) error {
+ if err := os.Chown(source, c.RootUID(), c.RootGID()); err != nil {
return err
}
- if err := label.Relabel(targetFile, c.MountLabel(), false); err != nil {
+ if err := label.Relabel(source, c.MountLabel(), false); err != nil {
return err
}
- if err = c.mountIntoRootDirs(config.DefaultHostsFile, targetFile); err != nil {
- return err
- }
- return nil
+ return c.mountIntoRootDirs(dest, source)
}
// generateGroupEntry generates an entry or entries into /etc/group as