Google Chrome and SE Linux

Google Chrome saying aw snap when it crashes

[107108.433300] chrome[12262]: segfault at bbadbeef ip 0000000000fbea18 sp 00007fffcf348100 error 6 in chrome[400000+27ad000]

When I first tried running the Google Chrome web browser [1] on SE Linux it recursively displayed the error message in the above picture, it first displayed the error and then displayed another error while trying to display a web page to describe the error. The kernel message log included messages such as the above message, it seems that some pointers are initialised to the value 0xbbadbeef to make debugging easier and more amusing.

V8 error: V8 is no longer usable (v8::V8::AddMessageListener())

When I ran Chrome from the command-line it gave the above error message (which was presumably somewhere in the 8MB ~/.xsession-errors file generated from a few hours of running a KDE4 session).

type=AVC msg=audit(1274070733.648:145): avc: denied { execmem } for pid=12833 comm=”chrome” scontext=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 tcontext=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 tclass=process
type=SYSCALL msg=audit(1274070733.648:145): arch=c000003e syscall=9 success=no exit=-131938567594024 a0=7fd863b41000 a1=40000 a2=7 a3=32 items=0 ppid=1 pid=12833 auid=4294967295 uid=1001 gid=1001 euid=1001 suid=1001 fsuid=1001 egid=1001 sgid=1001 fsgid=1001 tty=pts4 ses=4294967295 comm=”chrome” exe=”/opt/google/chrome/chrome” subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=(null)
type=ANOM_ABEND msg=audit(1274070733.648:146): auid=4294967295 uid=1001 gid=1001 ses=4294967295 subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 pid=12833 comm=”chrome” sig=11

V8 is the Google Javascript system which compiles JavaScript code and thus apparently needs read/write/execute access to memory [2]. In /var/log/audit/audit.log I saw the above messages (which would have been in the kernel message log as displayed by dmesg if I didn’t have auditd running). The most relevant parts are that execmem access was requested and that it was by system call 9. From linux/x86_64/syscallent.h in the strace source I discovered that system call 9 on the AMD64 architecture is sys_mmap. Does anyone know a good way to discover which system call has a given number on a particular architecture without reading strace source code?

Attempts to strace the Google Chrome process failed, Chrome gave the error “Failed to move to new PID namespace” after clone() failed. Clone was passed the flag 0x20000000 which according to /usr/include/linux/sched.h is CLONE_NEWPID. It seems that programs which create a new PID namespace (as Google Chrome does) can’t be straced as the clone() call fails. It’s a pity that Chrome doesn’t have an option to run without using this feature, losing the ability to strace it really decreases my ability to find and report bugs in the program – I’m sure that the Google developers want people like me to be able to help them find bugs in their code without undue effort.

Anyway the solution to this problem to allow it to run on the SE Linux Targeted configuration is to run the command “chcon -t unconfined_execmem_exec_t /opt/google/chrome/chrome” which causes the Chrome browser to run in the domain unconfined_execmem_t which is allowed to do such things. Of course we don’t want Chrome processes to run unconfined, I think that the idea I had in 2008 for running Chrome processes in different SE Linux contexts is viable and should be implemented [3].

As a general rule if you are running a program from the command-line on SE Linux with the Targeted configuration (the default and most common configuration) then any time you see an execmem failure logged to the kernel message log or the audit subsystem then you can change the context of the program to unconfined_execmem_exec_t to make the problem go away. Note that this isn’t necessarily a good thing to do, sometimes it’s best to change the program to not require such access. But it seems that in this case the design of V8 requires write/execute memory access to pre-compile JavaScript code.

3 comments to Google Chrome and SE Linux

  • Anonymous

    You can find out syscall numbers by looking at /usr/include/asm/unistd.h from the kernel headers. On x86, that includes either unistd_32.h or unistd_64.h. From that, you can see all the syscall numbers. You can also look at the same header in the kernel source, for any architecture.

    In theory, at least, V8 could learn to change memory from read/write to read/execute before executing it, though of course that would slow it down.

    If you want an strace that works system-wide and supports CLONE_NEWPID and other such things, try trace-cmd, based on ftrace.

  • Ben Hutchings

    There is an option to disable use of pid namespaces, which is –no-sandbox

  • Dave Malcolm

    Python’s signal module will give you the signal numbers for that arch’s build:
    $ pydoc signal
    and then scroll to the bottom