diff --git a/go.mod b/go.mod index ad0353f2c73..77b0fc399ec 100644 --- a/go.mod +++ b/go.mod @@ -9,7 +9,7 @@ require ( github.com/coreos/go-systemd/v22 v22.3.2 github.com/cyphar/filepath-securejoin v0.2.3 github.com/docker/go-units v0.4.0 - github.com/godbus/dbus/v5 v5.0.6 + github.com/godbus/dbus/v5 v5.1.0 github.com/moby/sys/mountinfo v0.6.0 github.com/mrunalp/fileutils v0.5.0 github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417 diff --git a/go.sum b/go.sum index 04ceb30fa8f..b8fd686db87 100644 --- a/go.sum +++ b/go.sum @@ -19,8 +19,8 @@ github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDD github.com/frankban/quicktest v1.14.0 h1:+cqqvzZV87b4adx/5ayVOaYZ2CrvM4ejQvUdBzPPUss= github.com/frankban/quicktest v1.14.0/go.mod h1:NeW+ay9A/U67EYXNFA1nPE8e/tnQv/09mUdL/ijj8og= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= -github.com/godbus/dbus/v5 v5.0.6 h1:mkgN1ofwASrYnJ5W6U/BxG15eXXXjirgZc7CLqkcaro= -github.com/godbus/dbus/v5 v5.0.6/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk= +github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ= diff --git a/vendor/github.com/godbus/dbus/v5/auth.go b/vendor/github.com/godbus/dbus/v5/auth.go index a59b4c0eb76..0f3b252c070 100644 --- a/vendor/github.com/godbus/dbus/v5/auth.go +++ b/vendor/github.com/godbus/dbus/v5/auth.go @@ -176,9 +176,10 @@ func (conn *Conn) tryAuth(m Auth, state authState, in *bufio.Reader) (error, boo return err, false } state = waitingForReject + } else { + conn.uuid = string(s[1]) + return nil, true } - conn.uuid = string(s[1]) - return nil, true case state == waitingForData: err = authWriteLine(conn.transport, []byte("ERROR")) if err != nil { @@ -191,9 +192,10 @@ func (conn *Conn) tryAuth(m Auth, state authState, in *bufio.Reader) (error, boo return err, false } state = waitingForReject + } else { + conn.uuid = string(s[1]) + return nil, true } - conn.uuid = string(s[1]) - return nil, true case state == waitingForOk && string(s[0]) == "DATA": err = authWriteLine(conn.transport, []byte("DATA")) if err != nil { diff --git a/vendor/github.com/godbus/dbus/v5/conn.go b/vendor/github.com/godbus/dbus/v5/conn.go index 76fc5cde3d2..69978ea26ab 100644 --- a/vendor/github.com/godbus/dbus/v5/conn.go +++ b/vendor/github.com/godbus/dbus/v5/conn.go @@ -169,7 +169,7 @@ func Connect(address string, opts ...ConnOption) (*Conn, error) { // SystemBusPrivate returns a new private connection to the system bus. // Note: this connection is not ready to use. One must perform Auth and Hello -// on the connection before it is useable. +// on the connection before it is usable. func SystemBusPrivate(opts ...ConnOption) (*Conn, error) { return Dial(getSystemBusPlatformAddress(), opts...) } @@ -284,10 +284,6 @@ func newConn(tr transport, opts ...ConnOption) (*Conn, error) { conn.ctx = context.Background() } conn.ctx, conn.cancelCtx = context.WithCancel(conn.ctx) - go func() { - <-conn.ctx.Done() - conn.Close() - }() conn.calls = newCallTracker() if conn.handler == nil { @@ -302,6 +298,11 @@ func newConn(tr transport, opts ...ConnOption) (*Conn, error) { conn.outHandler = &outputHandler{conn: conn} conn.names = newNameTracker() conn.busObj = conn.Object("org.freedesktop.DBus", "/org/freedesktop/DBus") + + go func() { + <-conn.ctx.Done() + conn.Close() + }() return conn, nil } @@ -550,6 +551,11 @@ func (conn *Conn) send(ctx context.Context, msg *Message, ch chan *Call) *Call { call.ctx = ctx call.ctxCanceler = canceler conn.calls.track(msg.serial, call) + if ctx.Err() != nil { + // short path: don't even send the message if context already cancelled + conn.calls.handleSendError(msg, ctx.Err()) + return call + } go func() { <-ctx.Done() conn.calls.handleSendError(msg, ctx.Err()) @@ -649,7 +655,9 @@ func (conn *Conn) RemoveMatchSignalContext(ctx context.Context, options ...Match // Signal registers the given channel to be passed all received signal messages. // -// Multiple of these channels can be registered at the same time. +// Multiple of these channels can be registered at the same time. The channel is +// closed if the Conn is closed; it should not be closed by the caller before +// RemoveSignal was called on it. // // These channels are "overwritten" by Eavesdrop; i.e., if there currently is a // channel for eavesdropped messages, this channel receives all signals, and @@ -765,7 +773,12 @@ func getKey(s, key string) string { for _, keyEqualsValue := range strings.Split(s, ",") { keyValue := strings.SplitN(keyEqualsValue, "=", 2) if len(keyValue) == 2 && keyValue[0] == key { - return keyValue[1] + val, err := UnescapeBusAddressValue(keyValue[1]) + if err != nil { + // No way to return an error. + return "" + } + return val } } return "" diff --git a/vendor/github.com/godbus/dbus/v5/conn_other.go b/vendor/github.com/godbus/dbus/v5/conn_other.go index 616dcf66449..90289ca85a2 100644 --- a/vendor/github.com/godbus/dbus/v5/conn_other.go +++ b/vendor/github.com/godbus/dbus/v5/conn_other.go @@ -54,7 +54,7 @@ func tryDiscoverDbusSessionBusAddress() string { if runUserBusFile := path.Join(runtimeDirectory, "bus"); fileExists(runUserBusFile) { // if /run/user//bus exists, that file itself // *is* the unix socket, so return its path - return fmt.Sprintf("unix:path=%s", runUserBusFile) + return fmt.Sprintf("unix:path=%s", EscapeBusAddressValue(runUserBusFile)) } if runUserSessionDbusFile := path.Join(runtimeDirectory, "dbus-session"); fileExists(runUserSessionDbusFile) { // if /run/user//dbus-session exists, it's a @@ -85,9 +85,6 @@ func getRuntimeDirectory() (string, error) { } func fileExists(filename string) bool { - if _, err := os.Stat(filename); !os.IsNotExist(err) { - return true - } else { - return false - } + _, err := os.Stat(filename) + return !os.IsNotExist(err) } diff --git a/vendor/github.com/godbus/dbus/v5/dbus.go b/vendor/github.com/godbus/dbus/v5/dbus.go index ddf3b7afde9..c188d104854 100644 --- a/vendor/github.com/godbus/dbus/v5/dbus.go +++ b/vendor/github.com/godbus/dbus/v5/dbus.go @@ -122,8 +122,11 @@ func isConvertibleTo(dest, src reflect.Type) bool { case dest.Kind() == reflect.Slice: return src.Kind() == reflect.Slice && isConvertibleTo(dest.Elem(), src.Elem()) + case dest.Kind() == reflect.Ptr: + dest = dest.Elem() + return isConvertibleTo(dest, src) case dest.Kind() == reflect.Struct: - return src == interfacesType + return src == interfacesType || dest.Kind() == src.Kind() default: return src.ConvertibleTo(dest) } @@ -274,13 +277,8 @@ func storeSliceIntoInterface(dest, src reflect.Value) error { func storeSliceIntoSlice(dest, src reflect.Value) error { if dest.IsNil() || dest.Len() < src.Len() { dest.Set(reflect.MakeSlice(dest.Type(), src.Len(), src.Cap())) - } - if dest.Len() != src.Len() { - return fmt.Errorf( - "dbus.Store: type mismatch: "+ - "slices are different lengths "+ - "need: %d have: %d", - src.Len(), dest.Len()) + } else if dest.Len() > src.Len() { + dest.Set(dest.Slice(0, src.Len())) } for i := 0; i < src.Len(); i++ { err := store(dest.Index(i), getVariantValue(src.Index(i))) diff --git a/vendor/github.com/godbus/dbus/v5/doc.go b/vendor/github.com/godbus/dbus/v5/doc.go index ade1df951cd..8f25a00d61e 100644 --- a/vendor/github.com/godbus/dbus/v5/doc.go +++ b/vendor/github.com/godbus/dbus/v5/doc.go @@ -10,8 +10,10 @@ value. Conversion Rules For outgoing messages, Go types are automatically converted to the -corresponding D-Bus types. The following types are directly encoded as their -respective D-Bus equivalents: +corresponding D-Bus types. See the official specification at +https://dbus.freedesktop.org/doc/dbus-specification.html#type-system for more +information on the D-Bus type system. The following types are directly encoded +as their respective D-Bus equivalents: Go type | D-Bus type ------------+----------- @@ -39,8 +41,8 @@ Maps encode as DICTs, provided that their key type can be used as a key for a DICT. Structs other than Variant and Signature encode as a STRUCT containing their -exported fields. Fields whose tags contain `dbus:"-"` and unexported fields will -be skipped. +exported fields in order. Fields whose tags contain `dbus:"-"` and unexported +fields will be skipped. Pointers encode as the value they're pointed to. diff --git a/vendor/github.com/godbus/dbus/v5/escape.go b/vendor/github.com/godbus/dbus/v5/escape.go new file mode 100644 index 00000000000..d1509d94581 --- /dev/null +++ b/vendor/github.com/godbus/dbus/v5/escape.go @@ -0,0 +1,84 @@ +package dbus + +import "net/url" + +// EscapeBusAddressValue implements a requirement to escape the values +// in D-Bus server addresses, as defined by the D-Bus specification at +// https://dbus.freedesktop.org/doc/dbus-specification.html#addresses. +func EscapeBusAddressValue(val string) string { + toEsc := strNeedsEscape(val) + if toEsc == 0 { + // Avoid unneeded allocation/copying. + return val + } + + // Avoid allocation for short paths. + var buf [64]byte + var out []byte + // Every to-be-escaped byte needs 2 extra bytes. + required := len(val) + 2*toEsc + if required <= len(buf) { + out = buf[:required] + } else { + out = make([]byte, required) + } + + j := 0 + for i := 0; i < len(val); i++ { + if ch := val[i]; needsEscape(ch) { + // Convert ch to %xx, where xx is hex value. + out[j] = '%' + out[j+1] = hexchar(ch >> 4) + out[j+2] = hexchar(ch & 0x0F) + j += 3 + } else { + out[j] = ch + j++ + } + } + + return string(out) +} + +// UnescapeBusAddressValue unescapes values in D-Bus server addresses, +// as defined by the D-Bus specification at +// https://dbus.freedesktop.org/doc/dbus-specification.html#addresses. +func UnescapeBusAddressValue(val string) (string, error) { + // Looks like url.PathUnescape does exactly what is required. + return url.PathUnescape(val) +} + +// hexchar returns an octal representation of a n, where n < 16. +// For invalid values of n, the function panics. +func hexchar(n byte) byte { + const hex = "0123456789abcdef" + + // For n >= len(hex), runtime will panic. + return hex[n] +} + +// needsEscape tells if a byte is NOT one of optionally-escaped bytes. +func needsEscape(c byte) bool { + if 'a' <= c && c <= 'z' || 'A' <= c && c <= 'Z' || '0' <= c && c <= '9' { + return false + } + switch c { + case '-', '_', '/', '\\', '.', '*': + return false + } + + return true +} + +// strNeedsEscape tells how many bytes in the string need escaping. +func strNeedsEscape(val string) int { + count := 0 + + for i := 0; i < len(val); i++ { + if needsEscape(val[i]) { + count++ + } + } + + return count +} diff --git a/vendor/github.com/godbus/dbus/v5/export.go b/vendor/github.com/godbus/dbus/v5/export.go index 522334715b6..d3dd9f7cd62 100644 --- a/vendor/github.com/godbus/dbus/v5/export.go +++ b/vendor/github.com/godbus/dbus/v5/export.go @@ -3,6 +3,7 @@ package dbus import ( "errors" "fmt" + "os" "reflect" "strings" ) @@ -209,28 +210,23 @@ func (conn *Conn) handleCall(msg *Message) { } reply.Headers[FieldSignature] = MakeVariant(SignatureOf(reply.Body...)) - conn.sendMessageAndIfClosed(reply, nil) + if err := reply.IsValid(); err != nil { + fmt.Fprintf(os.Stderr, "dbus: dropping invalid reply to %s.%s on obj %s: %s\n", ifaceName, name, path, err) + } else { + conn.sendMessageAndIfClosed(reply, nil) + } } } // Emit emits the given signal on the message bus. The name parameter must be // formatted as "interface.member", e.g., "org.freedesktop.DBus.NameLost". func (conn *Conn) Emit(path ObjectPath, name string, values ...interface{}) error { - if !path.IsValid() { - return errors.New("dbus: invalid object path") - } i := strings.LastIndex(name, ".") if i == -1 { return errors.New("dbus: invalid method name") } iface := name[:i] member := name[i+1:] - if !isValidMember(member) { - return errors.New("dbus: invalid method name") - } - if !isValidInterface(iface) { - return errors.New("dbus: invalid interface name") - } msg := new(Message) msg.Type = TypeSignal msg.Headers = make(map[HeaderField]Variant) @@ -241,6 +237,9 @@ func (conn *Conn) Emit(path ObjectPath, name string, values ...interface{}) erro if len(values) > 0 { msg.Headers[FieldSignature] = MakeVariant(SignatureOf(values...)) } + if err := msg.IsValid(); err != nil { + return err + } var closed bool conn.sendMessageAndIfClosed(msg, func() { diff --git a/vendor/github.com/godbus/dbus/v5/homedir.go b/vendor/github.com/godbus/dbus/v5/homedir.go index 0b745f9313a..c44d9b5fc24 100644 --- a/vendor/github.com/godbus/dbus/v5/homedir.go +++ b/vendor/github.com/godbus/dbus/v5/homedir.go @@ -2,27 +2,24 @@ package dbus import ( "os" - "sync" -) - -var ( - homeDir string - homeDirLock sync.Mutex + "os/user" ) +// Get returns the home directory of the current user, which is usually the +// value of HOME environment variable. In case it is not set or empty, os/user +// package is used. +// +// If linking statically with cgo enabled against glibc, make sure the +// osusergo build tag is used. +// +// If needing to do nss lookups, do not disable cgo or set osusergo. func getHomeDir() string { - homeDirLock.Lock() - defer homeDirLock.Unlock() - + homeDir := os.Getenv("HOME") if homeDir != "" { return homeDir } - - homeDir = os.Getenv("HOME") - if homeDir != "" { - return homeDir + if u, err := user.Current(); err == nil { + return u.HomeDir } - - homeDir = lookupHomeDir() - return homeDir + return "/" } diff --git a/vendor/github.com/godbus/dbus/v5/homedir_dynamic.go b/vendor/github.com/godbus/dbus/v5/homedir_dynamic.go deleted file mode 100644 index 2732081e73b..00000000000 --- a/vendor/github.com/godbus/dbus/v5/homedir_dynamic.go +++ /dev/null @@ -1,15 +0,0 @@ -// +build !static_build - -package dbus - -import ( - "os/user" -) - -func lookupHomeDir() string { - u, err := user.Current() - if err != nil { - return "/" - } - return u.HomeDir -} diff --git a/vendor/github.com/godbus/dbus/v5/homedir_static.go b/vendor/github.com/godbus/dbus/v5/homedir_static.go deleted file mode 100644 index b9d9cb5525a..00000000000 --- a/vendor/github.com/godbus/dbus/v5/homedir_static.go +++ /dev/null @@ -1,45 +0,0 @@ -// +build static_build - -package dbus - -import ( - "bufio" - "os" - "strconv" - "strings" -) - -func lookupHomeDir() string { - myUid := os.Getuid() - - f, err := os.Open("/etc/passwd") - if err != nil { - return "/" - } - defer f.Close() - - s := bufio.NewScanner(f) - - for s.Scan() { - if err := s.Err(); err != nil { - break - } - - line := strings.TrimSpace(s.Text()) - if line == "" { - continue - } - - parts := strings.Split(line, ":") - - if len(parts) >= 6 { - uid, err := strconv.Atoi(parts[2]) - if err == nil && uid == myUid { - return parts[5] - } - } - } - - // Default to / if we can't get a better value - return "/" -} diff --git a/vendor/github.com/godbus/dbus/v5/message.go b/vendor/github.com/godbus/dbus/v5/message.go index 16693eb3017..bdf43fdd6e5 100644 --- a/vendor/github.com/godbus/dbus/v5/message.go +++ b/vendor/github.com/godbus/dbus/v5/message.go @@ -208,7 +208,7 @@ func DecodeMessageWithFDs(rd io.Reader, fds []int) (msg *Message, err error) { // The possibly returned error can be an error of the underlying reader, an // InvalidMessageError or a FormatError. func DecodeMessage(rd io.Reader) (msg *Message, err error) { - return DecodeMessageWithFDs(rd, make([]int, 0)); + return DecodeMessageWithFDs(rd, make([]int, 0)) } type nullwriter struct{} @@ -227,8 +227,8 @@ func (msg *Message) CountFds() (int, error) { } func (msg *Message) EncodeToWithFDs(out io.Writer, order binary.ByteOrder) (fds []int, err error) { - if err := msg.IsValid(); err != nil { - return make([]int, 0), err + if err := msg.validateHeader(); err != nil { + return nil, err } var vs [7]interface{} switch order { @@ -237,7 +237,7 @@ func (msg *Message) EncodeToWithFDs(out io.Writer, order binary.ByteOrder) (fds case binary.BigEndian: vs[0] = byte('B') default: - return make([]int, 0), errors.New("dbus: invalid byte order") + return nil, errors.New("dbus: invalid byte order") } body := new(bytes.Buffer) fds = make([]int, 0) @@ -284,8 +284,13 @@ func (msg *Message) EncodeTo(out io.Writer, order binary.ByteOrder) (err error) } // IsValid checks whether msg is a valid message and returns an -// InvalidMessageError if it is not. +// InvalidMessageError or FormatError if it is not. func (msg *Message) IsValid() error { + var b bytes.Buffer + return msg.EncodeTo(&b, nativeEndian) +} + +func (msg *Message) validateHeader() error { if msg.Flags & ^(FlagNoAutoStart|FlagNoReplyExpected|FlagAllowInteractiveAuthorization) != 0 { return InvalidMessageError("invalid flags") } @@ -330,6 +335,7 @@ func (msg *Message) IsValid() error { return InvalidMessageError("missing signature") } } + return nil } diff --git a/vendor/github.com/godbus/dbus/v5/server_interfaces.go b/vendor/github.com/godbus/dbus/v5/server_interfaces.go index 79d97edf3ec..e4e0389fdf0 100644 --- a/vendor/github.com/godbus/dbus/v5/server_interfaces.go +++ b/vendor/github.com/godbus/dbus/v5/server_interfaces.go @@ -63,7 +63,7 @@ type Method interface { // any other decoding scheme. type ArgumentDecoder interface { // To decode the arguments of a method the sender and message are - // provided incase the semantics of the implementer provides access + // provided in case the semantics of the implementer provides access // to these as part of the method invocation. DecodeArguments(conn *Conn, sender string, msg *Message, args []interface{}) ([]interface{}, error) } diff --git a/vendor/github.com/godbus/dbus/v5/sig.go b/vendor/github.com/godbus/dbus/v5/sig.go index 41a0398129d..6b9cadb5fbc 100644 --- a/vendor/github.com/godbus/dbus/v5/sig.go +++ b/vendor/github.com/godbus/dbus/v5/sig.go @@ -102,7 +102,7 @@ func getSignature(t reflect.Type, depth *depthCounter) (sig string) { } } if len(s) == 0 { - panic("empty struct") + panic(InvalidTypeError{t}) } return "(" + s + ")" case reflect.Array, reflect.Slice: diff --git a/vendor/github.com/godbus/dbus/v5/transport_unix.go b/vendor/github.com/godbus/dbus/v5/transport_unix.go index 2212e7fa7f2..0a8c712ebdf 100644 --- a/vendor/github.com/godbus/dbus/v5/transport_unix.go +++ b/vendor/github.com/godbus/dbus/v5/transport_unix.go @@ -154,17 +154,15 @@ func (t *unixTransport) ReadMessage() (*Message, error) { // substitute the values in the message body (which are indices for the // array receiver via OOB) with the actual values for i, v := range msg.Body { - switch v.(type) { + switch index := v.(type) { case UnixFDIndex: - j := v.(UnixFDIndex) - if uint32(j) >= unixfds { + if uint32(index) >= unixfds { return nil, InvalidMessageError("invalid index for unix fd") } - msg.Body[i] = UnixFD(fds[j]) + msg.Body[i] = UnixFD(fds[index]) case []UnixFDIndex: - idxArray := v.([]UnixFDIndex) - fdArray := make([]UnixFD, len(idxArray)) - for k, j := range idxArray { + fdArray := make([]UnixFD, len(index)) + for k, j := range index { if uint32(j) >= unixfds { return nil, InvalidMessageError("invalid index for unix fd") } diff --git a/vendor/github.com/godbus/dbus/v5/transport_zos.go b/vendor/github.com/godbus/dbus/v5/transport_zos.go new file mode 100644 index 00000000000..1bba0d6bf78 --- /dev/null +++ b/vendor/github.com/godbus/dbus/v5/transport_zos.go @@ -0,0 +1,6 @@ +package dbus + +func (t *unixTransport) SendNullByte() error { + _, err := t.Write([]byte{0}) + return err +} diff --git a/vendor/github.com/godbus/dbus/v5/variant.go b/vendor/github.com/godbus/dbus/v5/variant.go index f1e81f3ede6..ca3dbe16a44 100644 --- a/vendor/github.com/godbus/dbus/v5/variant.go +++ b/vendor/github.com/godbus/dbus/v5/variant.go @@ -49,7 +49,7 @@ func ParseVariant(s string, sig Signature) (Variant, error) { } // format returns a formatted version of v and whether this string can be parsed -// unambigously. +// unambiguously. func (v Variant) format() (string, bool) { switch v.sig.str[0] { case 'b', 'i': diff --git a/vendor/modules.txt b/vendor/modules.txt index 2362c536b8e..01e52f54f58 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -26,7 +26,7 @@ github.com/cyphar/filepath-securejoin # github.com/docker/go-units v0.4.0 ## explicit github.com/docker/go-units -# github.com/godbus/dbus/v5 v5.0.6 +# github.com/godbus/dbus/v5 v5.1.0 ## explicit github.com/godbus/dbus/v5 # github.com/moby/sys/mountinfo v0.6.0