Re: Running sndiod as user sndiod on Arch Linux

From: Edward Wandasiewicz <w13ntd_at_gmail.com>
Date: Mon, 18 Sep 2017 11:32:16 +0000
Brilliant! Thanks for making it crystal clear.

Reading https://bbs.archlinux.org/viewtopic.php?id=191669

looks like, on Arch...

If you have a choice then use Type=simple for your systemd services.
It is simpler and systemd will take care or proper process
deamonizing, restarts and shutdowns.

Type=forking is for historical services that cannot be run in
foreground. In this case process itself will take care of its
deamonizing, but systemd should know the child pid somehow so you need
to provide PIDFile= option as well.

The service file below, works fine on Arch, defaults to User=root if
no User specified - if I add Type=forking

$ systemctl restart sndiod.service freezes

[Unit]
Description=Lightweight audio & MIDI server part of the OpenBSD project
After=network.target

[Service]
# User=root
# Type=forking
Restart=on-abort
EnvironmentFile=/etc/conf.d/sndiod
ExecStart=/usr/bin/sndiod -dd $OPTS

[Install]
WantedBy=multi-user.target

Question: I'm trying to get video and audio in sync, via aucat, using
-ao alsa. Can it be done?

#
# Getting aucat output via ALSA
#
cat /etc/asound.conf
# http://billauer.co.il/blog/2014/04/alsa-pipe-playback-capture/

pcm.sndio {
type asym
playback.pcm "sndio-play"

hint {
show on description "OpenBSD sndio"
}
}

pcm.sndio-play {
type plug
slave {
pcm "sndio-raw"
rate 48000
format s16_le
channels 2
}
}

pcm.sndio-raw {
type file
slave.pcm null

format raw
file "| aucat -f snd/0 -i -"
}

pcm.default sndio

Note: pcm.default is sndio, equivalent to alsa:device=sndio

$ mplayer -ao alsa _SOUND_ONLY_FILE_STREAM_

works nicely

$ mplayer -ao alsa _VIDEO_AND AUDIO_FILE_

plays audo, but video hardly plays - not in sync

Is it possible to get video to play in sync with the audio, improve a
setting to aucat, or because it's streaming audio to aucat and it
takes "processing time", it's this that is causing the video stream to
go very slowly?

Could you consider it a proxy for mplayer -ao sndio via ALSA, or is it
a hack, that aucat isn't really designed for, or can this asound.conf
be ok?

On Mon, Sep 18, 2017 at 10:42 AM, Alexandre Ratchov <alex_at_caoua.org> wrote:
> On Mon, Sep 18, 2017 at 09:44:35AM +0000, Edward Wandasiewicz wrote:
>> Does the illustration below, explain why /usr/bin/sndiod is run as user "root"
>> or a local user, and never as user "sndiod"?
>
> Sure.
>
>>
>> #
>> # Lets have a look at the directories created in /tmp
>> # when running sndiod as user { alison, root, sndiod }
>> #
>>
>> #
>> # Run sndiod as user=alison with id 1000
>> #
>>
>> $ ls -la /tmp/aucat-1000
>> total 0
>> drwx------ 2 alison alison  60 Sep 18 08:10 .
>> drwxrwxrwt 9 root   root   240 Sep 18 08:10 ..
>> srw-rw-rw- 1 alison alison   0 Sep 18 08:10 aucat0
>>
>
> this is OK, user alison gets its own daemon with its on private socket
> thus only reachable by his own processes.
>
>> #
>> # Run sndiod as user=root
>> #
>>
>> $ ls -la /tmp
>> drwxr-xr-x  2 root   root     60 Sep 18 08:55 aucat             # _MARK_1.0
>>
>> $ ls -la /tmp/aucat
>> total 0
>> drwxr-xr-x 2 root root  60 Sep 18 08:18 .
>> drwxrwxrwt 9 root root 220 Sep 18 08:18 ..
>> srw-rw-rw- 1 root root   0 Sep 18 08:18 aucat0                  # _MARK_1.1
>>
>
> this is OK as well, the dameon created (as root) a world
> readable/searchable directory with a socket to which any local user
> can connect. At this stage the ps utility should show the sndiod
> process running as user 'sndiod' (even if it was started by root)
> because root privileges are not needed anymore and the daemon has
> changed its user-id to the unprivileged 'sndiod' user-id.
>
> This way if the daemon is comprimised by a local attacker, he doesn't
> get root permissions.
>
>> #
>> # Run sndiod as user=sndiod via systemctl and not "sudo -u sndiod"
>> #
>> # user sndiod is running "/usr/bin/sndiod -dd -f rsnd/1"
>> #
>>
>
> This is not the proper setup for the system daemon. Here, sndiod would
> try to run as if 'sndiod' was a regular user, who would have its own
> private daemon. Thus, only processes that belong to the 'sndiod' user
> would be allowed to use it.
>
>> $ sudo systemctl restart sndiod.service
>>
>> $ ls -la /tmp
>> drwx------  2 sndiod audio    60 Sep 18 08:22 aucat-991         # _MARK_2.0
>>
>> $ sudo ls -la /tmp/aucat-991/
>> total 0
>> drwx------ 2 sndiod audio  60 Sep 18 08:22 .
>> drwxrwxrwt 9 root   root  220 Sep 18 08:22 ..
>> srw-rw-rw- 1 sndiod audio   0 Sep 18 08:22 aucat0               # _MARK_2.1
>>
>
> the socket belongs to the 'sndiod' user and is private (mode 0700,
> owned by user 991)
>
>> #
>> # Run an strace on aucat as our local user
>> #
>>
>> $ strace aucat -f snd/0 -i /use/share/sounds/alsa/Side_Right.wav
>>
>
> can't work as no local users except 991 (aka sndiod) are allowed to
> connect to the private daemon.
>
>> #
>> # BINGO - file can't be opened
>> #
>>
>> connect(4, {sa_family=AF_UNIX, sun_path="/tmp/aucat-1000/aucat0"}, 110) = -1 ENOENT (No such file or directory)
>> connect(4, {sa_family=AF_UNIX, sun_path="/tmp/aucat/aucat0"}, 110) = -1 ENOENT (No such file or directory)
>> close(4)                                = 0
>> write(2, "snd/0: couldn't open audio devic"..., 34snd/0: couldn't open audio device
>>
>
> first, the client (aucat) tries to connect to its own daemon and then
> to the system-shared daemon with no success (neither exists).
>
>> #
>> # Running sndiod as user sndiod, the local user never gets to open /tmp/aucat-991/aucat0
>> # no wonder....
>> # Lets try a symbolic link from /tmp/aucat to /tmp/aucat-991, and try an strace
>> #
>>
>> $ sudo ln -fs aucat-991 aucat
>>
>> #
>> # Run an strace with aucat symbolic linked to aucat-_ID_SNDIO_USER_
>> #
>>
>> $ strace aucat -f snd/0 -i /use/share/sounds/alsa/Side_Right.wav
>>
>> connect(4, {sa_family=AF_UNIX, sun_path="/tmp/aucat-1000/aucat0"}, 110) = -1 ENOENT (No such file or directory)
>> connect(4, {sa_family=AF_UNIX, sun_path="/tmp/aucat/aucat0"}, 110) = -1 EACCES (Permission denied)
>> close(4)                                = 0
>> write(2, "snd/0: couldn't open audio devic"..., 34snd/0: couldn't open audio device
>>
>> #
>> # What's different between running as root, and sndiod?
>> # File aucat0 has the same properties, srw-rw-rw- , see above _MARK_1.1 & _MARK_2.1
>> # Lets make _MARK_2.0 the same as _MARK_1.0
>> #
>> # Lets add {g, o} r+x permissions to /tmp/aucat-991
>> # the same properties as /tmp/aucat - sndiod running as root
>> # and add local users to the group audio
>> #
>>
>> $ sudo chmod g+rx aucat-991
>> $ sudo chmod o+rx aucat-991
>>
>> $ ls -la /tmp
>>
>> drwxrw-rw-  2 sndiod audio    60 Sep 18 08:22 aucat-991
>>
>> $ id
>>
>> uid=1000(alison) gid=1000(alison) groups=1000(alison),10(wheel),990(audio)
>>
>> #
>> # Let's give it a go...
>> #
>>
>> $ strace aucat -f snd/0 -i /use/share/sounds/alsa/Side_Right.wav
>>
>> connect(4, {sa_family=AF_UNIX, sun_path="/tmp/aucat-1000/aucat0"}, 110) = -1 ENOENT (No such file or directory)
>> connect(4, {sa_family=AF_UNIX, sun_path="/tmp/aucat/aucat0"}, 110) = 0
>> getuid()                                = 1000
>> geteuid()                               = 1000
>> getgid()                                = 1000
>> getegid()                               = 1000
>> openat(AT_FDCWD, "/home/alison/.aucat_cookie", O_RDONLY) = 5
>>
>> #
>> # WE HAVE LIFT OFF BABY!!!
>> #
>
> at this point the private socket is public and symlinked it to the
> location of the shared socket. So any client manages to connect to it.
>
>>
>> $ ls -la /tmp
>> lrwxrwxrwx  1 root   root      9 Sep 18 09:12 aucat -> aucat-991
>> drwxr-xr-x  2 sndiod audio    60 Sep 18 09:10 aucat-991
>>
>> Question: Do we run systemctl sndiod.service as user "sndiod"
>
> No. The system server must be started as root, the 'sndiod' is not
> intended to be used directly.
>
>> - where we would have to add an extra file to connect to - aucat of user sndiod
>> - and amend it's directory properties accordingly, with +rx
>> - and users would need to be a member of group audio
>>
>> Question: or run systemctl sndiod.service as user "roor"
>>
>> - no changes required
>>
>
> As root. FWIW, I tried to play with systemd and ended with this
> sndiod.service file. Maybe TimeoutSec could be lowered; not sure, yet.
>
> [Unit]
> Description=sndio audio and MIDI server
> After=network.target
>
> [Service]
> Type=forking
> Restart=on-abort
> EnvironmentFile=-/etc/default/sndiod
> ExecStart=/usr/bin/sndiod $DAEMON_OPTS
>
> [Install]
> WantedBy=multi-user.target
Received on Mon Sep 18 2017 - 13:32:16 CEST

This archive was generated by hypermail 2.3.0 : Tue Aug 09 2022 - 16:23:47 CEST