[lxc-devel] [lxd/master] Implement security.uid and security.gid for proxy devices

stgraber on Github lxc-bot at linuxcontainers.org
Wed Jul 11 05:32:13 UTC 2018


A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 301 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20180711/dfeeafc6/attachment.bin>
-------------- next part --------------
From 5fe6f782a863a5ae7875e21a37f8ee728e695652 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Wed, 11 Jul 2018 00:47:14 -0400
Subject: [PATCH 1/2] doc: Document uid/gid/mode for proxy
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Stéphane Graber <stgraber at ubuntu.com>
---
 doc/containers.md | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/doc/containers.md b/doc/containers.md
index 849432cfd..fe4305710 100644
--- a/doc/containers.md
+++ b/doc/containers.md
@@ -448,6 +448,9 @@ Key         | Type      | Default           | Required  | Description
 listen      | string    | -                 | yes       | The address and port to bind and listen
 connect     | string    | -                 | yes       | The address and port to connect to
 bind        | string    | host              | no        | Which side to bind on (host/container)
+uid         | int       | 0                 | no        | UID of the owner of the listening Unix socket
+gid         | int       | 0                 | no        | GID of the owner of the listening Unix socket
+mode        | int       | 0660              | no        | Mode for the listening Unix socket
 
 ```
 lxc config device add <container> <device-name> proxy listen=<type>:<addr>:<port>[-<port>][,<port>] connect=<type>:<addr>:<port> bind=<host/container>

From 4ba2f3d894d3790dceaf11097eb496faa3953233 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Wed, 11 Jul 2018 01:29:33 -0400
Subject: [PATCH 2/2] proxy: Implement security.{uid,gid} for priv drop
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Closes #4768

Signed-off-by: Stéphane Graber <stgraber at ubuntu.com>
---
 doc/api-extensions.md     |  5 +++++
 doc/containers.md         | 18 ++++++++++--------
 lxd/container.go          |  4 ++++
 lxd/container_lxc.go      |  4 +++-
 lxd/main_forkproxy.go     | 29 +++++++++++++++++++++++++++--
 lxd/proxy_device_utils.go |  4 ++++
 shared/version/api.go     |  1 +
 7 files changed, 54 insertions(+), 11 deletions(-)

diff --git a/doc/api-extensions.md b/doc/api-extensions.md
index a16527207..32e930b9d 100644
--- a/doc/api-extensions.md
+++ b/doc/api-extensions.md
@@ -540,3 +540,8 @@ sockets.
 ## container\_protection\_delete
 Enables setting the `security.protection.delete` field which prevents containers
 from being deleted if set to true. Snapshots are not affected by this setting.
+
+## proxy\_priv\_drop
+Adds security.uid and security.gid for the proxy devices, allowing
+privilege dropping and effectively changing the uid/gid used for
+connections to Unix sockets too.
diff --git a/doc/containers.md b/doc/containers.md
index fe4305710..0f3f9af63 100644
--- a/doc/containers.md
+++ b/doc/containers.md
@@ -443,14 +443,16 @@ The supported connection types are:
 * `UDP <-> UNIX`
 * `UNIX <-> UDP`
 
-Key         | Type      | Default           | Required  | Description
-:--         | :--       | :--               | :--       | :--
-listen      | string    | -                 | yes       | The address and port to bind and listen
-connect     | string    | -                 | yes       | The address and port to connect to
-bind        | string    | host              | no        | Which side to bind on (host/container)
-uid         | int       | 0                 | no        | UID of the owner of the listening Unix socket
-gid         | int       | 0                 | no        | GID of the owner of the listening Unix socket
-mode        | int       | 0660              | no        | Mode for the listening Unix socket
+Key             | Type      | Default           | Required  | Description
+:--             | :--       | :--               | :--       | :--
+listen          | string    | -                 | yes       | The address and port to bind and listen
+connect         | string    | -                 | yes       | The address and port to connect to
+bind            | string    | host              | no        | Which side to bind on (host/container)
+uid             | int       | 0                 | no        | UID of the owner of the listening Unix socket
+gid             | int       | 0                 | no        | GID of the owner of the listening Unix socket
+mode            | int       | 0755              | no        | Mode for the listening Unix socket
+security.uid    | int       | 0                 | no        | What UID to drop privilege to
+security.gid    | int       | 0                 | no        | What GID to drop privilege to
 
 ```
 lxc config device add <container> <device-name> proxy listen=<type>:<addr>:<port>[-<port>][,<port>] connect=<type>:<addr>:<port> bind=<host/container>
diff --git a/lxd/container.go b/lxd/container.go
index 2e4f6c440..d748aa597 100644
--- a/lxd/container.go
+++ b/lxd/container.go
@@ -237,6 +237,10 @@ func containerValidDeviceConfigKey(t, k string) bool {
 			return true
 		case "mode":
 			return true
+		case "security.gid":
+			return true
+		case "security.uid":
+			return true
 		case "uid":
 			return true
 		default:
diff --git a/lxd/container_lxc.go b/lxd/container_lxc.go
index 2b20819d8..2cee8ad1d 100644
--- a/lxd/container_lxc.go
+++ b/lxd/container_lxc.go
@@ -6871,7 +6871,9 @@ func (c *containerLXC) insertProxyDevice(devName string, m types.Device) error {
 		pidPath,
 		proxyValues.listenAddrGid,
 		proxyValues.listenAddrUid,
-		proxyValues.listenAddrMode)
+		proxyValues.listenAddrMode,
+		proxyValues.securityGid,
+		proxyValues.securityUid)
 	if err != nil {
 		return fmt.Errorf("Error occurred when starting proxy device: %s", err)
 	}
diff --git a/lxd/main_forkproxy.go b/lxd/main_forkproxy.go
index cdf942230..4f6d94ca1 100644
--- a/lxd/main_forkproxy.go
+++ b/lxd/main_forkproxy.go
@@ -299,7 +299,7 @@ type udpSession struct {
 func (c *cmdForkproxy) Command() *cobra.Command {
 	// Main subcommand
 	cmd := &cobra.Command{}
-	cmd.Use = "forkproxy <listen PID> <listen address> <connect PID> <connect address> <fd> <reexec> <log path> <pid path>"
+	cmd.Use = "forkproxy <listen PID> <listen address> <connect PID> <connect address> <log path> <pid path> <listen gid> <listen uid> <listen mode> <security gid> <security uid>"
 	cmd.Short = "Setup network connection proxying"
 	cmd.Long = `Description:
   Setup network connection proxying
@@ -403,7 +403,7 @@ func (c *cmdForkproxy) Run(cmd *cobra.Command, args []string) error {
 	}
 
 	// Sanity checks
-	if len(args) != 9 {
+	if len(args) != 11 {
 		cmd.Help()
 
 		if len(args) == 0 {
@@ -556,6 +556,31 @@ func (c *cmdForkproxy) Run(cmd *cobra.Command, args []string) error {
 		}
 	}
 
+	// Drop privilege if requested
+	if args[9] != "" {
+		gid, err := strconv.ParseInt(args[9], 10, 32)
+		if err != nil {
+			return err
+		}
+
+		errno := C.setgid(C.__gid_t(gid))
+		if errno < 0 {
+			return fmt.Errorf("setgid: %v", errno)
+		}
+	}
+
+	if args[10] != "" {
+		uid, err := strconv.ParseInt(args[10], 10, 32)
+		if err != nil {
+			return err
+		}
+
+		errno := C.setuid(C.__uid_t(uid))
+		if errno < 0 {
+			return fmt.Errorf("setuid: %v", errno)
+		}
+	}
+
 	// Handle SIGTERM which is sent when the proxy is to be removed
 	sigs := make(chan os.Signal, 1)
 	signal.Notify(sigs, syscall.SIGTERM)
diff --git a/lxd/proxy_device_utils.go b/lxd/proxy_device_utils.go
index 30733af2b..176feb757 100644
--- a/lxd/proxy_device_utils.go
+++ b/lxd/proxy_device_utils.go
@@ -21,6 +21,8 @@ type proxyProcInfo struct {
 	listenAddrGid  string
 	listenAddrUid  string
 	listenAddrMode string
+	securityUid    string
+	securityGid    string
 }
 
 func setupProxyProcInfo(c container, device map[string]string) (*proxyProcInfo, error) {
@@ -64,6 +66,8 @@ func setupProxyProcInfo(c container, device map[string]string) (*proxyProcInfo,
 		listenAddrGid:  device["gid"],
 		listenAddrUid:  device["uid"],
 		listenAddrMode: device["mode"],
+		securityGid:    device["security.gid"],
+		securityUid:    device["security.uid"],
 	}
 
 	return p, nil
diff --git a/shared/version/api.go b/shared/version/api.go
index 3a673206f..56a455d97 100644
--- a/shared/version/api.go
+++ b/shared/version/api.go
@@ -113,6 +113,7 @@ var APIExtensions = []string{
 	"network_state",
 	"proxy_unix_dac_properties",
 	"container_protection_delete",
+	"unix_priv_drop",
 }
 
 // APIExtensionsCount returns the number of available API extensions.


More information about the lxc-devel mailing list