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

[SDK] Run SDK without sudo rights or setcap #84

Open
MaximilienNaveau opened this issue Feb 17, 2021 · 18 comments
Open

[SDK] Run SDK without sudo rights or setcap #84

MaximilienNaveau opened this issue Feb 17, 2021 · 18 comments
Labels
enhancement New feature or request

Comments

@MaximilienNaveau
Copy link
Contributor

The fact of running the connection through a protected socket is problematic as we need sudo rights to run the low level controllers on the robot.

I would like to start here a brainstorming on how to fix it.
I am ready to invest time to fix this issue.

@MaximilienNaveau MaximilienNaveau added the bug Something isn't working label Feb 17, 2021
@thomasfla
Copy link
Member

Hi @MaximilienNaveau I agree that having to run controllers as root is not very nice.

Brainstorming here is a good idea,

I think the proper way to do things is to write a Linux driver in kernel land, but I'm far from being an expert on this topic. I did look at it quickly when writing the first version of the MB SDK but quickly gave up.

@thomasfla thomasfla added enhancement New feature or request and removed bug Something isn't working labels Feb 22, 2021
@MaximilienNaveau
Copy link
Contributor Author

I think the proper way to do things is to write a Linux driver in kernel land

I do not know what that means I will read on this.

I also considered a ip-table mapping the internet port to a none protected one.

pros:

  • you only need sudo to put the port forwarding in place once
  • all users can use the same port to communicate with the robot without sudo.

cons:

  • additional time delay introduced. (I think it could still be an efficient way to do this)

@thomasfla
Copy link
Member

thomasfla commented Feb 23, 2021

Unfortunately we are not using the TCP/IP protocol so there is no notion of Port or IP table. We are working at MAC layer.

The reason for not using TCP/IP but only raw socket, was motivated by the real time wifi connection needs.

If we decide to use IP (with UDP packets for example), we will need to drop realtime wifi feature, and also spend quite some time on the MB firmware again. Also we need to benchmark the latency.

@jviereck
Copy link
Contributor

So it looks like we want to use raw sockets for speed and because we have settled on them in the past. In this case we need to run an executable as root.

I wonder if we could write a small "odri_relay" executable. This one runs with sudo privileges and has the raw socket open. It then exposes the data from and to the raw socket via a UDP connection on a local port. When launching the master board SDK software, instead of connecting to the robot directly, one will connect to the relay station / executable. My hope is that using UDP on localhost doesn't create too much of a latency overhead.

I also though about using shared memory. However, I think shared memory has the same access privileges as the program creating the shared memory object. That means, if the executable needs to run as sudo, then all processes reading and writing to the shared memory will have to run as sudo as well. So this won't solve the problem we are facing now.

In addition, this executeable could pop-open a basic gui to give insight about the traffic quality, raw readings etc to monitor the communication.

What do you think?

@nim65s
Copy link
Contributor

nim65s commented Jun 13, 2021

I think the proper way to drive hardware from linux with elevated privileges is to write a kernel module, and package it with DKMS.

I already started to work on that a long time ago, but it was aborted after some discussions with @thomasfla, and I can't remember why.

@jviereck : your solution would also work, and be easier to implement. But I don't understand why you want to add UDP : I think we could just use a named fifo, which would remove the need for a transport layer.

@jviereck
Copy link
Contributor

jviereck commented Jun 13, 2021 via email

@wxmerkt

This comment has been minimized.

@nim65s
Copy link
Contributor

nim65s commented Jun 13, 2021

@jviereck : the fifo will just be a special file on the file system, and other processes will be able to write to it if they have the permission for this. So I guess we would want it to have a meaningful owner group, with permissions g+w, and add the authorized users in that group. Or, just simply put it a+w.

@wxmerkt : I think you misread the title of the issue ;)

edit: there was an old habit to put fifos in /tmp, but this is no longer the best idea since linux 4.19: https://unix.stackexchange.com/a/503169

@wxmerkt
Copy link

wxmerkt commented Jun 13, 2021

@wxmerkt : I think you misread the title of the issue ;)

You're right, apologies! I'll hide the previous comment

@jviereck
Copy link
Contributor

I think @wxmerkt comment was super helpful! What I would like to do is enable the user to run the robot setup completely without sudo rights.

What we should be able to do is this:

$ make odri_relay
$ sudo setcap cap_net_admin,cap_net_raw+ep odri_relay

Then as the user:

$ odri_relay enp5s0f1 ~/odri_relay.fifo
$ ./your_blmc_program ~/odri_relay.fifo

Because the odri_relay is not depending on anything in the LD_LIBRARY_PATH, this should work.

What do you think?

@MaximilienNaveau
Copy link
Contributor Author

MaximilienNaveau commented Jun 14, 2021

I am also in favor for a solution here,
I would think that a properly packaged kernel module with DKMS would be simpler in the long run though.
The reason is that there is less operations needed from the user to actually use the robot.
Just an installation phase if I understand it properly.
This will prevent people to do some mistakes.
But I guess this will be more work for us @nim65s ?
But that is just my 2 cents on the matter.

I am willing to spend time on this as this is particularly annoying...

@jviereck
Copy link
Contributor

I am willing to spend time on this as this is particularly annoying...

Awesome! Thank you so much @MaximilienNaveau :)

Let me know if you need any help with this or want me to test/look at some code.

@nim65s
Copy link
Contributor

nim65s commented Jun 15, 2021

@MaximilienNaveau : I think we could start with a version of what @jviereck suggested, as this would make a good first step toward having a kernel module later. This would basically be the same code for the 2 versions ; except for the driver, we'll have to follow the kernel API, and the fifo would more probably go into a fixed place in /procor something.

Especially if we don't already have someone proeficient at both writing kernel modules and handling the network as @thomasfla designed it for this project, decoupling both parts seems a good idea to me.

@thomasfla
Copy link
Member

Hi,
Personally, I would prefer the kernel land driver solution, but I can only agree with @nim65s, we need to have a skilled driver programmer to do help us.
The solution proposed by @jviereck then seems to be a valid short term one. I'm only fearing the proliferation of layers that we are slowly incorporating in our control architectures.

To give a little more context about the raw Ethernet choice vs UDP, it was motivated by the wireless packet compatibility. Indeed, in wireless, we do not use the TCP/IP stack since it will require an active connection, handshaking etc. In case of loss of connection, we can not recover instantaneously as we do with the raw packet.

@jviereck
Copy link
Contributor

jviereck commented Sep 2, 2021

I took a look today at how this could get implemented.

Right now the master board SDK supports two types of links - ethernet and wireless. See the code here: https://github.com/open-dynamic-robot-initiative/master-board/blob/master/sdk/master_board_sdk/src/master_board_interface.cpp#L58-L78

My proposal is to add a new third link type / class that inherits from LINK_manager that does the communication via the named pipes towards the odri_relay executable. This way, all the code in the master-board-sdk stays the same and only the code about the communication changes (as one would expect).

@MaximilienNaveau
Copy link
Contributor Author

That's right!
Then we can add the executable of the odri_relay (a.k.a. mb_sdk_relay?) in the master_board_sdk package as well.
I am working on benchmarking the wifi cards right now, but then I am free to work on this.

@thomasfla
Copy link
Member

https://github.com/acontis/atemsys This might be interesting, A kernel module that allows to directly access the MAC layer from userland (developed for EtherCAT).

I don't know yet if this would allow us to access Ethernet as well as Wi-Fi MAC.

@nim65s
Copy link
Contributor

nim65s commented Aug 31, 2022

DKMS would help a lot in the long term. Also that project is GPL, which would contaminate everything else.

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

No branches or pull requests

5 participants