func listen()

in internal/command/command_linux.go [87:154]


func listen(ctx context.Context, pipe string, filemode int, grp string) (net.Listener, error) {
	if file.Exists(pipe, file.TypeFile) {
		// Unix sockets must be unlinked `listener.Close()` before it can be reused
		// again. If file already exist bind can fail. In case process crashes or
		// was being killed cleanup might not happen leaving behind the socket file.
		galog.Debugf("Command pipe %q already exists, cleaning up", pipe)
		if err := os.Remove(pipe); err != nil {
			return nil, fmt.Errorf("could not remove command pipe %q: %w", pipe, err)
		}
	}

	// 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 {
			galog.Warnf("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 {
				galog.Warnf("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(filepath.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
	commandListener, err := lc.Listen(ctx, "unix", pipe)
	syscall.Umask(oldmask)
	runtime.UnlockOSThread()
	if err != nil {
		return nil, fmt.Errorf("could not start listener on %q: %w", pipe, 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 {
		if err := commandListener.Close(); err != nil {
			galog.Errorf("error closing socket listener after failing to set ownership: %v", err)
		}
		return nil, err
	}
	return commandListener, nil
}