Skip to content

Commit 74441f4

Browse files
committed
Add support for injecting additional GIDs
Signed-off-by: Evan Lezar <[email protected]>
1 parent 87f54c5 commit 74441f4

File tree

2 files changed

+61
-1
lines changed

2 files changed

+61
-1
lines changed

internal/edits/device.go

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@
1717
package edits
1818

1919
import (
20+
"os"
21+
22+
"golang.org/x/sys/unix"
2023
"tags.cncf.io/container-device-interface/pkg/cdi"
2124
"tags.cncf.io/container-device-interface/specs-go"
2225

@@ -32,9 +35,15 @@ func (d device) toEdits() (*cdi.ContainerEdits, error) {
3235
return nil, err
3336
}
3437

38+
var additionalGIDs []uint32
39+
if requiredGID, _ := d.getRequiredGID(); requiredGID != 0 {
40+
additionalGIDs = append(additionalGIDs, requiredGID)
41+
}
42+
3543
e := cdi.ContainerEdits{
3644
ContainerEdits: &specs.ContainerEdits{
37-
DeviceNodes: []*specs.DeviceNode{deviceNode},
45+
DeviceNodes: []*specs.DeviceNode{deviceNode},
46+
AdditionalGIDs: additionalGIDs,
3847
},
3948
}
4049
return &e, nil
@@ -52,10 +61,37 @@ func (d device) toSpec() (*specs.DeviceNode, error) {
5261
if hostPath == d.Path {
5362
hostPath = ""
5463
}
64+
5565
s := specs.DeviceNode{
5666
HostPath: hostPath,
5767
Path: d.Path,
5868
}
5969

6070
return &s, nil
6171
}
72+
73+
// getRequiredGID returns the group id of the device if the device is not world read/writable
74+
func (d device) getRequiredGID() (uint32, error) {
75+
path := d.HostPath
76+
if path == "" {
77+
path = d.Path
78+
}
79+
if path == "" {
80+
return 0, nil
81+
}
82+
83+
var stat unix.Stat_t
84+
if err := unix.Lstat(path, &stat); err != nil {
85+
return 0, err
86+
}
87+
// This is only supported for char devices
88+
if stat.Mode&unix.S_IFMT != unix.S_IFCHR {
89+
return 0, nil
90+
}
91+
92+
permissions := os.FileMode(stat.Mode).Perm()
93+
if permissions&06 == 0 {
94+
return stat.Gid, nil
95+
}
96+
return 0, nil
97+
}

pkg/nvcdi/transform/deduplicate.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
package transform
1818

1919
import (
20+
"slices"
21+
2022
"tags.cncf.io/container-device-interface/specs-go"
2123
)
2224

@@ -50,6 +52,12 @@ func (d dedupe) Transform(spec *specs.Spec) error {
5052
}
5153

5254
func (d dedupe) transformEdits(edits *specs.ContainerEdits) error {
55+
additionalGIDs, err := d.deduplicateAdditionalGIDs(edits.AdditionalGIDs)
56+
if err != nil {
57+
return err
58+
}
59+
edits.AdditionalGIDs = additionalGIDs
60+
5361
deviceNodes, err := d.deduplicateDeviceNodes(edits.DeviceNodes)
5462
if err != nil {
5563
return err
@@ -150,3 +158,19 @@ func (d dedupe) deduplicateMounts(entities []*specs.Mount) ([]*specs.Mount, erro
150158
}
151159
return mounts, nil
152160
}
161+
162+
func (d dedupe) deduplicateAdditionalGIDs(entities []uint32) ([]uint32, error) {
163+
seen := make(map[uint32]bool)
164+
var additionalGIDs []uint32
165+
for _, e := range entities {
166+
if seen[e] {
167+
continue
168+
}
169+
seen[e] = true
170+
additionalGIDs = append(additionalGIDs, e)
171+
}
172+
173+
slices.Sort(additionalGIDs)
174+
175+
return additionalGIDs, nil
176+
}

0 commit comments

Comments
 (0)