Aleksa Sarai [Fri, 28 Oct 2022 01:58:10 +0000 (12:58 +1100)]
build: drop build-time systemd dependency
On openSUSE, our packages are build in the Open Build Service which does
not have a proper systemd installation that you can query to get the
systemdunitdir.
The simplest solution is to re-add the ability to explicitly set the
systemdunitdir (as was previously possible with the autotools build
system in pre-5.0 LXC).
Aleksa Sarai [Fri, 28 Oct 2022 01:44:39 +0000 (12:44 +1100)]
build: only build init.lxc.static if libcap is statically linkable
Without setting this, the default build will fail if you don't have the
static libcap library installed (on openSUSE this is packaged separately
to libcap-devel).
Aleksa Sarai [Fri, 28 Oct 2022 01:38:20 +0000 (12:38 +1100)]
build: fix handling of dependancies to fix build on openSUSE
Among other things, openSUSE places seccomp.h inside a non-default
include directory (/usr/include/seccomp/seccomp.h) which revealed
several issues with how dependencies were being handled previously.
The most notable issue is that the include cflags of our build
dependencies were not being provided to the recipes for static
executables (yet they still expected access to the dependency headers).
This also involved a minor cleanup of how these dependencies are
collected, and added liburing to the set of private pkg-config libs
(which I assume was an oversight?).
Aleksa Sarai [Fri, 28 Oct 2022 01:27:57 +0000 (12:27 +1100)]
cgroups: fix -Waddress warning
While in principle the pointer could overflow, GCC 12 considers this to
not be possible and issues the following warning:
../src/lxc/cgroups/cgfsng.c: In function ‘__cgfsng_delegate_controllers’:
../src/lxc/cgroups/cgfsng.c:3306:21: warning: the comparison will always evaluate as ‘true’ for the pointer operand in ‘it + 8’ must not be NULL [-Waddress]
3306 | if ((it + 1) && *(it + 1))
| ^
This removes the only build warning triggered when building on openSUSE.
STRERROR_R_CHAR_P is always defined to 0 or 1 depending on the value of
have_func_strerror_r_char_p in meson.build so replace #ifdef by #if to
avoid a redefinition build failure if char *strerror_r is not defined
This fixes a really subtle off-by-one error constructing overlay mount options if rootfs options are provided and modern overlayfs (i.e. requiring a workdir) is used. We need to allow for the extra "," required to separate the extra options when computing the length!
we use HAVE_STATVFS in the code but with meson the check got
lost causing mount_entry to fail to remount some things such
as a bind mount of /dev/fuse via
DEBUG conf - ../src/lxc/conf.c:mount_entry:2416 - Remounting "/dev/fuse" on "/usr/lib/x86_64-linux-gnu/lxc/rootfs/dev/fuse" to respect bind or remount options
ERROR conf - ../src/lxc/conf.c:mount_entry:2459 - Operation not permitted - Failed to mount "/dev/fuse" on "/usr/lib/x86_64-linux-gnu/lxc/rootfs/dev/fuse"
note that the `Flags for ... were ...` line is not showing
up there, which depends on HAVE_STATVFS
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
Serge Hallyn [Tue, 21 Jun 2022 12:50:53 +0000 (14:50 +0200)]
use systemd dbus StartTransientUnit for unpriv cgroup2
If, when init'ing cgroups for a container start, we detect that we
are an unprivileged user on a unified-hierarchy-only system, then we
try to request systemd, through dbus api, to create a new scope for
us with delegation. Call the cgroup it creates for us P1. We then
create P1/init, move ourselves into there, so we can enable the
controllers for delegation to P1's children through P1/cgroup.subtree_control.
On attach, we try to request systemd attach us to the container's
scope. We can't do that ourselves in the normal case, as root owns
our login cgroups.
Create a new command api for the lxc monitor to tell lxc-attach the
systemd scope to which to attach.
Changelog:
* free cgroup_meta.systemd_scope in lxc_conf_free (Thanks Tycho)
* fix some indent
* address some (not all) of brauner's feedback
Raphael Isemann [Tue, 21 Jun 2022 11:10:40 +0000 (13:10 +0200)]
Fix uninitialized read in parse_cap when libcap is not used
fuzz-lxc-cgroup-init currently fails for me with the input
```
lxc.cap.keep=0
```
with this report:
```
==640655==WARNING: MemorySanitizer: use-of-uninitialized-value
#0 0x833c77 in parse_cap /src/lxc/san_build/../src/lxc/conf.c:3161:6
#1 0xaa5fd6 in add_cap_entry /src/lxc/san_build/../src/lxc/confile.c:2462:9
#2 0x9eb69c in set_config_cap_keep /src/lxc/san_build/../src/lxc/confile.c:2503:8
#3 0x974a76 in parse_line /src/lxc/san_build/../src/lxc/confile.c:3115:9
#4 0xea8cac in lxc_file_for_each_line_mmap /src/lxc/san_build/../src/lxc/parse.c:123:9
#5 0x9700a1 in lxc_config_read /src/lxc/san_build/../src/lxc/confile.c:3192:9
#6 0x4a3b50 in LLVMFuzzerTestOneInput /src/lxc/san_build/../src/tests/fuzz-lxc-cgroup-init.c:40:8
#7 0x10556e3 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:611:15
#8 0x1041372 in fuzzer::RunOneTest(fuzzer::Fuzzer*, char const*, unsigned long) /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerDriver.cpp:324:6
#9 0x1046bbc in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerDriver.cpp:860:9
#10 0x106f7b2 in main /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerMain.cpp:20:10
#11 0x7ffff7bc00b2 in __libc_start_main /build/glibc-sMfBJT/glibc-2.31/csu/../csu/libc-start.c:308:16
#12 0x420a9d in _start (/home/fuzzer/oss-fuzz/build/out/lxc/fuzz-lxc-cgroup-init+0x420a9d)
Uninitialized value was created by an allocation of 'last_cap' in the stack frame of function 'parse_cap'
#0 0x832e30 in parse_cap /src/lxc/san_build/../src/lxc/conf.c:3131
```
The reason is that without libcap we parse_cap ends up comparing two
uninitialized values. See the snippet below:
```
int parse_cap(const char *cap_name, __u32 *cap)
{
int ret;
unsigned int res;
__u32 last_cap;
[...]
ret = lxc_caps_last_cap(&last_cap); // NOTE: 1. Call here.
if (ret) // Not taken as dummy lxc_caps_last_cap returned 0.
return -1;
if ((__u32)res > last_cap) // last_cap is uninitialized.
return -1;
*cap = (__u32)res;
return 0;
}
```
Root cause seems to be that the dummy `lxc_caps_last_cap` returns 0 but
doesn't set the last_cap value. This patch just returns -1 as an error code
to avoid the uninitialized read.
Note: When reproducing the bug you need to compile with O0 and *not* with O1
otherwise you will not see the report.
neilnaveen [Wed, 8 Jun 2022 01:08:12 +0000 (01:08 +0000)]
chore: Set permissions for GitHub actions
Restrict the GitHub token permissions only to the required ones; this way, even if the attackers will succeed in compromising your workflow, they won’t be able to do much.
- Included permissions for the action. https://github.com/ossf/scorecard/blob/main/docs/checks.md#token-permissions
[Keeping your GitHub Actions and workflows secure Part 1: Preventing pwn requests](https://securitylab.github.com/research/github-actions-preventing-pwn-requests/)