Cannot run VLC on de-escalated C program

Viewed 247

I'm trying to indirectly run VLC media player on Linux from a program that runs as root (i.e. sudo ./capture). After running into some error codes that VLC doesn't run as root, I attempted to de-escalate the program's privileges before running, as such

setuid(1000);
setgid(1000);
putenv("HOME=/home/musicman");
putenv("LOGNAME=musicman");
putenv("USER=musicman");
putenv("DISPLAY=:0");
putenv("DESKTOP_SESSION=plasma");
    
printf("Running args: ");
char* ARGS2[] = {"cvlc", "file:///home/musicman/bad_apple.mp3", "vlc://quit", NULL};
for (int i = 0; i < 3; i++)
{
    printf("'%s' ", ARGS2[i]);
}
printf("\n");
execvp(ARGS2[0], ARGS2);

Now, while the intermediary python program runs fine, VLC itself generates the following errors:

Running args: 'cvlc' 'file:///home/musicman/bad_apple.mp3' 'vlc://quit' 
VLC media player 3.0.12 Vetinari (revision 3.0.12-1-0-gd147bb5e7e)
[0000557de32b32c0] vlcpulse audio output error: PulseAudio server connection failure: Connection refused
[0000557de3354f70] dummy interface: using the dummy interface module...
ALSA lib pcm_dmix.c:1075:(snd_pcm_dmix_open) unable to open slave
[0000557de32b32c0] alsa audio output error: cannot open ALSA device "default": Device or resource busy
[0000557de32b32c0] main audio output error: Audio output failed
[0000557de32b32c0] main audio output error: The audio device "default" could not be used:
Device or resource busy.
[0000557de32b32c0] main audio output error: module not functional
[00007f5094c48220] main decoder error: failed to create audio output

However, if I just run the following code without sudo

char* ARGS2[] = {"cvlc", "file:///home/musicman/bad_apple.mp3", "vlc://quit", NULL};
printf("Running args: ");
for (int i = 0; i < 3; i++)
{
    printf("'%s' ", ARGS2[i]);
}
printf("\n");
execvp(ARGS2[0], ARGS2);

I get the following output:

Running args: 'cvlc' 'file:///home/musicman/bad_apple.mp3' 'vlc://quit' 
VLC media player 3.0.12 Vetinari (revision 3.0.12-1-0-gd147bb5e7e)
[00005570414ddd00] dummy interface: using the dummy interface module...

...and the song plays. I suspect that, for some reason, PulseAudio is relying on some environmental variables that I'm not providing, but I'm really not sure what I'm missing, as running env | egrep "^PULSE" reveals nothing. Do any of you have ideas?

I'm running on Kubuntu 21.04 with an X11 session and pulseaudio 14.2.

3 Answers

At the end of the day, my primary issue was trying to run a keylogger and VLC in the same process. At @hobbs suggestion, I just added my user to Linux's inputs user group, allowing me to run the keylogger in the user space. The final program was uploaded by my partner to GitHub.

That said, if anyone does come up with an answer to the original question, I will mark that as the correct answer for anyone who comes across a similar situation that can't be side-stepped like my problem was.

Whether any of this is germane to your issue, I don't know but pulseaudio is not designed to run as root.

Expect to see something like the following:

E: [pulseaudio] core-util.c: Home directory not accessible: Permission denied
W: [pulseaudio] main.c: This program is not intended to be run as root (unless --system is specified).
E: [autospawn] core-util.c: Home directory not accessible: Permission denied
W: [autospawn] lock-autospawn.c: Cannot access autospawn lock.
E: [pulseaudio] main.c: Failed to acquire autospawn lock
Home directory not accessible: Permission denied
Connection failure: Connection refused
pa_context_connect() failed: Connection refused
Home directory not accessible: Permission denied

There are ways (optional parameters) around it but they're not recommended.

Specifically:

--system[=BOOL]
              Run as system-wide instance instead  of  per-user.  Please  note
              that  this disables certain features of PulseAudio and is gener‐
              ally not recommended unless the  system  knows  no  local  users
              (e.g.  is  a thin client). This feature needs special configura‐
              tion and a dedicated UNIX user set up. It is highly  recommended
              to combine this with --disallow-module-loading (see below).


--disallow-module-loading[=BOOL]
          Disallow  module  loading after startup. This is a security fea‐
          ture since it disallows additional module loading during runtime
          and  on  user request. It is highly recommended when --system is
          used (see above). Note however, that this  breaks  certain  fea‐
          tures like automatic module loading on hot plug.

Additionally, pulseaudio expects to be able to access a default.pa file, which would normally be found in $HOME/.config/pulse.
There may be issues with that too, if running as root.

I had the same exact problem, and was able to solve by setting the XDG_RUNTIME_DIR environment variable to my user's one (which for the records is /run/user/1000).

No idea why, and indeed that is not mentioned in the list of relevant environment variables... but another FAQ does refer to it. I just found out by trying to add all environment variables one by one until it worked.

Related