On Mon, Sep 13, 2021 at 10:09 PM Josh Gao <jmgao@xxxxxx> wrote: > > People working on Oculus (and from my past experience and current > discussions with the Googlers CCed here, people working on Android) > have been frustrated with the difficulty of tracking down the precise > caller that triggers an selinux denial, since it might be multiple > layers deep in transitive dependencies of the process that actually > gets blamed. Thiébaud implemented a tracepoint which can be used to > interactively track down a denial, but it has some shortcomings: > > - it requires a tracer running as root (or some equivalently scary set > of capabilities), so it's not really feasible to run it across our > deployment of dogfood devices > > - trace output doesn't provide the full context of the process, so > AFAIK, it's not possible to do things like unwind through JIT > compiled functions, or print syscall arguments that are on the heap > > - it's asynchronous, so you can't go in with a debugger and inspect > program state to figure out why the failing syscall was made in the > first place > > In an ideal world, an selinux failure would have the same sort of > diagnostic tooling as a SIGSEGV. To do this, I propose that we let > processes opt-in to receiving a signal when an avc denial occurs. If a > user wants to debug interactively, they can set it to SIGSTOP manually; > on systems like Android where libc registers a signal handler that > collects a bug report and forwards it through a crash reporting > pipeline, the system can set it to that signal automatically. > > I'm guessing that the best interface for this is a file in procfs at > somewhere along the lines of /proc/$PID/selinux/audit_signal, taking a > signal number. It's probably useful to be able to correlate this with > an audit serial number, so perhaps we should add an si_code value for > this, with a field in siginfo_t? > > To keep this from inadvertently allowing signals to be sent on systems > that would otherwise prevent them entirely, we can add a new access > vectors in process2 to get/set the audit signal. > > I think the setting should be maintained across fork; I'm not sure > whether it should be reset on exec. AT_SECURE transitions almost > definitely should, but I'm not sure about the utility of inheriting it > in the first place: if it's configured to a signal that's set by libc, > and libc itself triggers an audit before it gets around to registering > a signal handler, the process will mysteriously disappear. > > I have a patch against 4.9 that implements most of this [1], but I > wanted to run this by the upstream mailing list to get some feedback > before reimplementing it on linux-next. > > Thanks, > Josh > > 1: https://gist.github.com/jmgao/9c17bcc93d65472d9dd2a17362ed4075 We already have a /proc/$PID/attr directory for LSM-related process attributes. Simple enough to add a new attribute there if we want it to be general/applicable to other LSMs. That interface only allows a task to modify its own attributes (see proc_pid_attr_write); I assume that suffices here? Other attributes set that way (e.g. fscreate / create_sid) are similarly inherited across fork and unconditionally reset on execve. Currently in the case of SELinux those attribute values are stored in the cred security blob, which used to be the task security blob (hence the legacy task_security_struct name) before creds existed. Later LSM revived support for a separate task security blob for the sake of TOMOYO so that does exist if needed but SELinux doesn't currently allocate or use it. AppArmor switched to using it for its task-specific state after it was restored; SELinux could split its current task_security_struct into two parts (per-cred and per-task) and do likewise if that is worthwhile (not sure). With respect to the implementation, it is generally frowned upon to embed SELinux-specific fields and code in the core kernel (versus wrapping in a LSM security field and hooks) and I think most if not all of what you want is achievable through existing security fields and hooks once you add a new attribute to /proc/pid/attr.