From db02e22dfa3df9bc9558f21e352071cb7475860e Mon Sep 17 00:00:00 2001 From: Kadin Sayani Date: Tue, 12 Nov 2024 07:24:46 -0700 Subject: [PATCH] lxd/device: Add `unixDeviceOwnership` function and change default ownership behaviour This commit adds a function `unixDeviceOwnership()` which returns device ownership (gid and uid). The new default ownerhship behaviour for unix devices is to use the host's ownership rule when no gid or uid is specified in the device config. If the ownership can't be identified, root (0) ownership is used. Signed-off-by: Kadin Sayani --- lxd/device/device_utils_unix.go | 30 +++++++++++++++++++++++------- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/lxd/device/device_utils_unix.go b/lxd/device/device_utils_unix.go index 6bb66cf9a6b5..1b5feb9ff1d6 100644 --- a/lxd/device/device_utils_unix.go +++ b/lxd/device/device_utils_unix.go @@ -45,6 +45,20 @@ func unixDeviceAttributes(path string) (dType string, major uint32, minor uint32 return dType, major, minor, nil } +// unixDeviceOwnership returns the ownership (gid and uid) for a device. +func unixDeviceOwnership(path string) (gid uint32, uid uint32, err error) { + stat := unix.Stat_t{} + err = unix.Stat(path, &stat) + if err != nil { + return 0, 0, err + } + + gid = stat.Gid + uid = stat.Uid + + return gid, uid, nil +} + // unixDeviceModeOct converts a string unix octal mode to an int. func unixDeviceModeOct(strmode string) (int, error) { i, err := strconv.ParseInt(strmode, 8, 32) @@ -91,13 +105,9 @@ func unixDeviceDestPath(m deviceConfig.Device) string { return destPath } -// UnixDeviceCreate creates a UNIX device (either block or char). If the supplied device config map -// contains a major and minor number for the device, then a stat is avoided, otherwise this info -// retrieved from the origin device. Similarly, if a mode is supplied in the device config map or -// defaultMode is set as true, then the device is created with the supplied or default mode (0660) -// respectively, otherwise the origin device's mode is used. If the device config doesn't contain a -// type field then it defaults to created a unix-char device. The ownership of the created device -// defaults to root (0) but can be specified with the uid and gid fields in the device config map. +// UnixDeviceCreate creates a UNIX device (either block or char). +// If the supplied device config map contains a major and minor number for the device, then a stat is avoided, otherwise this info retrieved from the origin device. Similarly, if a mode is supplied in the device config map or defaultMode is set as true, then the device is created with the supplied or default mode (0660)respectively, otherwise the origin device's mode is used. +// If the device config doesn't contain a type field then it defaults to created a unix-char device. The ownership of the created device defaults to the host's ownership but can be specified with the uid and gid fields in the device config map. If the host ownership can't be identified, root (0) ownership is applied to the device. // It returns a UnixDevice containing information about the device created. func UnixDeviceCreate(s *state.State, idmapSet *idmap.IdmapSet, devicesPath string, prefix string, m deviceConfig.Device, defaultMode bool) (*UnixDevice, error) { var err error @@ -176,6 +186,9 @@ func UnixDeviceCreate(s *state.State, idmapSet *idmap.IdmapSet, devicesPath stri if err != nil { return nil, fmt.Errorf("Invalid uid %s in device %s", m["uid"], srcPath) } + } else { + _, uid, _ := unixDeviceOwnership(srcPath) + d.UID = int(uid) } if m["gid"] != "" { @@ -183,6 +196,9 @@ func UnixDeviceCreate(s *state.State, idmapSet *idmap.IdmapSet, devicesPath stri if err != nil { return nil, fmt.Errorf("Invalid gid %s in device %s", m["gid"], srcPath) } + } else { + gid, _, _ := unixDeviceOwnership(srcPath) + d.GID = int(gid) } // Create the devices directory if missing.