Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

systemd does not work with kernel 5.4 #603

Open
1 task done
kkourt opened this issue Jul 30, 2024 · 0 comments
Open
1 task done

systemd does not work with kernel 5.4 #603

kkourt opened this issue Jul 30, 2024 · 0 comments

Comments

@kkourt
Copy link
Collaborator

kkourt commented Jul 30, 2024

Intro

Latest debian systemd (256.4-2) is failing on kernel 5.4

dev-hugepages.mount: Failed to spawn executor: Argument list too long
dev-hugepages.mount: Failed to spawn 'mount' task: Argument list too long
dev-mqueue.mount: Failed to spawn executor: Argument list too long
dev-mqueue.mount: Failed to spawn 'mount' task: Argument list too long
run-lock.mount: Failed to spawn executor: Argument list too long
run-lock.mount: Failed to spawn executor: Argument list too long

More details in: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1077204.

Details

The issue seems to be in systemd's use of pidfd_spawn(): https://github.com/systemd/systemd/blob/a55d1b29a4cc2edc8550c5f4e062f2194807dcd3/src/basic/process-util.c#L2102-L2117.

The code checks wither the error is "Not supported": is https://github.com/systemd/systemd/blob/a55d1b29a4cc2edc8550c5f4e062f2194807dcd3/src/basic/errno-util.h#L161-L171

And if the error is something else, it fails.

On 5.4 the error is E2BIG (the clone3 syscall is supported, but what is not supported is CLONE_INTO_CGROUP that was added in 5.7 (torvalds/linux@ef2c41c).

As a result, on 5.4 all executions result in E2B

Fix

Workaround

In the meantime, here's a workaround where we override glibc and have it always return EOPNOTSUPP in kernels earlier than 5.7.

systemd-pidfd-fix.c:

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <spawn.h>
#include <sys/utsname.h>
#include <dlfcn.h>
#include <ctype.h>

int pidfd_spawn(int *restrict pidfd,
	const char *restrict file,
	const posix_spawn_file_actions_t *restrict facts,
	const posix_spawnattr_t *restrict attrp,
	char *const argv[restrict],
	char *const envp[restrict]);

int pidfd_spawn (int *restrict pidfd,
	const char *restrict file,
	const posix_spawn_file_actions_t *restrict facts,
	const posix_spawnattr_t *restrict attrp,
	char *const argv[restrict],
	char *const envp[restrict])
{
	struct utsname buff;
	if (uname(&buff) == 0) {
		long ver[16];
		int i = 0;
		char *p = buff.release;
		while (*p) {
        		if (isdigit(*p)) {
            			ver[i] = strtol(p, &p, 10);
            			i++;
        		} else {
            			p++;
        		}
    		}
		printf("%ld.%ld.%ld\n", ver[0], ver[1], ver[2]);
		if (ver[0] <= 5 && ver[0] < 7) {
			return ENOSYS;
		}
	}

	typeof(pidfd_spawn) *f = dlsym(RTLD_NEXT, "pidfd_spawn");
	if (!f) {
		return EINVAL;
	}

	return f(pidfd, file, facts, attrp, argv, envp);
}

gcc -Wall -O2 -ldl -fPIC -shared -o systemd-pidfd-fix.so systemd-pidfd-fix.c

And add it to /etc/ld.so.preload:

/systemd-pidfd-fix.so

Misc

Reproducer program:

#define _GNU_SOURCE

#include <stdio.h>
#include <spawn.h>
#include <fcntl.h>
#include <string.h>

int main(int argc, char **argv)
{
	int ret;
	int pidfd;
	char path[] = "/bin/true";
	posix_spawnattr_t attr;

	char *eargv[] = {"true", NULL};
	char *envp[] = {NULL};

	int cgroup_fd = open("/sys/fs/cgroup", O_DIRECTORY);
	if (cgroup_fd == -1)
		perror("sys/fs/cgroup");
	
	ret = posix_spawnattr_init(&attr);
	if (ret != 0)
		perror("init");

	ret = posix_spawnattr_setcgroup_np(&attr, cgroup_fd);
	if (ret != 0)
		perror("setcgroup");


	short flags = POSIX_SPAWN_SETCGROUP;
        ret = posix_spawnattr_setflags(&attr, flags);
        if (ret != 0)
		perror("setflags");
	ret = pidfd_spawn(&pidfd, path, NULL, &attr, eargv, envp);
	printf("ret=%s (%d)\n", strerror(ret), ret);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant