Velvet Star Monitor

Standout celebrity highlights with iconic style.

updates

Widevine plugin crashes when attempting to play Netflix DRM content with firefox

Writer Matthew Harrington

I've recently updated my 18.04 install to 20.04.1 and Netflix fails to play its DRM content using Firefox (at the latest 78.0.2). When attempting to play a video on the Netflix website I am taken to an error page with F7701-1003 and a yellow bar appears at the top of the page frame from firefox saying that the plugin crashed. I took the obvious steps to enable DRM.

The kernel message log contained these lines after each time the plugin would crash:

[440489.660558] MainThread[364746]: segfault at 0 ip 00007fb9fed72335 sp 00007fffa457a790 error 6 in libxul.so[7fb9fce9e000+4b5b000]
[440489.660566] Code: 8b 0d f7 80 39 05 48 89 01 c7 04 25 00 00 00 00 47 02 00 00 e8 dc 51 13 fe 48 8d 05 3f c7 d3 03 48 8b 0d d6 80 39 05 48 89 01 <c7> 04 25 00 00 00 00 49 02 00 00 e8 bb 51 13 fe 48 8d 05 50 c7 d3

So it looks like the plugin is crashing in libxul.so. To see where, I installed the firefox debug package, and using this SO answer, ran in the bash shell the following (where IP and MAPOFF were taken from the kernel log message):

IP=0x00007fb9fed72335
MAPOFF=0x7fb9fce9e000
ADDR=$(python3 -c "print(hex($IP-$MAPOFF))")
addr2line -j .text -e /usr/lib/firefox/libxul.so $ADDR

With the resulting output:

/build/firefox-k3d8Rk/firefox-78.0.2+build2/obj-x86_64-linux-gnu/dist/include/mozilla/RefPtr.h:67

Looking at the firefox source online (I didn't want to install the source package, I doubt ubuntu has patched this file) doesn't really help much.

I was thinking it could be a seccomp issue similar to this one. So I disabled all sandboxing why running with these environment variables set: MOZ_DISABLE_CONTENT_SANDBOX=1 MOZ_DISABLE_GMP_SANDBOX=1. But that didn't help either.

I've tried attaching a gdb instance to the plugin container using these instructions. And while I can attach to the plugin container, gdb never catches anything and eventually the plugin is terminated. I'm wondering if this is due to some anti-debugging features in the widevine plugin (ie. the library thinks its being debugged and is intentionally crashing).

Then I used strace to log all syscalls from all processes of the firefox instance and found where the plugin container is crashing. Here's a relevant snippet:

359684 execve("/usr/lib/firefox/plugin-container", ["/usr/lib/firefox/plugin-container", "/home/user/.mozilla/firefox/Media-Streaming-Sites/gmp-widevinecdm/4.10.1582.2", "359458", "true", "gmplugin"], 0x7f6598fb1000 /* 82 vars */ <unfinished ...>
... snip ...
359684 openat(AT_FDCWD, "/home/user/.mozilla/firefox/Media-Streaming-Sites/gmp-widevinecdm/4.10.1582.2/libwidevinecdm.so", O_RDONLY|O_CLOEXEC) = 15</home/user/.mozilla/firefox/Media-Streaming-Sites/gmp-widevinecdm/4.10.1582.2/libwidevinecdm.so>
359684 read(15</home/user/.mozilla/firefox/Media-Streaming-Sites/gmp-widevinecdm/4.10.1582.2/libwidevinecdm.so>, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\0\0\0\0\0\0\0\0\354\16l\0\0\0\0\0\270\23l\0\0\0\0\0\0\0\0\0@\08\0\n\0@\0(\0'"..., 832) = 832
359684 pread64(15</home/user/.mozilla/firefox/Media-Streaming-Sites/gmp-widevinecdm/4.10.1582.2/libwidevinecdm.so>, "\6\0\0\0\4\0\0\0\354\16l\0\0\0\0\0\354\16l\0\0\0\0\0\354\16l\0\0\0\0\0000\2\0\0\0\0\0\0000\2\0\0"..., 560, 7081708) = 560
359684 fstat(15</home/user/.mozilla/firefox/Media-Streaming-Sites/gmp-widevinecdm/4.10.1582.2/libwidevinecdm.so>, {st_mode=S_IFREG|0600, st_size=7085500, ...}) = 0
359684 pread64(15</home/user/.mozilla/firefox/Media-Streaming-Sites/gmp-widevinecdm/4.10.1582.2/libwidevinecdm.so>, "\6\0\0\0\4\0\0\0\354\16l\0\0\0\0\0\354\16l"..., 560, 7081708) = 560
359684 mmap(NULL, 7082268, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 15</home/user/.mozilla/firefox/Media-Streaming-Sites/gmp-widevinecdm/4.10.1582.2/libwidevinecdm.so>, 0) = -1 EPERM (Operation not permitted)
359684 close(15</home/user/.mozilla/firefox/Media-Streaming-Sites/gmp-widevinecdm/4.10.1582.2/libwidevinecdm.so>) = 0
359684 --- SIGSEGV {si_signo=SIGSEGV, si_code=SEGV_MAPERR, si_addr=NULL} ---
359684 rt_sigaction(SIGSEGV, NULL, {sa_handler=0x7fdf19dbc670, sa_mask=[ILL TRAP ABRT BUS FPE SEGV], sa_flags=SA_RESTORER|SA_ONSTACK|SA_SIGINFO, sa_restorer=0x7fdf1db583c0}, 8) = 0
359684 write(7<pipe:[3459405]>, "`\0\0\0001\0\0\0\0\0\0\0MOZ_CRASH(aborting because of MsgProcessingError)\212\0\0\0\34\0\0\0\0\0\0\000359686:\"Chrome_ChildThread\",6\0\0\0X\0\0\0\0\0\0\0/home/user/.mozilla/firefox/Media-Streaming-Sites/gmp-widevinecdm/4.10.1582.2", 201) = 201
359684 close(7<pipe:[3459405]>) = 0
359684 prctl(PR_SET_DUMPABLE, SUID_DUMP_USER) = 0

So in the strace output we can see that the plugin container process is 359684. It is successfully, opening the plugin library file and doing a read and a couple pread64 successfully. Then tries to mmap the file, but fails and shortly there after the process gets a SIGSEGV with code SEGV_MAPERR. The process's SIGSEGV handler is then invoked and an error message is written indicating there was a crash because of a MsgProcessingError in the library.

How can I fix this?

3

1 Answer

TLDR; Verify that the plugin is located on a mount that has execute permissions on.

It turns out the profile was located on a mount with the noexec property. So a call to mmap with PROT_EXEC should fail with EPERM as it did. However, the library uses mmap to load its instructions into memory and then execute them. Once the profile (and thus the plugin file) was moved to a mount with execute priviledges, streaming Netflix content works as expected.

Though I don't explicitly set noexec on any of my mounts, it was being implicitly added because /home/user/.mozilla is a mount point in fstab with the user property, allowing the mount to be done by my user. The user property implicitly adds noexec to the mount.

I'm guessing that I was getting a SEGV_MAPERR because the code assumed that the mmap was successful and tried to run instructions in the mapped memory that was requested. However, since the mmap failed, that memory was not actually mapped.

The moral of the story is, if widevine is crashing and you do weird stuff with your profile locations, make sure the library is able to be executed. This could all have been avoided by having widevine be a package that is installed next to the firefox binaries, but there's probably some legal reason for not doing so.

1

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy