gluxon / wireguard-uapi-rs

MIT License
32 stars 10 forks source link

WgSocket::get_device returns ParseDeviceError #9

Closed dhl closed 4 years ago

dhl commented 4 years ago

Summary

wireguard-uapi (1.0.2) is unable to obtain device information for a device with 3 peers.

Environment

wireguard-uapi version: v1.0.2 Operating System: Ubuntu 19.09 WireGuard version: v1.0.20200206

Expected Behavior

wg.get_device(DeviceInterface::from_name("wg0"))

would return device information

Actual Behavior

WgSocket::getDevice returns an Err with parseDeviceError(UnknownDeviceAttributeError { id: 32776 })

gluxon commented 4 years ago

Thanks for the report. I'll take a look this week.

dhl commented 4 years ago

Hi @gluxon. Further investigation shows that the unknown device attribute with ID 32776 is actually the peers attribute.

This is very perplexing. I really couldn't figure out why this is the case.

dhl commented 4 years ago

I am able to reproduce the same problem with neli, so it appears that it is a problem upstream.

gluxon commented 4 years ago

Ah, that's helpful to know. Were you able to reproduce it with one of neli's examples, or did you write a custom test case?

dhl commented 4 years ago

I basically followed what you did with wireguard-uapi to get device information to confirm my hunch that the problem is with neli.

I tried https://git.zx2c4.com/wireguard-tools/tree/contrib/embeddable-wg-library and it was able to decode the attribute ID for peers just fine.

I suspect there's a decoding issue in neli's attribute decoding.

dhl commented 4 years ago

Hi @gluxon, it seems like the bug is due to neli not parsing the nla_type correctly.

When there are multiple peers, the peers will be returned in a nested attribute, and the nla_type in of the peers attribute will be set to 1000000000001000b (or 32776 in decimal), where the most significant bit indicates that the attribute is a nested one.

neli should have masked out that bit and parsed that into 0000000000001000b (or 8 in decimal, corresponding to the actual peers attribute type ID) for the actual nla_type for the peers attribute's Nlattr.

I have reported the issue upstream https://github.com/jbaublitz/neli/issues/84

gluxon commented 4 years ago

I applied the new version of neli (v0.5.0-rc1) but discovered that the nested attributes flag needs to be set on netlink attribute types for Ubuntu 20.04 as well. The patch currently just masks it away for reading the type.

I was curious why the library works on Ubuntu 18.04 and 16.04 (the CI environment). It looks like a Linux kernel commit in 2019 is the source of this change in behavior.

https://github.com/torvalds/linux/commit/ae0be8de9a53cda3505865c11826d8ff0640237c

Going to try always setting the flag on write and always masking it away on read. That behavior should be compatible with linux kernel versions before and after that patch but I'll have to test.

gluxon commented 4 years ago

This should be fixed in v1.0.4. Thanks for filing and deep diving to find the root issue David.

dhl commented 4 years ago

Thank you so much for this, Brandon!