0

I have a linux application which loads *.so libraries using a modified rpath (set during installation). It also needs to run with realtime priority.

To get realtime priority it does this:

sched_param sched;
sched.sched_priority = 70;
sched_setscheduler(getpid(), SCHED_FIFO, &sched);

However sched_setscheduler is a privilaged method, protected by the CAP_SYS_NICE capability. Therefore, to get realtime priority without running as root, I add setcap to my postinst:

setcap cap_sys_nice+ep /path/to/myapp

However, linux decides that programs should not be allowed to load libraries from rpath if they have extra capabilities.

Is there a way for me to set my own priority and load rpath libraries?

Note: I'd prefer to do this in the application or in the postinst. I'd like to avoid deploying scripts as the only way to launch the application. I know sudo chrt -f -p 70 $! could do it from a script.

Stewart
  • 4,356
  • 2
  • 27
  • 59
  • 1
    You can try `dlopen` to explicitly load the desired library using it's full path. – oakad Jul 17 '18 at 07:09
  • Tried this out. Apparently it's not just dynamically loaded libraries, it's **any** library which uses the rpath. So if I link to a *.so at compile time and install both binaries togeather, I still get the problem. Note that I'm installing to `/opt/..` so the libraries can't be installed in the normal system directories. I've edited my question to exclude the word "dynamic" – Stewart Jul 18 '18 at 07:47
  • 1
    Well, you can always tweak the libc. It's not as bad as it sounds - it's done all the time on embedded. For glibc, you'd just want to make sure that `__libc_enable_secure` global never gets set to 1. Otherwise you're bound by secure execution rules, as listed here: http://man7.org/linux/man-pages/man8/ld.so.8.html – oakad Jul 18 '18 at 09:33

1 Answers1

0

I have two solutions which do not involve modifying libc. Both solutions require us to replace the calls to sched_setscheduler() with a call to launch another process directly.

  1. Install a file to /etc/sudoers.d/ with the following line:

    %users ALL=NOPASSWD: /usr/bin/chrt
    

    Then from our application launch sudo as a process with arguments chrt -f -p X Y where X is the configured priority and Y is the result of getpid().

  2. Create a custom chrt with:

    cp $(which chrt) $(DESTDIR)/bin/chrt
    sudo setcap cap_sys_nice+ep $(DESTDIR)/bin/chrt
    sudo chmod 755 $(DESTDIR)/bin/chrt
    

    Then from our application launch chrt as a process with arguments -f -p X Y

Not sure which solution is better. Note this is effectively embedded (or at least purpose built) so I'm not too worried about the security exposure.

Stewart
  • 4,356
  • 2
  • 27
  • 59