Legato on Generic Linux

OK, so I think I’ve found the problem. The documentation for this LSM-related stuff is really pretty bad. In 2005, a new Linux-specific socket option flag SO_PASSSEC and a new ancillary data message SCM_SECURITY were added (it looks like part of the SELINUX development). This was not documented and remains undocumented and even (in the case of SCM_SECURITY) unsupported in the libc headers on many modern systems, including this 4.8.12-based Yocto release. But, if this socket option is not set, then passing a file descriptor over that socket will not include the “security context”, which in our case is the SMACK label. The result is that the receiving end doesn’t have the SMACK label that should be attached to the file descriptor it receives, so it defaults to “_”, which the receiving process is not allowed to write to, so the SMACK security check rejects the received file descriptor.

In older kernels, the SMACK security checks for file descriptor passing on unix domain sockets were either not implemented or broken, so our stuff just worked without setting the SO_PASSSEC flag on the socket. But, at some point quite recently (before kernel 4.8) it was fixed. (Actually, it was broken first, then fixed in December 2015 by commit 79be093500791cc25cc31bcaec5a4db62e21497b.)

Anyway, we now need to make a few changes to to get things working on these newer kernels:

  • Add SCM_SECURITY to the standard library headers;
  • in unixSocket.c, in unixSocket_CreateSeqPacketUnnamed(), set the SO_PASSSEC socket option flag;
  • In unixSocket.c, in ExtractAncillaryData(), handle the SCM_SECURITY message (just throw it away);
  • Make the Supervisor add a couple of new SMACK rules:
    • “framework admin w”
    • “admin framework w”
  • Set the extended attribute “security.SMACK64EXEC” to “framework” on all command-line tools bundled with the framework.

The good news is that we don’t have to patch the kernel to get this working. Although, we should probably submit a patch to fix the documentation.