Merge pull request #12945 from vrothberg/vendor-psgo

vendor c/psgo@v1.7.2
This commit is contained in:
OpenShift Merge Robot
2022-01-20 12:29:32 -05:00
committed by GitHub
8 changed files with 1063 additions and 78 deletions

2
go.mod
View File

@ -16,7 +16,7 @@ require (
github.com/containers/conmon v2.0.20+incompatible github.com/containers/conmon v2.0.20+incompatible
github.com/containers/image/v5 v5.18.0 github.com/containers/image/v5 v5.18.0
github.com/containers/ocicrypt v1.1.2 github.com/containers/ocicrypt v1.1.2
github.com/containers/psgo v1.7.1 github.com/containers/psgo v1.7.2
github.com/containers/storage v1.38.0 github.com/containers/storage v1.38.0
github.com/coreos/go-systemd/v22 v22.3.2 github.com/coreos/go-systemd/v22 v22.3.2
github.com/coreos/stream-metadata-go v0.0.0-20210225230131-70edb9eb47b3 github.com/coreos/stream-metadata-go v0.0.0-20210225230131-70edb9eb47b3

5
go.sum
View File

@ -333,8 +333,8 @@ github.com/containers/ocicrypt v1.1.0/go.mod h1:b8AOe0YR67uU8OqfVNcznfFpAzu3rdgU
github.com/containers/ocicrypt v1.1.1/go.mod h1:Dm55fwWm1YZAjYRaJ94z2mfZikIyIN4B0oB3dj3jFxY= github.com/containers/ocicrypt v1.1.1/go.mod h1:Dm55fwWm1YZAjYRaJ94z2mfZikIyIN4B0oB3dj3jFxY=
github.com/containers/ocicrypt v1.1.2 h1:Ez+GAMP/4GLix5Ywo/fL7O0nY771gsBIigiqUm1aXz0= github.com/containers/ocicrypt v1.1.2 h1:Ez+GAMP/4GLix5Ywo/fL7O0nY771gsBIigiqUm1aXz0=
github.com/containers/ocicrypt v1.1.2/go.mod h1:Dm55fwWm1YZAjYRaJ94z2mfZikIyIN4B0oB3dj3jFxY= github.com/containers/ocicrypt v1.1.2/go.mod h1:Dm55fwWm1YZAjYRaJ94z2mfZikIyIN4B0oB3dj3jFxY=
github.com/containers/psgo v1.7.1 h1:2N6KADeFvBm1aI2iXxu6+/Xh7CCkdh8p8F3F/cpIU5I= github.com/containers/psgo v1.7.2 h1:WbCvsY9w+nCv3j4der0mbD3PSRUv/W8l+G0YrZrdSDc=
github.com/containers/psgo v1.7.1/go.mod h1:mWGpFzW73qWFA+blhF6l7GuKzbrACkYgr/ajiNQR+RM= github.com/containers/psgo v1.7.2/go.mod h1:SLpqxsPOHtTqRygjutCPXmeU2PoEFzV3gzJplN4BMx0=
github.com/containers/storage v1.37.0/go.mod h1:kqeJeS0b7DO2ZT1nVWs0XufrmPFbgV3c+Q/45RlH6r4= github.com/containers/storage v1.37.0/go.mod h1:kqeJeS0b7DO2ZT1nVWs0XufrmPFbgV3c+Q/45RlH6r4=
github.com/containers/storage v1.37.1-0.20211119174841-bf170b3ddac0/go.mod h1:XjCNlt5JUUmRuTJXhFxHb9hHGPho7DNg3o4N/14prdQ= github.com/containers/storage v1.37.1-0.20211119174841-bf170b3ddac0/go.mod h1:XjCNlt5JUUmRuTJXhFxHb9hHGPho7DNg3o4N/14prdQ=
github.com/containers/storage v1.37.1-0.20211122164443-82b8f06bfc08/go.mod h1:hvKpaiPRALDI7oz4Jx+AEch8iS/viRnc22HPilQROWU= github.com/containers/storage v1.37.1-0.20211122164443-82b8f06bfc08/go.mod h1:hvKpaiPRALDI7oz4Jx+AEch8iS/viRnc22HPilQROWU=
@ -1585,7 +1585,6 @@ golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210816074244-15123e1e1f71/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210816074244-15123e1e1f71/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210816183151-1e6c022a8912/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210816183151-1e6c022a8912/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210817190340-bfb29a6856f2/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210820121016-41cdb8703e55/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210820121016-41cdb8703e55/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210906170528-6f6e22806c34/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210906170528-6f6e22806c34/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=

View File

@ -3,7 +3,8 @@ module github.com/containers/psgo
go 1.14 go 1.14
require ( require (
github.com/opencontainers/runc v1.0.2 github.com/containers/storage v1.38.0
github.com/opencontainers/runc v1.1.0
github.com/stretchr/testify v1.7.0 github.com/stretchr/testify v1.7.0
golang.org/x/sys v0.0.0-20210817190340-bfb29a6856f2 golang.org/x/sys v0.0.0-20220114195835-da31bd327af9
) )

File diff suppressed because it is too large Load Diff

View File

@ -19,13 +19,9 @@ import (
"fmt" "fmt"
"io" "io"
"os" "os"
)
type IDMap struct { "github.com/containers/storage/pkg/idtools"
ContainerID int )
HostID int
Size int
}
// ParsePIDNamespace returns the content of /proc/$pid/ns/pid. // ParsePIDNamespace returns the content of /proc/$pid/ns/pid.
func ParsePIDNamespace(pid string) (string, error) { func ParsePIDNamespace(pid string) (string, error) {
@ -46,14 +42,14 @@ func ParseUserNamespace(pid string) (string, error) {
} }
// ReadMappings reads the user namespace mappings at the specified path // ReadMappings reads the user namespace mappings at the specified path
func ReadMappings(path string) ([]IDMap, error) { func ReadMappings(path string) ([]idtools.IDMap, error) {
file, err := os.Open(path) file, err := os.Open(path)
if err != nil { if err != nil {
return nil, err return nil, err
} }
defer file.Close() defer file.Close()
mappings := []IDMap{} var mappings []idtools.IDMap
buf := bufio.NewReader(file) buf := bufio.NewReader(file)
for { for {
@ -68,10 +64,10 @@ func ReadMappings(path string) ([]IDMap, error) {
return mappings, nil return mappings, nil
} }
containerID, hostID, size := 0, 0, 0 var containerID, hostID, size int
if _, err := fmt.Sscanf(string(line), "%d %d %d", &containerID, &hostID, &size); err != nil { if _, err := fmt.Sscanf(string(line), "%d %d %d", &containerID, &hostID, &size); err != nil {
return nil, fmt.Errorf("cannot parse %s: %w", string(line), err) return nil, fmt.Errorf("cannot parse %s: %w", string(line), err)
} }
mappings = append(mappings, IDMap{ContainerID: containerID, HostID: hostID, Size: size}) mappings = append(mappings, idtools.IDMap{ContainerID: containerID, HostID: hostID, Size: size})
} }
} }

View File

@ -18,8 +18,11 @@ import (
"bufio" "bufio"
"fmt" "fmt"
"os" "os"
"os/exec" "strconv"
"strings" "strings"
"sync"
"github.com/containers/storage/pkg/idtools"
) )
// Status is a direct translation of a `/proc/[pid]/status`, which provides much // Status is a direct translation of a `/proc/[pid]/status`, which provides much
@ -173,23 +176,8 @@ type Status struct {
NonvoluntaryCtxtSwitches string NonvoluntaryCtxtSwitches string
} }
// readStatusUserNS joins the user namespace of pid and returns the content of // readStatus returns the content of /proc/pid/status as a string slice.
// /proc/pid/status as a string slice. func readStatus(pid string) ([]string, error) {
func readStatusUserNS(pid string) ([]string, error) {
path := fmt.Sprintf("/proc/%s/status", pid)
args := []string{"nsenter", "-U", "-t", pid, "cat", path}
c := exec.Command(args[0], args[1:]...)
output, err := c.CombinedOutput()
if err != nil {
return nil, fmt.Errorf("error executing %q: %w", strings.Join(args, " "), err)
}
return strings.Split(string(output), "\n"), nil
}
// readStatusDefault returns the content of /proc/pid/status as a string slice.
func readStatusDefault(pid string) ([]string, error) {
path := fmt.Sprintf("/proc/%s/status", pid) path := fmt.Sprintf("/proc/%s/status", pid)
f, err := os.Open(path) f, err := os.Open(path)
if err != nil { if err != nil {
@ -203,21 +191,81 @@ func readStatusDefault(pid string) ([]string, error) {
return lines, nil return lines, nil
} }
// ParseStatus parses the /proc/$pid/status file and returns a *Status. // mapField maps a single string-typed ID field given the set of mappings. If
func ParseStatus(pid string, joinUserNS bool) (*Status, error) { // no mapping exists, the overflow uid/gid is used.
var lines []string func mapStatusField(field *string, mapping []idtools.IDMap, overflow string) {
var err error hostId, err := strconv.Atoi(*field)
if err != nil {
if joinUserNS { *field = overflow
lines, err = readStatusUserNS(pid) return
} else {
lines, err = readStatusDefault(pid)
} }
contId, err := idtools.RawToContainer(hostId, mapping)
if err != nil {
*field = overflow
return
}
*field = strconv.Itoa(contId)
}
var (
overflowOnce sync.Once
overflowUid = "65534"
overflowGid = "65534"
)
func overflowIds() (string, string) {
overflowOnce.Do(func() {
if uid, err := os.ReadFile("/proc/sys/kernel/overflowuid"); err == nil {
overflowUid = strings.TrimSpace(string(uid))
}
if gid, err := os.ReadFile("/proc/sys/kernel/overflowgid"); err == nil {
overflowGid = strings.TrimSpace(string(gid))
}
})
return overflowUid, overflowGid
}
// mapStatus takes a Status struct and remaps all of the relevant fields to
// match the user namespace of the target process.
func mapStatus(pid string, status *Status) (*Status, error) {
uidMap, err := ReadMappings(fmt.Sprintf("/proc/%s/uid_map", pid))
if err != nil { if err != nil {
return nil, err return nil, err
} }
return parseStatus(pid, lines) gidMap, err := ReadMappings(fmt.Sprintf("/proc/%s/gid_map", pid))
if err != nil {
return nil, err
}
overflowUid, overflowGid := overflowIds()
for i := range status.Uids {
mapStatusField(&status.Uids[i], uidMap, overflowUid)
}
for i := range status.Gids {
mapStatusField(&status.Gids[i], gidMap, overflowGid)
}
for i := range status.Groups {
mapStatusField(&status.Groups[i], gidMap, overflowGid)
}
return status, nil
}
// ParseStatus parses the /proc/$pid/status file and returns a *Status.
func ParseStatus(pid string, mapUserNS bool) (*Status, error) {
lines, err := readStatus(pid)
if err != nil {
return nil, err
}
status, err := parseStatus(pid, lines)
if err != nil {
return nil, err
}
if mapUserNS {
status, err = mapStatus(pid, status)
if err != nil {
return nil, err
}
}
return status, nil
} }
// parseStatus extracts data from lines and returns a *Status. // parseStatus extracts data from lines and returns a *Status.

View File

@ -41,28 +41,18 @@ import (
"github.com/containers/psgo/internal/dev" "github.com/containers/psgo/internal/dev"
"github.com/containers/psgo/internal/proc" "github.com/containers/psgo/internal/proc"
"github.com/containers/psgo/internal/process" "github.com/containers/psgo/internal/process"
"github.com/containers/storage/pkg/idtools"
"golang.org/x/sys/unix" "golang.org/x/sys/unix"
) )
// IDMap specifies a mapping range from the host to the container IDs.
type IDMap struct {
// ContainerID is the first ID in the container.
ContainerID int
// HostID is the first ID in the host.
HostID int
// Size specifies how long is the range. e.g. 1 means a single user
// is mapped.
Size int
}
// JoinNamespaceOpts specifies different options for joining the specified namespaces. // JoinNamespaceOpts specifies different options for joining the specified namespaces.
type JoinNamespaceOpts struct { type JoinNamespaceOpts struct {
// UIDMap specifies a mapping for UIDs in the container. If specified // UIDMap specifies a mapping for UIDs in the container. If specified
// huser will perform the reverse mapping. // huser will perform the reverse mapping.
UIDMap []IDMap UIDMap []idtools.IDMap
// GIDMap specifies a mapping for GIDs in the container. If specified // GIDMap specifies a mapping for GIDs in the container. If specified
// hgroup will perform the reverse mapping. // hgroup will perform the reverse mapping.
GIDMap []IDMap GIDMap []idtools.IDMap
// FillMappings specified whether UIDMap and GIDMap must be initialized // FillMappings specified whether UIDMap and GIDMap must be initialized
// with the current user namespace. // with the current user namespace.
@ -102,7 +92,7 @@ type aixFormatDescriptor struct {
} }
// findID converts the specified id to the host mapping // findID converts the specified id to the host mapping
func findID(idStr string, mapping []IDMap, lookupFunc func(uid string) (string, error), overflowFile string) (string, error) { func findID(idStr string, mapping []idtools.IDMap, lookupFunc func(uid string) (string, error), overflowFile string) (string, error) {
if len(mapping) == 0 { if len(mapping) == 0 {
return idStr, nil return idStr, nil
} }
@ -350,29 +340,16 @@ func JoinNamespaceAndProcessInfo(pid string, descriptors []string) ([][]string,
return JoinNamespaceAndProcessInfoWithOptions(pid, descriptors, &JoinNamespaceOpts{}) return JoinNamespaceAndProcessInfoWithOptions(pid, descriptors, &JoinNamespaceOpts{})
} }
func readMappings(path string) ([]IDMap, error) {
mappings, err := proc.ReadMappings(path)
if err != nil {
return nil, err
}
var res []IDMap
for _, i := range mappings {
m := IDMap{ContainerID: i.ContainerID, HostID: i.HostID, Size: i.Size}
res = append(res, m)
}
return res, nil
}
func contextFromOptions(options *JoinNamespaceOpts) (*psContext, error) { func contextFromOptions(options *JoinNamespaceOpts) (*psContext, error) {
ctx := new(psContext) ctx := new(psContext)
ctx.opts = options ctx.opts = options
if ctx.opts != nil && ctx.opts.FillMappings { if ctx.opts != nil && ctx.opts.FillMappings {
uidMappings, err := readMappings("/proc/self/uid_map") uidMappings, err := proc.ReadMappings("/proc/self/uid_map")
if err != nil { if err != nil {
return nil, err return nil, err
} }
gidMappings, err := readMappings("/proc/self/gid_map") gidMappings, err := proc.ReadMappings("/proc/self/gid_map")
if err != nil { if err != nil {
return nil, err return nil, err
} }

2
vendor/modules.txt vendored
View File

@ -221,7 +221,7 @@ github.com/containers/ocicrypt/keywrap/pkcs7
github.com/containers/ocicrypt/spec github.com/containers/ocicrypt/spec
github.com/containers/ocicrypt/utils github.com/containers/ocicrypt/utils
github.com/containers/ocicrypt/utils/keyprovider github.com/containers/ocicrypt/utils/keyprovider
# github.com/containers/psgo v1.7.1 # github.com/containers/psgo v1.7.2
## explicit ## explicit
github.com/containers/psgo github.com/containers/psgo
github.com/containers/psgo/internal/capabilities github.com/containers/psgo/internal/capabilities