Skip to content

limitations

parke edited this page Jan 10, 2022 · 6 revisions

Known limitations of lxroot


Understanding unprivileged Linux namespaces

  • lxroot creates virtual software environments via Linux namespaces.
    • For more info, see user_namespaces(7) and namespaces(7).
    • More specifically: lxroot uses what I call "unprivileged" Linux namespaces.
    • That is, lxroot uses only namespace features that are available to non-root users.
    • Unprivileged Linux namespaces, by their very nature, have limitations.
    • Lxroot inherits these limitations.
    • Understanding the limitations of unprivileged namespaces will help you understand (and adapt to) lxroot's own limitations.
    • There are both advantages and limitations to using unprivileged namespaces.
  • Advantages
    • root-access is not required.
    • Safety and security:
      • A process running inside an lxroot environment is limited by the Linux kernel itself.
      • In other words, provided that there are no bugs in the Linux kernel: a process will only be able to perform actions that can be performed by the non-root user who ran lxroot.
    • Performance: namespace functionality is built into the Linux kernel and therefore may be more efficient than alternative virtualization technologies.
  • Limitations
    • root-access is not available to a process running inside the unprivileged namespace.
    • The suid and guid bits are ignored. Consequently: (a) privileged escalation is impossible, and (b) all processes run with the same non-root uid and gid.
      • Aside: Two different users may both lxroot into the same directory. In this case, two different virtual environments are created that happen to share the same directories and files. This can be useful. But at the kernel level, two distinct and separate namespaces are created.
    • Secondary group IDs (also called "supplementary group IDs") may be (are?) ignored (or frozen?). I'm not sure of the exact details. Suffice to say, secondary group IDs may work differently, or may not work at all, inside an unprivileged namespace.
    • A process inside an unprivileged namespace will be limited to actions that can be performed by the non-root user that ran lxroot. Any syscall that attempts to exceed these limitation will fail.
    • Very old Linux kernels lack unprivileged namespaces.
    • Even with modern Linux kernels, unprivileged namespaces may be disabled either: (a) when the kernel was compiled, or (b) at runtime by root.

The suid and sgid bits are ignored

  • As mentioned above, the suid and sgid bits are ignored inside an unprivileged namespace.
  • Advantages
    • Privilege escalation is impossible inside the unprivileged namespace.
  • Disadvantages
    • Programs that rely upon privilege escalation will probably fail.

sudo will fail

The failure of sudo inside an unprivileged namespace is a direct consequence the fact that the suid and sgid bits are ignored.

Possible workarounds

  • Change lxroot -- sudo command to lxroot -r -- command.
  • Change lxroot -- sudo command to lxroot -w -- unshare -r command
    • Note: unshare uses namespaces, just like lxroot. unshare should be as efficient as lxroot.
  • Charge lxroot -- sudo command to lxroot -w -- proot -R / command
    • Note: I am not a proot expert. It is possible there are better options than -R / to use with proot.
    • Note: proot uses ptrace() instead of namespaces. Therefore:
      • proot is noticeably less efficient than lxroot.
      • proot has virtualization capabilities that lxroot lacks.
  • Replace /usr/bin/sudo with the following script, and run lxroot with the -w option:
#! /bin/sh
/usr/bin/unshare  -r  "$@"

I guess alternatively, you could use:

#! /bin/sh
proot  -R /  "$@"

There may be other workarounds beyond the above. It is also possible that there is no easy lxroot-based workaround for your particular situation.


chown will mostly fail

A process running inside an unprivileged namespace will not be able to change the owner of a file. Attempts to change the group of a file may (will?) also fail.

Calls to chown() that change neither the UID nor GID may (will?) succeed.

I've learned that it should be possible for lxroot to use seccomp filters to cause the kernel to ignore all calls to chown(). By "ignore" I mean: the kernel will (a) do nothing yet (b) report success. I have not yet invested any time in exploring use of seccomp.


Other syscalls may fail

Obviously, beyond chown(), there are other syscalls that will also fail inside an unprivileged namespace. Specifically, any syscall should fail when the syscall exceeds the permissions of the non-user that ran lxroot.

It may be possible to extend lxroot to use seccomp to ignore these syscalls as well. I have not yet explored any use of seccomp.