Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Properties.Get() SIGSEGV(segment violation) #245

Open
leiless opened this issue Jun 27, 2021 · 5 comments
Open

Properties.Get() SIGSEGV(segment violation) #245

leiless opened this issue Jun 27, 2021 · 5 comments

Comments

@leiless
Copy link

leiless commented Jun 27, 2021

Hi, godbus developers, I have a minimal reproducible code to represent the segment fault.

I believe there certainly some kinda misuse of the propsSpec?
And I don't know how to present the Configuration result according to https://developer.gnome.org/NetworkManager/stable/gdbus-org.freedesktop.NetworkManager.DnsManager.html

package main

import (
	"fmt"
	"github.com/godbus/dbus/v5"
	"github.com/godbus/dbus/v5/prop"
)

func main() {
	conn, err := dbus.ConnectSystemBus()
	if err != nil {
		panic(fmt.Errorf("cannot connect to system d-bus"))
	}
	defer conn.Close()

	propsSpec := map[string]map[string]*prop.Prop{
		"org.freedesktop.NetworkManager.DnsManager": {
			"Configuration": {
				nil, // Q: misuse?
				false,
				prop.EmitTrue,
				func(change *prop.Change) *dbus.Error {
					panic(fmt.Errorf("should never be called: %v", change))
				},
			},
		},
	}

	properties, err := prop.Export(conn, "/org/freedesktop/NetworkManager/DnsManager", propsSpec)
	if err != nil {
		panic(fmt.Errorf("cannot export: %w", err))
	}
	fmt.Printf("%+v\n", properties)

	v, err := properties.Get("org.freedesktop.NetworkManager.DnsManager", "Configuration")
	if err != nil {
		panic(fmt.Errorf("cannot get from properties: %w", err))
	}
	fmt.Printf("%+v\n", v)
}

Run result:

$ go run main.go         
&{m:map[org.freedesktop.NetworkManager.DnsManager:map[Configuration:0xc0000aa000]] mut:{w:{state:0 sema:0} writerSem:0 readerSem:0 readerCount:0 readerWait:0} conn:0xc000136000 path:/org/freedesktop/NetworkManager/DnsManager}

panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x98 pc=0x54cd9a]

goroutine 1 [running]:
github.com/godbus/dbus/v5.getSignature(0x0, 0x0, 0x1, 0xe2)
	/home/lei/go/pkg/mod/github.com/godbus/dbus/v5@v5.0.4/sig.go:51 +0x3a
github.com/godbus/dbus/v5.SignatureOf(0xc000143e98, 0x1, 0x1, 0xd, 0xc0000ac088)
	/home/lei/go/pkg/mod/github.com/godbus/dbus/v5@v5.0.4/sig.go:37 +0xa5
github.com/godbus/dbus/v5.MakeVariant(...)
	/home/lei/go/pkg/mod/github.com/godbus/dbus/v5@v5.0.4/variant.go:20
github.com/godbus/dbus/v5/prop.(*Properties).Get(0xc0000ae000, 0x5d19bb, 0x29, 0x5ca792, 0xd, 0x0, 0x0, 0x0, 0x0, 0x0)
	/home/lei/go/pkg/mod/github.com/godbus/dbus/v5@v5.0.4/prop/prop.go:202 +0x15d
main.main()
	/tmp/dbus-demo-go/main.go:35 +0x334
exit status 2

@leiless
Copy link
Author

leiless commented Jun 27, 2021

$ busctl get-property org.freedesktop.NetworkManager /org/freedesktop/NetworkManager/DnsManager org.freedesktop.NetworkManager.DnsManager Configuration
aa{sv} 1 4 "nameservers" as 1 "192.168.200.1" "interface" s "eno1" "priority" i 100 "vpn" b false

@esendjer
Copy link

@leiless Hello!
May I ask, did you manage to solve this issue? I've just faced a pretty similar error in an attempt to get a property for /org/freedesktop/login1/session/self and it looks like you are the sole person with the same issue that I've found.

@leiless
Copy link
Author

leiless commented Nov 30, 2021

May I ask, did you manage to solve this issue?

Not quite yet, have no idea what's going on here, I switch to not to use godbus to solve my problem.

@esendjer
Copy link

esendjer commented Nov 30, 2021

Hey!
I've managed to get around the issue in another way. Perhaps, it might be helpful for you or someone else.
Workable example:

package main

import (
	"fmt"
	"os"

	"github.com/godbus/dbus/v5"
)

const (
	IFACEGETPROP  = "org.freedesktop.DBus.Properties.Get"
	NMNODE        = "org.freedesktop.NetworkManager"
	NMOBJPATH     = "/org/freedesktop/NetworkManager/DnsManager"
	NMIFACECONF   = "org.freedesktop.NetworkManager.DnsManager"
	NMPROPNAME    = "Configuration"
)

func main() {
	conn, err := dbus.ConnectSystemBus()
	if err != nil {
		fmt.Fprintln(os.Stderr, "Failed to connect to system bus:", err)
		os.Exit(1)
	}
	defer conn.Close()

	nmObj := conn.Object(NMNODE, NMOBJPATH)

	nmConfig := nmObj.Call(IFACEGETPROP, 0, NMIFACECONF, NMPROPNAME).Body[0]
	fmt.Printf("NM Config: %+v\n", nmConfig)
}

Output:

$ go run main.go
NM Config: [{"interface": <"eth0">, "nameservers": <["8.8.8.8", "1.1.1.1"]>, "priority": <100>, "vpn": <false>}]

@guelfey
Copy link
Member

guelfey commented Jan 5, 2022

@leiless Are you just trying to read this property from NetworkManager, or are you trying to implement a NetworkManager-compatible interface (i.e. "fake" this property to someone else trying to read it)? Because the first part of your example is accomplishing the latter, but the second part does the former. In case of only reading, @esendjer's code is enough.

The prop package is just a helper if you want to implement the properties interface to that other D-Bus apps can get or set them. It's not used for dealing with properties from other apps, you want https://pkg.go.dev/github.com/godbus/dbus?utm_source=godoc#Object.GetProperty for that. (For the record, if you wanted to export such a Configuration type as mentioned in your link, you'd need to put a []map[string]dbus.Variant as Value in propsSpec).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants