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

libzmq/ffmpeg: "Address family not supported by protocol (src/ip_resolver.cpp:542) / Aborted" from mpd.service "RestrictAddressFamilies=AF_INET AF_INET6 AF_UNIX AF_NETLINK" #4737

Open
iconoclasthero opened this issue Sep 5, 2024 · 1 comment

Comments

@iconoclasthero
Copy link

iconoclasthero commented Sep 5, 2024

tl;dr: libzmq errors out when RestrictAddressFamilies=AF_INET AF_INET6 AF_UNIX is in the mpd systemd unit file when mpd, running as a system service, calls ffmpeg ... zmq:tcp://127.0.0.1:5555 directly (i.e., in the systemd environment). How to get around this while retaining security in the systemd unit?

Issue description

I was able to get ffmpeg's libzmq implementation to work on the cli either using cat /tmp/mpd.fifo | ffmpeg ... -i - ... zmq:tcp://127.0.0.1:5555 pipe as stdin or just using the named pipe as direct input ffmepg ... -i /tmp/mpd.fifo ... zmq:tcp://127.0.0.1:5555 but it kept erroring out when called directly by mpd's pipe output, e.g.,

audio_output {
    name            "ffmpeg zmq"
    enabled         "no"
    type            "pipe"
    format          "48000:16:2"
    command         "ffmpeg -hide_banner -f s16le -ar 48000 -ac 2 -i - -f mpegts -acodec libopus -b:a 128k zmq:tcp://127.0.0.1:5555 >> /var/log/mpd/ffmpeg.log 2>&1"
}

results in ffmpeg reporting,"Address family not supported by protocol (src/ip_resolver.cpp:542) / Aborted" and mpd just saying it was a broken pipe.

Upon a good bit of investigation and helpful suggestions from #ffmpeg, #bash, and #systemd the offending line in systemd unit file mpd.service was: RestrictAddressFamilies=AF_INET AF_INET6 AF_UNIX

What is the best way to let libzmq have whatever access it needs without significantly sacrificing security (which is described in the mpd.service unit file as one of the "# more paranoid security settings")?

replacing the RestrictAddressFamlies=... with

IPAddressAllow=localhost
IPAddressDeny=any

does solve the problem so if that's the best solution then this can be closed and left for anyone else looking to solve this problem.

Environment

  • libzmq version (commit hash if unreleased):
    these probably came from apt
    ii libzmq3-dev:amd64 4.3.5-1build2 amd64
    ii libzmq5:amd64 4.3.5-1build2 amd64
    however I also compiled libzmq from source because I wasn't sure if libzmq3-dev would work and:
$ ldd $(which ffmpeg) | grep zmq; pkg-config --modversion libzmq
	libzmq.so.5 => /usr/local/lib/libzmq.so.5 (0x000073830ca6c000)
4.3.6

so when ffmpeg was compiled (after its libzmq was patched) with --enable=libzmq it presumably used the 4.3.6 that pkgconfig displayed. (If it's super duper relevant I'm sure I could recompile ffmpeg again to test.)

  • OS: Rhino Linux 2024.02
  • ffmpeg version:
ffmpeg version N-116842-ga87a96105e Copyright (c) 2000-2024 the FFmpeg developers
  built with gcc 14 (Ubuntu 14.2.0-4ubuntu1)
  configuration: --bindir=/usr/local/bin --prefix=/cache/ffmpeg_build --pkg-config-flags=--static --extra-cflags=-I/cache/ffmpeg_build/include --extra-ldflags=-L/cache/ffmpeg_build/lib --extra-libs='-lpthread -lm' --ld=g++ ...  --enable-libzmq
  • Music Player Daemon 0.24 (v0.23.15-1377-g381215fd7+)

Minimal test code / Steps to reproduce the issue

  1. See above...
  2. run mpd as system service using the default systemd unit file included with mpd source.
  3. create an mpd pipe output shown above with the ffmpeg command: command "ffmpeg -hide_banner -f s16le -ar 48000 -ac 2 -i - -f mpegts -acodec libopus -b:a 128k zmq:tcp://127.0.0.1:5555 >> /var/log/mpd/ffmpeg.log 2>&1"
  4. enable the pipe output to ffmpeg/zmq
  5. hear no sound
  6. look at the logs

What's the actual result? (include assertion message & call stack if applicable)

mpd can't use the output, it results in ffmpeg reporting,"Address family not supported by protocol (src/ip_resolver.cpp:542) / Aborted" and mpd just saying it was a broken pipe.

I put an strace in front of ffmpeg in the mpd pipe command in mpd.conf:

$ for i in /var/lib/mpd/ffmpegstrace.log.*; do cat "$i"; hr; done
⋮
read(3, "?\376\v\374\226\375d\373\256\375y\373s\3753\373\17\375\302\372\340\374\205\372I\375\347\372a\375\37\373"..., 36864) = 4096
read(3, "h\3731\372-\373\356\371\302\373\201\372\350\373\214\372\247\373=\372\375\373\242\372\307\373e\372\332\373\212\372"..., 32768) = 8192
read(3, "\203\371\22\371\0\371R\370$\3716\370\260\371{\370\264\372a\371\316\373t\372\320\373]\372\300\372;\371"..., 65536) = 4096
read(3, "f\375\306\376\310\375\312\376Q\376\2\377\3\377L\377o\377@\377\f\377o\376\267\376\250\375]\376\325\374"..., 61440) = 4096
read(3, "w\0Z\377\7\0\355\376\277\377\276\376\254\377\260\376v\377n\376\336\376\303\375s\3769\375\221\376D\375"..., 57344) = 4096
read(3, "u\2#\4\307\2\322\4\362\2J\5\340\2\205\5_\2B\5B\2W\5_\2\256\5\360\1`\5"..., 53248) = 4096
read(3, "\245\374\t\371\220\374\6\371\225\374\30\371v\375\3\372\255\376O\373\317\376\225\373;\376\37\3739\376P\373"..., 49152) = 4096
read(3, "\251\376\"\3752\377D\375O\377\32\375\373\376k\374\374\376\"\374\323\376\317\373\353\376\267\373\235\3777\374"..., 45056) = 4096
read(3, "\237\375H\377k\375\372\376&\375\235\376\24\375\206\376\262\374\23\376\307\373\17\375\241\373\323\374\236\373\263\374"..., 40960) = 4096
read(3, "\246\3\350\3\352\2\31\3@\2v\2\374\1\16\2\271\1\241\1q\1<\1\202\1\16\1\f\1`\0"..., 36864) = 4096
read(3, "\345\4\270\7\230\4\245\7U\4\254\0073\4\314\7\r\4\303\7\363\3\332\7\372\3\360\7\251\3\256\7"..., 32768) = 4096
read(3, "g\6\272\2\263\6-\3\372\6\251\3\307\6\272\3[\6\255\3K\6\354\3w\6\207\4\7\7~\5"..., 65536) = 4096
read(3, "\321\377I\1\252\0\261\1\273\1[\2\266\2\356\2S\0037\3<\3\362\2\263\2B\2\331\1R\1"..., 61440) = 4096
read(3, "\6\365\277\370x\365\372\370\355\365W\371I\366\301\371\261\3667\3726\367\335\372\223\367\\\3732\370\360\373"..., 57344) = 4096
read(3, "\336\372v\1\327\372L\1\355\3727\0014\373/\1/\373\323\0\335\372.\0\312\372\302\3774\373\322\377"..., 53248) = 4096
read(3, "\343\3706\1\242\370\26\1o\370\7\1T\370\365\0\213\370\7\1\311\370#\1\t\371A\1b\371~\1"..., 49152) = 8192
read(3, "\227\361\374\362u\361T\363e\361\237\363!\361\277\363\334\360\356\363\344\360c\364\243\360\216\364G\360\233\364"..., 40960) = 4096
read(3, "\330\377\34\376\203\377!\376\335\376\323\375$\376\201\375\236\375B\375\2\375\367\374\224\374\330\374{\374\343\374"..., 36864) = 4096
brk(0x5a490936a000)                     = 0x5a490936a000
read(3, ">\21<\f\355\20\2\f\7\21,\f\16\21N\f-\21\244\fV\21\346\fV\21\r\r^\21D\r"..., 32768) = 4096
read(3, "\367\5\333\2\241\6c\3\7\7\310\3\220\7L\4\243\7j\4x\7Y\4\207\7`\4\\\79\4"..., 65536) = 4096
read(3, "\301\367\256\363[\367%\363\23\367\315\362\31\367\302\362S\367\345\362\245\3679\363\20\370\231\363J\370\310\363"..., 61440) = 4096
read(3, "\255\377P\0K\377\273\3777\377m\377\24\377\n\3771\377\343\376`\377\311\376*\377M\3768\377\23\376"..., 57344) = 4096
read(3, "@\377\216\372\16\377\221\372\0\377\244\372\17\377\314\372u\377[\373\264\377\237\373\256\377\261\373\225\377\307\373"..., 53248) = 4096
read(3, "%\367<\366\20\367.\366-\367@\366~\367\223\366\202\367\223\366e\367b\366M\367D\366\26\367\2\366"..., 49152) = 4096
read(3, "\230\2\265\0\343\2\n\1g\3\232\1x\3\274\1i\3\267\1H\3\247\1J\3\324\1\253\3N\2"..., 45056) = 4096
read(3, "\244\r\355\f\374\6\220\6\332\4\230\4x\vq\n`\v\371\10\342\n\257\10\341\7\221\7\337\5\367\4"..., 40960) = 4096
read(3, "k\372B\375=\374\240\377\372\375c\2;\1\275\4\376\3\222\6\223\0\210\4\226\375\3\2\367\3730\377"..., 36864) = 4096
read(3, "\204\374q\375\243\373\257\374\266\374\357\374\t\375K\375\256\3732\374\352\3738\374?\375\235\375\7\376p\376"..., 32768) = 4096
read(3, "\215\4Q\5\214\4i\5A\4\21\5\226\3\204\4\335\2\f\4\205\2\314\3\221\3\v\5D\4\25\6"..., 65536) = 4096
read(3, ")\372v\370\374\371\30\370q\372o\370\344\372\344\370\352\372\331\370\205\373q\371,\374%\372\r\375\t\373"..., 61440) = 4096
fstat(3, {st_mode=S_IFIFO|0600, st_size=0, ...}) = 0
fstat(3, {st_mode=S_IFIFO|0600, st_size=0, ...}) = 0
fstat(3, {st_mode=S_IFIFO|0600, st_size=0, ...}) = 0
ioctl(2, TCGETS, 0x7ffd2e003870)        = -1 ENOTTY (Inappropriate ioctl for device)
write(2, "[aist#0:0/pcm_s16le @ 0x5a490935"..., 38) = 38
write(2, "Guessed Channel Layout: stereo\n", 31) = 31
write(2, "Input #0, s16le, from 'fd:':\n", 29) = 29
write(2, "  Duration: ", 12)            = 12
write(2, "N/A", 3)                      = 3
write(2, ", bitrate: ", 11)             = 11
write(2, "1536 kb/s", 9)                = 9
write(2, "\n", 1)                       = 1
write(2, "  Stream #0", 11)             = 11
write(2, ":0", 2)                       = 2
write(2, ": Audio: pcm_s16le, 48000 Hz, st"..., 52) = 52
write(2, "\n", 1)                       = 1
eventfd2(0, EFD_CLOEXEC)                = 4
fcntl(4, F_GETFL)                       = 0x2 (flags O_RDWR)
fcntl(4, F_SETFL, O_RDWR|O_NONBLOCK)    = 0
fcntl(4, F_GETFL)                       = 0x802 (flags O_RDWR|O_NONBLOCK)
fcntl(4, F_SETFL, O_RDWR|O_NONBLOCK)    = 0
getpid()                                = 360340
getpid()                                = 360340
eventfd2(0, EFD_CLOEXEC)                = 5
fcntl(5, F_GETFL)                       = 0x2 (flags O_RDWR)
fcntl(5, F_SETFL, O_RDWR|O_NONBLOCK)    = 0
fcntl(5, F_GETFL)                       = 0x802 (flags O_RDWR|O_NONBLOCK)
fcntl(5, F_SETFL, O_RDWR|O_NONBLOCK)    = 0
getpid()                                = 360340
epoll_create1(EPOLL_CLOEXEC)            = 6
epoll_ctl(6, EPOLL_CTL_ADD, 5, {events=0, data={u32=154481152, u64=99269733593600}}) = 0
epoll_ctl(6, EPOLL_CTL_MOD, 5, {events=EPOLLIN, data={u32=154481152, u64=99269733593600}}) = 0
getpid()                                = 360340
rt_sigaction(SIGRT_1, {sa_handler=0x77902289e830, sa_mask=[], sa_flags=SA_RESTORER|SA_ONSTACK|SA_RESTART|SA_SIGINFO, sa_restorer=0x779022845250}, NULL, 8) = 0
rt_sigprocmask(SIG_UNBLOCK, [RTMIN RT_1], NULL, 8) = 0
mmap(NULL, 8392704, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_STACK, -1, 0) = 0x779021000000
mprotect(0x779021001000, 8388608, PROT_READ|PROT_WRITE) = 0
rt_sigprocmask(SIG_BLOCK, ~[], [], 8)   = 0
clone3({flags=CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID, child_tid=0x779021800990, parent_tid=0x779021800990, exit_signal=0, stack=0x779021000000, stack_size=0x7ffc80, tls=0x7790218006c0}, 88) = -1 ENOSYS (Function not implemented)
clone(child_stack=0x7790217ffc70, flags=CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID, parent_tid=[360346], tls=0x7790218006c0, child_tidptr=0x779021800990) = 360346
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
eventfd2(0, EFD_CLOEXEC)                = 7
fcntl(7, F_GETFL)                       = 0x2 (flags O_RDWR)
fcntl(7, F_SETFL, O_RDWR|O_NONBLOCK)    = 0
fcntl(7, F_GETFL)                       = 0x802 (flags O_RDWR|O_NONBLOCK)
fcntl(7, F_SETFL, O_RDWR|O_NONBLOCK)    = 0
getpid()                                = 360340
epoll_create1(EPOLL_CLOEXEC)            = 8
epoll_ctl(8, EPOLL_CTL_ADD, 7, {events=0, data={u32=154491008, u64=99269733603456}}) = 0
epoll_ctl(8, EPOLL_CTL_MOD, 7, {events=EPOLLIN, data={u32=154491008, u64=99269733603456}}) = 0
mmap(NULL, 8392704, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_STACK, -1, 0) = 0x779020600000
mprotect(0x779020601000, 8388608, PROT_READ|PROT_WRITE) = 0
rt_sigprocmask(SIG_BLOCK, ~[], [], 8)   = 0
clone(child_stack=0x779020dffc70, flags=CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID, parent_tid=[360347], tls=0x779020e006c0, child_tidptr=0x779020e00990) = 360347
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
eventfd2(0, EFD_CLOEXEC)                = 9
fcntl(9, F_GETFL)                       = 0x2 (flags O_RDWR)
fcntl(9, F_SETFL, O_RDWR|O_NONBLOCK)    = 0
fcntl(9, F_GETFL)                       = 0x802 (flags O_RDWR|O_NONBLOCK)
fcntl(9, F_SETFL, O_RDWR|O_NONBLOCK)    = 0
getpid()                                = 360340
getpid()                                = 360340
poll([{fd=9, events=POLLIN}], 1, 0)     = 0 (Timeout)
socket(AF_NETLINK, SOCK_RAW|SOCK_CLOEXEC, NETLINK_ROUTE) = -1 EAFNOSUPPORT (Address family not supported by protocol)
write(2, "Address family not supported by "..., 67) = 67
rt_sigprocmask(SIG_UNBLOCK, [ABRT], NULL, 8) = 0
gettid()                                = 360340
getpid()                                = 360340
tgkill(360340, 360340, SIGABRT)         = 0
--- SIGABRT {si_signo=SIGABRT, si_code=SI_TKILL, si_pid=360340, si_uid=113} ---
+++ killed by SIGABRT +++
######################################################################################################################
rseq(0x779021800fe0, 0x20, 0, 0x53053053) = 0
set_robust_list(0x7790218009a0, 24)     = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
rt_sigprocmask(SIG_BLOCK, ~[RTMIN RT_1], NULL, 8) = 0
sched_getparam(360346, [0])             = 0
sched_getscheduler(360346)              = 0 (SCHED_OTHER)
sched_setscheduler(360346, SCHED_OTHER, [0]) = 0
prctl(PR_SET_NAME, "ZMQbg/Reaper")      = 0
epoll_wait(6,  <unfinished ...>)        = ?
+++ killed by SIGABRT +++
######################################################################################################################
rseq(0x779020e00fe0, 0x20, 0, 0x53053053) = 0
set_robust_list(0x779020e009a0, 24)     = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
rt_sigprocmask(SIG_BLOCK, ~[RTMIN RT_1], NULL, 8) = 0
sched_getparam(360347, [0])             = 0
sched_getscheduler(360347)              = 0 (SCHED_OTHER)
sched_setscheduler(360347, SCHED_OTHER, [0]) = 0
prctl(PR_SET_NAME, "ZMQbg/IO/0")        = 0
epoll_wait(8,  <unfinished ...>)        = ?
+++ killed by SIGABRT +++
#####################################################################################################################

What's the expected result?

I just want ffmpeg to stream music from one machine to the other and I want mpd to be able to use an unnamed pipe so ffmpeg can be called directly from mpd like I've been doing with rtsp instead of some workaround:

audio_output {
     name            "pipe to ffmpeg - suffix"
     enabled         "no"
     type            "pipe"
     format          "48000:16:2"
     command         "ffmpeg -loglevel error -hide_banner -y -f s16le -ar 48000 -ac 2 -vn -i - -c libopus -b:a 64k -f rtsp
rtsp://localhost:8554/mpd/mpd.opus"
}
@iconoclasthero
Copy link
Author

I think one of the following is true:

  • this is a bug with libzmq because it works fine with rtsp.
  • this is a bug in the rtsp implementation of ffmpeg in that rtsp is insecure by not checking those systemd directives.

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

No branches or pull requests

1 participant