summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/source/markdown/podman-system-connection-add.1.md4
-rw-r--r--go.mod2
-rw-r--r--go.sum3
-rw-r--r--libpod/oci_conmon_linux.go4
-rw-r--r--libpod/runtime.go12
-rw-r--r--libpod/stats.go10
-rw-r--r--pkg/api/handlers/compat/containers_stats.go2
-rw-r--r--pkg/api/handlers/swagger/swagger.go9
-rw-r--r--pkg/api/server/register_containers.go4
-rw-r--r--test/e2e/pause_test.go5
-rw-r--r--test/system/075-exec.bats28
-rw-r--r--test/system/125-import.bats63
-rw-r--r--vendor/github.com/godbus/dbus/v5/README.md (renamed from vendor/github.com/godbus/dbus/v5/README.markdown)12
-rw-r--r--vendor/github.com/godbus/dbus/v5/auth.go13
-rw-r--r--vendor/github.com/godbus/dbus/v5/conn.go14
-rw-r--r--vendor/github.com/godbus/dbus/v5/decoder.go16
-rw-r--r--vendor/github.com/godbus/dbus/v5/encoder.go61
-rw-r--r--vendor/github.com/godbus/dbus/v5/export.go37
-rw-r--r--vendor/github.com/godbus/dbus/v5/message.go73
-rw-r--r--vendor/github.com/godbus/dbus/v5/sig.go66
-rw-r--r--vendor/github.com/godbus/dbus/v5/transport_generic.go10
-rw-r--r--vendor/github.com/godbus/dbus/v5/transport_unix.go24
-rw-r--r--vendor/modules.txt2
23 files changed, 364 insertions, 110 deletions
diff --git a/docs/source/markdown/podman-system-connection-add.1.md b/docs/source/markdown/podman-system-connection-add.1.md
index ad9acb4d8..fa763d7cc 100644
--- a/docs/source/markdown/podman-system-connection-add.1.md
+++ b/docs/source/markdown/podman-system-connection-add.1.md
@@ -41,9 +41,9 @@ $ podman system connection add QA podman.example.com
$ podman system connection add --identity ~/.ssh/dev_rsa production ssh://root@server.example.com:2222
-$ podman system connection add unix:///run/podman/podman.sock
+$ podman system connection add testing unix:///run/podman/podman.sock
-$ podman system connection add tcp://localhost:8080
+$ podman system connection add debug tcp://localhost:8080
```
## SEE ALSO
podman-system(1) , podman-system-connection(1) , containers.conf(5)
diff --git a/go.mod b/go.mod
index 3266f3bb1..038c2f667 100644
--- a/go.mod
+++ b/go.mod
@@ -32,7 +32,7 @@ require (
github.com/dtylman/scp v0.0.0-20181017070807-f3000a34aef4
github.com/fsnotify/fsnotify v1.5.1
github.com/ghodss/yaml v1.0.0
- github.com/godbus/dbus/v5 v5.0.4
+ github.com/godbus/dbus/v5 v5.0.5
github.com/google/shlex v0.0.0-20181106134648-c34317bd91bf
github.com/google/uuid v1.3.0
github.com/gorilla/mux v1.8.0
diff --git a/go.sum b/go.sum
index d855d82d7..693e487d5 100644
--- a/go.sum
+++ b/go.sum
@@ -402,8 +402,9 @@ github.com/godbus/dbus v0.0.0-20180201030542-885f9cc04c9c/go.mod h1:/YcGZj5zSblf
github.com/godbus/dbus v0.0.0-20190422162347-ade71ed3457e h1:BWhy2j3IXJhjCbC68FptL43tDKIq8FladmaTs3Xs7Z8=
github.com/godbus/dbus v0.0.0-20190422162347-ade71ed3457e/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4=
github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
-github.com/godbus/dbus/v5 v5.0.4 h1:9349emZab16e7zQvpmsbtjc18ykshndd8y2PG3sgJbA=
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
+github.com/godbus/dbus/v5 v5.0.5 h1:9Eg0XUhQxtkV8ykTMKtMMYY72g4NgxtRq4jgh4Ih5YM=
+github.com/godbus/dbus/v5 v5.0.5/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU=
github.com/gogo/googleapis v1.2.0/go.mod h1:Njal3psf3qN6dwBtQfUmBZh2ybovJ0tlu3o/AC7HYjU=
github.com/gogo/googleapis v1.4.0/go.mod h1:5YRNX2z1oM5gXdAkurHa942MDgEJyk02w4OecKY87+c=
diff --git a/libpod/oci_conmon_linux.go b/libpod/oci_conmon_linux.go
index 353e6af71..c00d83f95 100644
--- a/libpod/oci_conmon_linux.go
+++ b/libpod/oci_conmon_linux.go
@@ -46,7 +46,9 @@ import (
const (
// This is Conmon's STDIO_BUF_SIZE. I don't believe we have access to it
// directly from the Go code, so const it here
- bufferSize = conmonConfig.BufSize
+ // Important: The conmon attach socket uses an extra byte at the beginning of each
+ // message to specify the STREAM so we have to increase the buffer size by one
+ bufferSize = conmonConfig.BufSize + 1
)
// ConmonOCIRuntime is an OCI runtime managed by Conmon.
diff --git a/libpod/runtime.go b/libpod/runtime.go
index 1c9c56d16..761fa08a2 100644
--- a/libpod/runtime.go
+++ b/libpod/runtime.go
@@ -335,8 +335,16 @@ func makeRuntime(ctx context.Context, runtime *Runtime) (retErr error) {
// If user is rootless and XDG_RUNTIME_DIR is found, podman will not proceed with /tmp directory
// it will try to use existing XDG_RUNTIME_DIR
// if current user has no write access to XDG_RUNTIME_DIR we will fail later
- if unix.Access(runtime.storageConfig.RunRoot, unix.W_OK) != nil {
- logrus.Warnf("XDG_RUNTIME_DIR is pointing to a path which is not writable. Most likely podman will fail.")
+ if err := unix.Access(runtime.storageConfig.RunRoot, unix.W_OK); err != nil {
+ msg := "XDG_RUNTIME_DIR is pointing to a path which is not writable. Most likely podman will fail."
+ if errors.Is(err, os.ErrNotExist) {
+ // if dir does not exists try to create it
+ if err := os.MkdirAll(runtime.storageConfig.RunRoot, 0700); err != nil {
+ logrus.Warn(msg)
+ }
+ } else {
+ logrus.Warn(msg)
+ }
}
}
diff --git a/libpod/stats.go b/libpod/stats.go
index 6f0360ef1..975152535 100644
--- a/libpod/stats.go
+++ b/libpod/stats.go
@@ -30,7 +30,7 @@ func (c *Container) GetContainerStats(previousStats *define.ContainerStats) (*de
}
}
- if c.state.State != define.ContainerStateRunning {
+ if c.state.State != define.ContainerStateRunning && c.state.State != define.ContainerStatePaused {
return stats, define.ErrCtrStateInvalid
}
@@ -54,6 +54,12 @@ func (c *Container) GetContainerStats(previousStats *define.ContainerStats) (*de
return nil, err
}
+ // If the current total usage in the cgroup is less than what was previously
+ // recorded then it means the container was restarted and runs in a new cgroup
+ if previousStats.Duration > cgroupStats.CPU.Usage.Total {
+ previousStats = &define.ContainerStats{}
+ }
+
previousCPU := previousStats.CPUNano
now := uint64(time.Now().UnixNano())
stats.Duration = cgroupStats.CPU.Usage.Total
@@ -65,7 +71,7 @@ func (c *Container) GetContainerStats(previousStats *define.ContainerStats) (*de
stats.MemLimit = getMemLimit(cgroupStats.Memory.Usage.Limit)
stats.MemPerc = (float64(stats.MemUsage) / float64(stats.MemLimit)) * 100
stats.PIDs = 0
- if conState == define.ContainerStateRunning {
+ if conState == define.ContainerStateRunning || conState == define.ContainerStatePaused {
stats.PIDs = cgroupStats.Pids.Current
}
stats.BlockInput, stats.BlockOutput = calculateBlockIO(cgroupStats)
diff --git a/pkg/api/handlers/compat/containers_stats.go b/pkg/api/handlers/compat/containers_stats.go
index 851955207..b95fbfdd8 100644
--- a/pkg/api/handlers/compat/containers_stats.go
+++ b/pkg/api/handlers/compat/containers_stats.go
@@ -97,7 +97,7 @@ streamLabel: // A label to flatten the scope
default:
// Container stats
- stats, err := ctnr.GetContainerStats(stats)
+ stats, err = ctnr.GetContainerStats(stats)
if err != nil {
logrus.Errorf("Unable to get container stats: %v", err)
return
diff --git a/pkg/api/handlers/swagger/swagger.go b/pkg/api/handlers/swagger/swagger.go
index 2296eea3a..9844839b7 100644
--- a/pkg/api/handlers/swagger/swagger.go
+++ b/pkg/api/handlers/swagger/swagger.go
@@ -176,3 +176,12 @@ type swagInspectPodResponse struct {
define.InspectPodData
}
}
+
+// Get stats for one or more containers
+// swagger:response ContainerStats
+type swagContainerStatsResponse struct {
+ // in:body
+ Body struct {
+ define.ContainerStats
+ }
+}
diff --git a/pkg/api/server/register_containers.go b/pkg/api/server/register_containers.go
index 2a32966cc..8dcea1301 100644
--- a/pkg/api/server/register_containers.go
+++ b/pkg/api/server/register_containers.go
@@ -1124,11 +1124,9 @@ func (s *APIServer) registerContainersHandlers(r *mux.Router) error {
// - application/json
// responses:
// 200:
- // description: no error
+ // $ref: "#/responses/ContainerStats"
// 404:
// $ref: "#/responses/NoSuchContainer"
- // 409:
- // $ref: "#/responses/ConflictError"
// 500:
// $ref: "#/responses/InternalError"
r.HandleFunc(VersionedPath("/libpod/containers/stats"), s.APIHandler(libpod.StatsContainer)).Methods(http.MethodGet)
diff --git a/test/e2e/pause_test.go b/test/e2e/pause_test.go
index ea7a96428..2e5e07de9 100644
--- a/test/e2e/pause_test.go
+++ b/test/e2e/pause_test.go
@@ -79,6 +79,11 @@ var _ = Describe("Podman pause", func() {
Expect(result).To(ExitWithError())
Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0))
Expect(strings.ToLower(podmanTest.GetContainerStatus())).To(ContainSubstring(createdState))
+
+ // check we can read stats for a paused container
+ result = podmanTest.Podman([]string{"stats", "--no-stream", cid})
+ result.WaitWithDefaultTimeout()
+ Expect(result).To(ExitWithError())
})
It("podman pause a running container by id", func() {
diff --git a/test/system/075-exec.bats b/test/system/075-exec.bats
index 3e8c3c1ea..b7367d153 100644
--- a/test/system/075-exec.bats
+++ b/test/system/075-exec.bats
@@ -101,4 +101,32 @@ load helpers
run_podman rm $cid
}
+# #11496: podman-remote loses output
+@test "podman exec/run - missing output" {
+ local bigfile=${PODMAN_TMPDIR}/bigfile
+ local newfile=${PODMAN_TMPDIR}/newfile
+ # create a big file, bigger than the 8K buffer size
+ base64 /dev/urandom | head -c 20K > $bigfile
+
+ run_podman run --rm -v $bigfile:/tmp/test:Z $IMAGE cat /tmp/test
+ printf "%s" "$output" > $newfile
+ # use cmp to compare the files, this is very helpful since it will
+ # tell us the first wrong byte in case this fails
+ run cmp $bigfile $newfile
+ is "$output" "" "run output is identical with the file"
+
+ run_podman run -d --stop-timeout 0 -v $bigfile:/tmp/test:Z $IMAGE sleep inf
+ cid="$output"
+
+ run_podman exec $cid cat /tmp/test
+ printf "%s" "$output" > $newfile
+ # use cmp to compare the files, this is very helpful since it will
+ # tell us the first wrong byte in case this fails
+ run cmp $bigfile $newfile
+ is "$output" "" "exec output is identical with the file"
+
+ # Clean up
+ run_podman rm -f $cid
+}
+
# vim: filetype=sh
diff --git a/test/system/125-import.bats b/test/system/125-import.bats
index c53711618..5995d71bf 100644
--- a/test/system/125-import.bats
+++ b/test/system/125-import.bats
@@ -43,3 +43,66 @@ load helpers
is "$output" "$random_content" "tagged import via stdin"
run_podman rmi -f $fqin
}
+
+@test "podman export, alter tarball, re-import" {
+
+ # Create a test file following test
+ mkdir $PODMAN_TMPDIR/tmp
+ touch $PODMAN_TMPDIR/testfile1
+ echo "modified tar file" >> $PODMAN_TMPDIR/tmp/testfile2
+
+ # Create Dockerfile for test
+ dockerfile=$PODMAN_TMPDIR/Dockerfile
+
+ cat >$dockerfile <<EOF
+FROM $IMAGE
+ADD testfile1 /tmp
+WORKDIR /tmp
+EOF
+
+ b_img=before_change_img
+ b_cnt=before_change_cnt
+ a_img=after_change_img
+ a_cnt=after_change_cnt
+
+ # Build from Dockerfile FROM non-existing local image
+ run_podman build -t $b_img $PODMAN_TMPDIR
+ run_podman create --name $b_cnt $b_img
+
+ # Export built container as tarball
+ run_podman export -o $PODMAN_TMPDIR/$b_cnt.tar $b_cnt
+ run_podman rm -f $b_cnt
+
+ # Modify tarball contents
+ tar --delete -f $PODMAN_TMPDIR/$b_cnt.tar tmp/testfile1
+ tar -C $PODMAN_TMPDIR -rf $PODMAN_TMPDIR/$b_cnt.tar tmp/testfile2
+
+ # Import tarball and Tag imported image
+ run_podman import -q $PODMAN_TMPDIR/$b_cnt.tar \
+ --change "CMD sh -c \
+ \"trap 'exit 33' 2;
+ while true; do sleep 0.05;done\"" $a_img
+
+ # Run imported image to confirm tarball modification, block on non-special signal
+ run_podman run --name $a_cnt -d $a_img
+
+ # Confirm testfile1 is deleted from tarball
+ run_podman 1 exec $a_cnt cat /tmp/testfile1
+ is "$output" ".*can't open '/tmp/testfile1': No such file or directory"
+
+ # Confirm testfile2 is added to tarball
+ run_podman exec $a_cnt cat /tmp/testfile2
+ is "$output" "modified tar file" "modify tarball content"
+
+ # Kill can send non-TERM/KILL signal to container to exit
+ run_podman kill --signal 2 $a_cnt
+ run_podman wait $a_cnt
+
+ # Confirm exit within timeout
+ run_podman ps -a --filter name=$a_cnt --format '{{.Status}}'
+ is "$output" "Exited (33)" "Exit by non-TERM/KILL"
+
+ run_podman rm -f $a_cnt
+ run_podman rmi $b_img $a_img
+
+}
diff --git a/vendor/github.com/godbus/dbus/v5/README.markdown b/vendor/github.com/godbus/dbus/v5/README.md
index 1fb2eacaa..5c2412583 100644
--- a/vendor/github.com/godbus/dbus/v5/README.markdown
+++ b/vendor/github.com/godbus/dbus/v5/README.md
@@ -14,14 +14,12 @@ D-Bus message bus system.
### Installation
-This packages requires Go 1.7. If you installed it and set up your GOPATH, just run:
+This packages requires Go 1.12 or later. It can be installed by running the command below:
```
-go get github.com/godbus/dbus
+go get github.com/godbus/dbus/v5
```
-If you want to use the subpackages, you can install them the same way.
-
### Usage
The complete package documentation and some simple examples are available at
@@ -30,10 +28,12 @@ The complete package documentation and some simple examples are available at
gives a short overview over the basic usage.
#### Projects using godbus
-- [notify](https://github.com/esiqveland/notify) provides desktop notifications over dbus into a library.
+- [fyne](https://github.com/fyne-io/fyne) a cross platform GUI in Go inspired by Material Design.
+- [fynedesk](https://github.com/fyne-io/fynedesk) a full desktop environment for Linux/Unix using Fyne.
- [go-bluetooth](https://github.com/muka/go-bluetooth) provides a bluetooth client over bluez dbus API.
-- [playerbm](https://github.com/altdesktop/playerbm) a bookmark utility for media players.
- [iwd](https://github.com/shibumi/iwd) go bindings for the internet wireless daemon "iwd".
+- [notify](https://github.com/esiqveland/notify) provides desktop notifications over dbus into a library.
+- [playerbm](https://github.com/altdesktop/playerbm) a bookmark utility for media players.
Please note that the API is considered unstable for now and may change without
further notice.
diff --git a/vendor/github.com/godbus/dbus/v5/auth.go b/vendor/github.com/godbus/dbus/v5/auth.go
index 283487a0e..eb0b2f434 100644
--- a/vendor/github.com/godbus/dbus/v5/auth.go
+++ b/vendor/github.com/godbus/dbus/v5/auth.go
@@ -75,9 +75,9 @@ func (conn *Conn) Auth(methods []Auth) error {
s = s[1:]
for _, v := range s {
for _, m := range methods {
- if name, data, status := m.FirstData(); bytes.Equal(v, name) {
+ if name, _, status := m.FirstData(); bytes.Equal(v, name) {
var ok bool
- err = authWriteLine(conn.transport, []byte("AUTH"), v, data)
+ err = authWriteLine(conn.transport, []byte("AUTH"), v)
if err != nil {
return err
}
@@ -194,11 +194,14 @@ func (conn *Conn) tryAuth(m Auth, state authState, in *bufio.Reader) (error, boo
}
conn.uuid = string(s[1])
return nil, true
+ case state == waitingForOk && string(s[0]) == "DATA":
+ err = authWriteLine(conn.transport, []byte("DATA"))
+ if err != nil {
+ return err, false
+ }
case state == waitingForOk && string(s[0]) == "REJECTED":
return nil, false
- case state == waitingForOk && (string(s[0]) == "DATA" ||
- string(s[0]) == "ERROR"):
-
+ case state == waitingForOk && string(s[0]) == "ERROR":
err = authWriteLine(conn.transport, []byte("CANCEL"))
if err != nil {
return err, false
diff --git a/vendor/github.com/godbus/dbus/v5/conn.go b/vendor/github.com/godbus/dbus/v5/conn.go
index 29fe018ad..cb8966a74 100644
--- a/vendor/github.com/godbus/dbus/v5/conn.go
+++ b/vendor/github.com/godbus/dbus/v5/conn.go
@@ -478,14 +478,24 @@ func (conn *Conn) sendMessageAndIfClosed(msg *Message, ifClosed func()) {
conn.outInt(msg)
}
err := conn.outHandler.sendAndIfClosed(msg, ifClosed)
- conn.calls.handleSendError(msg, err)
if err != nil {
- conn.serialGen.RetireSerial(msg.serial)
+ conn.handleSendError(msg, err)
} else if msg.Type != TypeMethodCall {
conn.serialGen.RetireSerial(msg.serial)
}
}
+func (conn *Conn) handleSendError(msg *Message, err error) {
+ if msg.Type == TypeMethodCall {
+ conn.calls.handleSendError(msg, err)
+ } else if msg.Type == TypeMethodReply {
+ if _, ok := err.(FormatError); ok {
+ conn.sendError(err, msg.Headers[FieldDestination].value.(string), msg.Headers[FieldReplySerial].value.(uint32))
+ }
+ }
+ conn.serialGen.RetireSerial(msg.serial)
+}
+
// Send sends the given message to the message bus. You usually don't need to
// use this; use the higher-level equivalents (Call / Go, Emit and Export)
// instead. If msg is a method call and NoReplyExpected is not set, a non-nil
diff --git a/vendor/github.com/godbus/dbus/v5/decoder.go b/vendor/github.com/godbus/dbus/v5/decoder.go
index ede91575b..89bfed9d1 100644
--- a/vendor/github.com/godbus/dbus/v5/decoder.go
+++ b/vendor/github.com/godbus/dbus/v5/decoder.go
@@ -10,14 +10,16 @@ type decoder struct {
in io.Reader
order binary.ByteOrder
pos int
+ fds []int
}
// newDecoder returns a new decoder that reads values from in. The input is
// expected to be in the given byte order.
-func newDecoder(in io.Reader, order binary.ByteOrder) *decoder {
+func newDecoder(in io.Reader, order binary.ByteOrder, fds []int) *decoder {
dec := new(decoder)
dec.in = in
dec.order = order
+ dec.fds = fds
return dec
}
@@ -53,7 +55,7 @@ func (dec *decoder) Decode(sig Signature) (vs []interface{}, err error) {
vs = make([]interface{}, 0)
s := sig.str
for s != "" {
- err, rem := validSingle(s, 0)
+ err, rem := validSingle(s, &depthCounter{})
if err != nil {
return nil, err
}
@@ -150,7 +152,7 @@ func (dec *decoder) decode(s string, depth int) interface{} {
if len(sig.str) == 0 {
panic(FormatError("variant signature is empty"))
}
- err, rem := validSingle(sig.str, 0)
+ err, rem := validSingle(sig.str, &depthCounter{})
if err != nil {
panic(err)
}
@@ -161,7 +163,11 @@ func (dec *decoder) decode(s string, depth int) interface{} {
variant.value = dec.decode(sig.str, depth+1)
return variant
case 'h':
- return UnixFDIndex(dec.decode("u", depth).(uint32))
+ idx := dec.decode("u", depth).(uint32)
+ if int(idx) < len(dec.fds) {
+ return UnixFD(dec.fds[idx])
+ }
+ return UnixFDIndex(idx)
case 'a':
if len(s) > 1 && s[1] == '{' {
ksig := s[2:3]
@@ -219,7 +225,7 @@ func (dec *decoder) decode(s string, depth int) interface{} {
v := make([]interface{}, 0)
s = s[1 : len(s)-1]
for s != "" {
- err, rem := validSingle(s, 0)
+ err, rem := validSingle(s, &depthCounter{})
if err != nil {
panic(err)
}
diff --git a/vendor/github.com/godbus/dbus/v5/encoder.go b/vendor/github.com/godbus/dbus/v5/encoder.go
index adfbb75c5..015b26cd5 100644
--- a/vendor/github.com/godbus/dbus/v5/encoder.go
+++ b/vendor/github.com/godbus/dbus/v5/encoder.go
@@ -5,28 +5,33 @@ import (
"encoding/binary"
"io"
"reflect"
+ "strings"
+ "unicode/utf8"
)
// An encoder encodes values to the D-Bus wire format.
type encoder struct {
out io.Writer
+ fds []int
order binary.ByteOrder
pos int
}
// NewEncoder returns a new encoder that writes to out in the given byte order.
-func newEncoder(out io.Writer, order binary.ByteOrder) *encoder {
- return newEncoderAtOffset(out, 0, order)
+func newEncoder(out io.Writer, order binary.ByteOrder, fds []int) *encoder {
+ enc := newEncoderAtOffset(out, 0, order, fds)
+ return enc
}
// newEncoderAtOffset returns a new encoder that writes to out in the given
// byte order. Specify the offset to initialize pos for proper alignment
// computation.
-func newEncoderAtOffset(out io.Writer, offset int, order binary.ByteOrder) *encoder {
+func newEncoderAtOffset(out io.Writer, offset int, order binary.ByteOrder, fds []int) *encoder {
enc := new(encoder)
enc.out = out
enc.order = order
enc.pos = offset
+ enc.fds = fds
return enc
}
@@ -75,6 +80,9 @@ func (enc *encoder) Encode(vs ...interface{}) (err error) {
// encode encodes the given value to the writer and panics on error. depth holds
// the depth of the container nesting.
func (enc *encoder) encode(v reflect.Value, depth int) {
+ if depth > 64 {
+ panic(FormatError("input exceeds depth limitation"))
+ }
enc.align(alignment(v.Type()))
switch v.Kind() {
case reflect.Uint8:
@@ -97,7 +105,14 @@ func (enc *encoder) encode(v reflect.Value, depth int) {
enc.binwrite(uint16(v.Uint()))
enc.pos += 2
case reflect.Int, reflect.Int32:
- enc.binwrite(int32(v.Int()))
+ if v.Type() == unixFDType {
+ fd := v.Int()
+ idx := len(enc.fds)
+ enc.fds = append(enc.fds, int(fd))
+ enc.binwrite(uint32(idx))
+ } else {
+ enc.binwrite(int32(v.Int()))
+ }
enc.pos += 4
case reflect.Uint, reflect.Uint32:
enc.binwrite(uint32(v.Uint()))
@@ -112,9 +127,21 @@ func (enc *encoder) encode(v reflect.Value, depth int) {
enc.binwrite(v.Float())
enc.pos += 8
case reflect.String:
- enc.encode(reflect.ValueOf(uint32(len(v.String()))), depth)
+ str := v.String()
+ if !utf8.ValidString(str) {
+ panic(FormatError("input has a not-utf8 char in string"))
+ }
+ if strings.IndexByte(str, byte(0)) != -1 {
+ panic(FormatError("input has a null char('\\000') in string"))
+ }
+ if v.Type() == objectPathType {
+ if !ObjectPath(str).IsValid() {
+ panic(FormatError("invalid object path"))
+ }
+ }
+ enc.encode(reflect.ValueOf(uint32(len(str))), depth)
b := make([]byte, v.Len()+1)
- copy(b, v.String())
+ copy(b, str)
b[len(b)-1] = 0
n, err := enc.out.Write(b)
if err != nil {
@@ -124,20 +151,23 @@ func (enc *encoder) encode(v reflect.Value, depth int) {
case reflect.Ptr:
enc.encode(v.Elem(), depth)
case reflect.Slice, reflect.Array:
- if depth >= 64 {
- panic(FormatError("input exceeds container depth limit"))
- }
// Lookahead offset: 4 bytes for uint32 length (with alignment),
// plus alignment for elements.
n := enc.padding(0, 4) + 4
offset := enc.pos + n + enc.padding(n, alignment(v.Type().Elem()))
var buf bytes.Buffer
- bufenc := newEncoderAtOffset(&buf, offset, enc.order)
+ bufenc := newEncoderAtOffset(&buf, offset, enc.order, enc.fds)
for i := 0; i < v.Len(); i++ {
bufenc.encode(v.Index(i), depth+1)
}
+
+ if buf.Len() > 1<<26 {
+ panic(FormatError("input exceeds array size limitation"))
+ }
+
+ enc.fds = bufenc.fds
enc.encode(reflect.ValueOf(uint32(buf.Len())), depth)
length := buf.Len()
enc.align(alignment(v.Type().Elem()))
@@ -146,13 +176,10 @@ func (enc *encoder) encode(v reflect.Value, depth int) {
}
enc.pos += length
case reflect.Struct:
- if depth >= 64 && v.Type() != signatureType {
- panic(FormatError("input exceeds container depth limit"))
- }
switch t := v.Type(); t {
case signatureType:
str := v.Field(0)
- enc.encode(reflect.ValueOf(byte(str.Len())), depth+1)
+ enc.encode(reflect.ValueOf(byte(str.Len())), depth)
b := make([]byte, str.Len()+1)
copy(b, str.String())
b[len(b)-1] = 0
@@ -176,9 +203,6 @@ func (enc *encoder) encode(v reflect.Value, depth int) {
case reflect.Map:
// Maps are arrays of structures, so they actually increase the depth by
// 2.
- if depth >= 63 {
- panic(FormatError("input exceeds container depth limit"))
- }
if !isKeyType(v.Type().Key()) {
panic(InvalidTypeError{v.Type()})
}
@@ -189,12 +213,13 @@ func (enc *encoder) encode(v reflect.Value, depth int) {
offset := enc.pos + n + enc.padding(n, 8)
var buf bytes.Buffer
- bufenc := newEncoderAtOffset(&buf, offset, enc.order)
+ bufenc := newEncoderAtOffset(&buf, offset, enc.order, enc.fds)
for _, k := range keys {
bufenc.align(8)
bufenc.encode(k, depth+2)
bufenc.encode(v.MapIndex(k), depth+2)
}
+ enc.fds = bufenc.fds
enc.encode(reflect.ValueOf(uint32(buf.Len())), depth)
length := buf.Len()
enc.align(8)
diff --git a/vendor/github.com/godbus/dbus/v5/export.go b/vendor/github.com/godbus/dbus/v5/export.go
index 2447b51d4..522334715 100644
--- a/vendor/github.com/godbus/dbus/v5/export.go
+++ b/vendor/github.com/godbus/dbus/v5/export.go
@@ -26,6 +26,27 @@ var (
}
)
+func MakeNoObjectError(path ObjectPath) Error {
+ return Error{
+ "org.freedesktop.DBus.Error.NoSuchObject",
+ []interface{}{fmt.Sprintf("No such object '%s'", string(path))},
+ }
+}
+
+func MakeUnknownMethodError(methodName string) Error {
+ return Error{
+ "org.freedesktop.DBus.Error.UnknownMethod",
+ []interface{}{fmt.Sprintf("Unknown / invalid method '%s'", methodName)},
+ }
+}
+
+func MakeUnknownInterfaceError(ifaceName string) Error {
+ return Error{
+ "org.freedesktop.DBus.Error.UnknownInterface",
+ []interface{}{fmt.Sprintf("Object does not implement the interface '%s'", ifaceName)},
+ }
+}
+
func MakeFailedError(err error) *Error {
return &Error{
"org.freedesktop.DBus.Error.Failed",
@@ -128,6 +149,11 @@ func (conn *Conn) handleCall(msg *Message) {
ifaceName, _ := msg.Headers[FieldInterface].value.(string)
sender, hasSender := msg.Headers[FieldSender].value.(string)
serial := msg.serial
+
+ if len(name) == 0 {
+ conn.sendError(ErrMsgUnknownMethod, sender, serial)
+ }
+
if ifaceName == "org.freedesktop.DBus.Peer" {
switch name {
case "Ping":
@@ -135,29 +161,26 @@ func (conn *Conn) handleCall(msg *Message) {
case "GetMachineId":
conn.sendReply(sender, serial, conn.uuid)
default:
- conn.sendError(ErrMsgUnknownMethod, sender, serial)
+ conn.sendError(MakeUnknownMethodError(name), sender, serial)
}
return
}
- if len(name) == 0 {
- conn.sendError(ErrMsgUnknownMethod, sender, serial)
- }
object, ok := conn.handler.LookupObject(path)
if !ok {
- conn.sendError(ErrMsgNoObject, sender, serial)
+ conn.sendError(MakeNoObjectError(path), sender, serial)
return
}
iface, exists := object.LookupInterface(ifaceName)
if !exists {
- conn.sendError(ErrMsgUnknownInterface, sender, serial)
+ conn.sendError(MakeUnknownInterfaceError(ifaceName), sender, serial)
return
}
m, exists := iface.LookupMethod(name)
if !exists {
- conn.sendError(ErrMsgUnknownMethod, sender, serial)
+ conn.sendError(MakeUnknownMethodError(name), sender, serial)
return
}
args, err := conn.decodeArguments(m, sender, msg)
diff --git a/vendor/github.com/godbus/dbus/v5/message.go b/vendor/github.com/godbus/dbus/v5/message.go
index 6a925367e..dd86aff4f 100644
--- a/vendor/github.com/godbus/dbus/v5/message.go
+++ b/vendor/github.com/godbus/dbus/v5/message.go
@@ -118,11 +118,7 @@ type header struct {
Variant
}
-// DecodeMessage tries to decode a single message in the D-Bus wire format
-// from the given reader. The byte order is figured out from the first byte.
-// 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) {
+func DecodeMessageWithFDs(rd io.Reader, fds []int) (msg *Message, err error) {
var order binary.ByteOrder
var hlength, length uint32
var typ, flags, proto byte
@@ -142,7 +138,7 @@ func DecodeMessage(rd io.Reader) (msg *Message, err error) {
return nil, InvalidMessageError("invalid byte order")
}
- dec := newDecoder(rd, order)
+ dec := newDecoder(rd, order, fds)
dec.pos = 1
msg = new(Message)
@@ -166,7 +162,7 @@ func DecodeMessage(rd io.Reader) (msg *Message, err error) {
if hlength+length+16 > 1<<27 {
return nil, InvalidMessageError("message is too long")
}
- dec = newDecoder(io.MultiReader(bytes.NewBuffer(b), rd), order)
+ dec = newDecoder(io.MultiReader(bytes.NewBuffer(b), rd), order, fds)
dec.pos = 12
vs, err = dec.Decode(Signature{"a(yv)"})
if err != nil {
@@ -196,7 +192,7 @@ func DecodeMessage(rd io.Reader) (msg *Message, err error) {
sig, _ := msg.Headers[FieldSignature].value.(Signature)
if sig.str != "" {
buf := bytes.NewBuffer(body)
- dec = newDecoder(buf, order)
+ dec = newDecoder(buf, order, fds)
vs, err := dec.Decode(sig)
if err != nil {
return nil, err
@@ -207,12 +203,32 @@ func DecodeMessage(rd io.Reader) (msg *Message, err error) {
return
}
-// EncodeTo encodes and sends a message to the given writer. The byte order must
-// be either binary.LittleEndian or binary.BigEndian. If the message is not
-// valid or an error occurs when writing, an error is returned.
-func (msg *Message) EncodeTo(out io.Writer, order binary.ByteOrder) error {
+// DecodeMessage tries to decode a single message in the D-Bus wire format
+// from the given reader. The byte order is figured out from the first byte.
+// 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));
+}
+
+type nullwriter struct{}
+
+func (nullwriter) Write(p []byte) (cnt int, err error) {
+ return len(p), nil
+}
+
+func (msg *Message) CountFds() (int, error) {
+ if len(msg.Body) == 0 {
+ return 0, nil
+ }
+ enc := newEncoder(nullwriter{}, nativeEndian, make([]int, 0))
+ err := enc.Encode(msg.Body...)
+ return len(enc.fds), err
+}
+
+func (msg *Message) EncodeToWithFDs(out io.Writer, order binary.ByteOrder) (fds []int, err error) {
if err := msg.IsValid(); err != nil {
- return err
+ return make([]int, 0), err
}
var vs [7]interface{}
switch order {
@@ -221,12 +237,16 @@ func (msg *Message) EncodeTo(out io.Writer, order binary.ByteOrder) error {
case binary.BigEndian:
vs[0] = byte('B')
default:
- return errors.New("dbus: invalid byte order")
+ return make([]int, 0), errors.New("dbus: invalid byte order")
}
body := new(bytes.Buffer)
- enc := newEncoder(body, order)
+ fds = make([]int, 0)
+ enc := newEncoder(body, order, fds)
if len(msg.Body) != 0 {
- enc.Encode(msg.Body...)
+ err = enc.Encode(msg.Body...)
+ if err != nil {
+ return
+ }
}
vs[1] = msg.Type
vs[2] = msg.Flags
@@ -239,17 +259,28 @@ func (msg *Message) EncodeTo(out io.Writer, order binary.ByteOrder) error {
}
vs[6] = headers
var buf bytes.Buffer
- enc = newEncoder(&buf, order)
- enc.Encode(vs[:]...)
+ enc = newEncoder(&buf, order, enc.fds)
+ err = enc.Encode(vs[:]...)
+ if err != nil {
+ return
+ }
enc.align(8)
body.WriteTo(&buf)
if buf.Len() > 1<<27 {
- return InvalidMessageError("message is too long")
+ return make([]int, 0), InvalidMessageError("message is too long")
}
if _, err := buf.WriteTo(out); err != nil {
- return err
+ return make([]int, 0), err
}
- return nil
+ return enc.fds, nil
+}
+
+// EncodeTo encodes and sends a message to the given writer. The byte order must
+// be either binary.LittleEndian or binary.BigEndian. If the message is not
+// valid or an error occurs when writing, an error is returned.
+func (msg *Message) EncodeTo(out io.Writer, order binary.ByteOrder) (err error) {
+ _, err = msg.EncodeToWithFDs(out, order);
+ return err;
}
// IsValid checks whether msg is a valid message and returns an
diff --git a/vendor/github.com/godbus/dbus/v5/sig.go b/vendor/github.com/godbus/dbus/v5/sig.go
index 2d326cebc..41a039812 100644
--- a/vendor/github.com/godbus/dbus/v5/sig.go
+++ b/vendor/github.com/godbus/dbus/v5/sig.go
@@ -34,7 +34,7 @@ type Signature struct {
func SignatureOf(vs ...interface{}) Signature {
var s string
for _, v := range vs {
- s += getSignature(reflect.TypeOf(v))
+ s += getSignature(reflect.TypeOf(v), &depthCounter{})
}
return Signature{s}
}
@@ -42,11 +42,19 @@ func SignatureOf(vs ...interface{}) Signature {
// SignatureOfType returns the signature of the given type. It panics if the
// type is not representable in D-Bus.
func SignatureOfType(t reflect.Type) Signature {
- return Signature{getSignature(t)}
+ return Signature{getSignature(t, &depthCounter{})}
}
// getSignature returns the signature of the given type and panics on unknown types.
-func getSignature(t reflect.Type) string {
+func getSignature(t reflect.Type, depth *depthCounter) (sig string) {
+ if !depth.Valid() {
+ panic("container nesting too deep")
+ }
+ defer func() {
+ if len(sig) > 255 {
+ panic("signature exceeds the length limitation")
+ }
+ }()
// handle simple types first
switch t.Kind() {
case reflect.Uint8:
@@ -74,7 +82,7 @@ func getSignature(t reflect.Type) string {
case reflect.Float64:
return "d"
case reflect.Ptr:
- return getSignature(t.Elem())
+ return getSignature(t.Elem(), depth)
case reflect.String:
if t == objectPathType {
return "o"
@@ -90,17 +98,20 @@ func getSignature(t reflect.Type) string {
for i := 0; i < t.NumField(); i++ {
field := t.Field(i)
if field.PkgPath == "" && field.Tag.Get("dbus") != "-" {
- s += getSignature(t.Field(i).Type)
+ s += getSignature(t.Field(i).Type, depth.EnterStruct())
}
}
+ if len(s) == 0 {
+ panic("empty struct")
+ }
return "(" + s + ")"
case reflect.Array, reflect.Slice:
- return "a" + getSignature(t.Elem())
+ return "a" + getSignature(t.Elem(), depth.EnterArray())
case reflect.Map:
if !isKeyType(t.Key()) {
panic(InvalidTypeError{t})
}
- return "a{" + getSignature(t.Key()) + getSignature(t.Elem()) + "}"
+ return "a{" + getSignature(t.Key(), depth.EnterArray().EnterDictEntry()) + getSignature(t.Elem(), depth.EnterArray().EnterDictEntry()) + "}"
case reflect.Interface:
return "v"
}
@@ -118,7 +129,7 @@ func ParseSignature(s string) (sig Signature, err error) {
}
sig.str = s
for err == nil && len(s) != 0 {
- err, s = validSingle(s, 0)
+ err, s = validSingle(s, &depthCounter{})
}
if err != nil {
sig = Signature{""}
@@ -144,7 +155,7 @@ func (s Signature) Empty() bool {
// Single returns whether the signature represents a single, complete type.
func (s Signature) Single() bool {
- err, r := validSingle(s.str, 0)
+ err, r := validSingle(s.str, &depthCounter{})
return err != nil && r == ""
}
@@ -164,15 +175,38 @@ func (e SignatureError) Error() string {
return fmt.Sprintf("dbus: invalid signature: %q (%s)", e.Sig, e.Reason)
}
+type depthCounter struct {
+ arrayDepth, structDepth, dictEntryDepth int
+}
+
+func (cnt *depthCounter) Valid() bool {
+ return cnt.arrayDepth <= 32 && cnt.structDepth <= 32 && cnt.dictEntryDepth <= 32
+}
+
+func (cnt depthCounter) EnterArray() *depthCounter {
+ cnt.arrayDepth++
+ return &cnt
+}
+
+func (cnt depthCounter) EnterStruct() *depthCounter {
+ cnt.structDepth++
+ return &cnt
+}
+
+func (cnt depthCounter) EnterDictEntry() *depthCounter {
+ cnt.dictEntryDepth++
+ return &cnt
+}
+
// Try to read a single type from this string. If it was successful, err is nil
// and rem is the remaining unparsed part. Otherwise, err is a non-nil
// SignatureError and rem is "". depth is the current recursion depth which may
// not be greater than 64 and should be given as 0 on the first call.
-func validSingle(s string, depth int) (err error, rem string) {
+func validSingle(s string, depth *depthCounter) (err error, rem string) {
if s == "" {
return SignatureError{Sig: s, Reason: "empty signature"}, ""
}
- if depth > 64 {
+ if !depth.Valid() {
return SignatureError{Sig: s, Reason: "container nesting too deep"}, ""
}
switch s[0] {
@@ -187,10 +221,10 @@ func validSingle(s string, depth int) (err error, rem string) {
i++
rem = s[i+1:]
s = s[2:i]
- if err, _ = validSingle(s[:1], depth+1); err != nil {
+ if err, _ = validSingle(s[:1], depth.EnterArray().EnterDictEntry()); err != nil {
return err, ""
}
- err, nr := validSingle(s[1:], depth+1)
+ err, nr := validSingle(s[1:], depth.EnterArray().EnterDictEntry())
if err != nil {
return err, ""
}
@@ -199,7 +233,7 @@ func validSingle(s string, depth int) (err error, rem string) {
}
return nil, rem
}
- return validSingle(s[1:], depth+1)
+ return validSingle(s[1:], depth.EnterArray())
case '(':
i := findMatching(s, '(', ')')
if i == -1 {
@@ -208,7 +242,7 @@ func validSingle(s string, depth int) (err error, rem string) {
rem = s[i+1:]
s = s[1:i]
for err == nil && s != "" {
- err, s = validSingle(s, depth+1)
+ err, s = validSingle(s, depth.EnterStruct())
}
if err != nil {
rem = ""
@@ -236,7 +270,7 @@ func findMatching(s string, left, right rune) int {
// typeFor returns the type of the given signature. It ignores any left over
// characters and panics if s doesn't start with a valid type signature.
func typeFor(s string) (t reflect.Type) {
- err, _ := validSingle(s, 0)
+ err, _ := validSingle(s, &depthCounter{})
if err != nil {
panic(err)
}
diff --git a/vendor/github.com/godbus/dbus/v5/transport_generic.go b/vendor/github.com/godbus/dbus/v5/transport_generic.go
index 718a1ff02..a08e2813c 100644
--- a/vendor/github.com/godbus/dbus/v5/transport_generic.go
+++ b/vendor/github.com/godbus/dbus/v5/transport_generic.go
@@ -41,10 +41,12 @@ func (t genericTransport) ReadMessage() (*Message, error) {
}
func (t genericTransport) SendMessage(msg *Message) error {
- for _, v := range msg.Body {
- if _, ok := v.(UnixFD); ok {
- return errors.New("dbus: unix fd passing not enabled")
- }
+ fds, err := msg.CountFds()
+ if err != nil {
+ return err
+ }
+ if fds != 0 {
+ return errors.New("dbus: unix fd passing not enabled")
}
return msg.EncodeTo(t, nativeEndian)
}
diff --git a/vendor/github.com/godbus/dbus/v5/transport_unix.go b/vendor/github.com/godbus/dbus/v5/transport_unix.go
index c7cd02f97..2212e7fa7 100644
--- a/vendor/github.com/godbus/dbus/v5/transport_unix.go
+++ b/vendor/github.com/godbus/dbus/v5/transport_unix.go
@@ -113,7 +113,7 @@ func (t *unixTransport) ReadMessage() (*Message, error) {
if _, err := io.ReadFull(t.rdr, headerdata[4:]); err != nil {
return nil, err
}
- dec := newDecoder(bytes.NewBuffer(headerdata), order)
+ dec := newDecoder(bytes.NewBuffer(headerdata), order, make([]int, 0))
dec.pos = 12
vs, err := dec.Decode(Signature{"a(yv)"})
if err != nil {
@@ -147,7 +147,7 @@ func (t *unixTransport) ReadMessage() (*Message, error) {
if err != nil {
return nil, err
}
- msg, err := DecodeMessage(bytes.NewBuffer(all))
+ msg, err := DecodeMessageWithFDs(bytes.NewBuffer(all), fds)
if err != nil {
return nil, err
}
@@ -179,21 +179,21 @@ func (t *unixTransport) ReadMessage() (*Message, error) {
}
func (t *unixTransport) SendMessage(msg *Message) error {
- fds := make([]int, 0)
- for i, v := range msg.Body {
- if fd, ok := v.(UnixFD); ok {
- msg.Body[i] = UnixFDIndex(len(fds))
- fds = append(fds, int(fd))
- }
+ fdcnt, err := msg.CountFds()
+ if err != nil {
+ return err
}
- if len(fds) != 0 {
+ if fdcnt != 0 {
if !t.hasUnixFDs {
return errors.New("dbus: unix fd passing not enabled")
}
- msg.Headers[FieldUnixFDs] = MakeVariant(uint32(len(fds)))
- oob := syscall.UnixRights(fds...)
+ msg.Headers[FieldUnixFDs] = MakeVariant(uint32(fdcnt))
buf := new(bytes.Buffer)
- msg.EncodeTo(buf, nativeEndian)
+ fds, err := msg.EncodeToWithFDs(buf, nativeEndian)
+ if err != nil {
+ return err
+ }
+ oob := syscall.UnixRights(fds...)
n, oobn, err := t.UnixConn.WriteMsgUnix(buf.Bytes(), oob, nil)
if err != nil {
return err
diff --git a/vendor/modules.txt b/vendor/modules.txt
index 0a0df7e71..35409a743 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -348,7 +348,7 @@ github.com/ghodss/yaml
github.com/go-logr/logr
# github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0
github.com/go-task/slim-sprig
-# github.com/godbus/dbus/v5 v5.0.4
+# github.com/godbus/dbus/v5 v5.0.5
github.com/godbus/dbus/v5
# github.com/gogo/protobuf v1.3.2
github.com/gogo/protobuf/gogoproto