in google_guest_agent/command/command_linux.go [86:137]
func listen(ctx context.Context, pipe string, filemode int, grp string) (net.Listener, error) {
// If grp is an int, use it as a GID
gid, err := strconv.Atoi(grp)
if err != nil {
// Otherwise lookup GID
group, err := user.LookupGroup(grp)
if err != nil {
logger.Errorf("guest agent command pipe group %s is not a GID nor a valid group, not changing socket ownership", grp)
gid = -1
} else {
gid, err = strconv.Atoi(group.Gid)
if err != nil {
logger.Errorf("os reported group %s has gid %s which is not a valid int, not changing socket ownership. this should never happen", grp, group.Gid)
gid = -1
}
}
}
// socket owner group does not need to have permissions to everything in the directory containing it, whatever user and group we are should own that
user, err := user.Current()
if err != nil {
return nil, fmt.Errorf("could not lookup current user")
}
currentuid, err := strconv.Atoi(user.Uid)
if err != nil {
return nil, fmt.Errorf("os reported user %s has uid %s which is not a valid int, can't determine directory owner. this should never happen", user.Username, user.Uid)
}
currentgid, err := strconv.Atoi(user.Gid)
if err != nil {
return nil, fmt.Errorf("os reported user %s has gid %s which is not a valid int, can't determine directory owner. this should never happen", user.Username, user.Gid)
}
if err := mkdirpWithPerms(path.Dir(pipe), os.FileMode(filemode), currentuid, currentgid); err != nil {
return nil, err
}
// Mutating the umask of the process for this is not ideal, but tightening permissions with chown after creation is not really secure.
// Lock OS thread while mutating umask so we don't lose a thread with a mutated mask.
runtime.LockOSThread()
oldmask := syscall.Umask(777 - filemode)
var lc net.ListenConfig
l, err := lc.Listen(ctx, "unix", pipe)
syscall.Umask(oldmask)
runtime.UnlockOSThread()
if err != nil {
return nil, err
}
// But we need to chown anyway to loosen permissions to include whatever group the user has configured
err = os.Chown(pipe, int(currentuid), gid)
if err != nil {
l.Close()
return nil, err
}
return l, nil
}