Merge pull request #25291 from keszybz/util-cleanup

Split/rename util.c+h and def.h
This commit is contained in:
Yu Watanabe
2022-11-09 09:23:17 +09:00
committed by GitHub
361 changed files with 1107 additions and 1080 deletions

2
TODO
View File

@@ -72,8 +72,6 @@ Regularly:
Janitorial Clean-ups:
* Rearrange tests so that the various test-xyz.c match a specific src/basic/xyz.c again
* rework mount.c and swap.c to follow proper state enumeration/deserialization
semantics, like we do for device.c now

File diff suppressed because it is too large Load Diff

View File

@@ -2,6 +2,7 @@
#include <getopt.h>
#include "build.h"
#include "main-func.h"
#include "udev-util.h"

View File

@@ -9,6 +9,7 @@
#include "sd-daemon.h"
#include "alloc-util.h"
#include "build.h"
#include "env-util.h"
#include "errno-util.h"
#include "escape.h"
@@ -23,7 +24,6 @@
#include "string-util.h"
#include "strv.h"
#include "terminal-util.h"
#include "util.h"
static char **arg_listen = NULL;
static bool arg_accept = false;

View File

@@ -3,7 +3,7 @@
#include "analyze.h"
#include "analyze-cat-config.h"
#include "conf-files.h"
#include "def.h"
#include "constants.h"
#include "nulstr-util.h"
#include "path-util.h"
#include "pretty-print.h"

View File

@@ -37,6 +37,7 @@
#include "analyze-unit-paths.h"
#include "analyze-compare-versions.h"
#include "analyze-verify.h"
#include "build.h"
#include "bus-error.h"
#include "bus-locator.h"
#include "bus-map-properties.h"
@@ -46,7 +47,7 @@
#include "capability-util.h"
#include "conf-files.h"
#include "copy.h"
#include "def.h"
#include "constants.h"
#include "exit-status.h"
#include "extract-word.h"
#include "fd-util.h"
@@ -79,7 +80,6 @@
#include "time-util.h"
#include "tmpfile-util.h"
#include "unit-name.h"
#include "util.h"
#include "verb-log-control.h"
#include "verbs.h"
#include "version.h"

View File

@@ -6,7 +6,8 @@
#include <unistd.h>
#include "ask-password-api.h"
#include "def.h"
#include "build.h"
#include "constants.h"
#include "log.h"
#include "macro.h"
#include "main-func.h"

View File

@@ -19,7 +19,6 @@
#include "string-util.h"
#include "strv.h"
#include "terminal-util.h"
#include "util.h"
#define PCI_CLASS_GRAPHICS_CARD 0x30000

View File

@@ -4,7 +4,6 @@
#include <endian.h>
#include "macro.h"
#include "util.h"
/* A cleaned up architecture definition. We don't want to get lost in
* processor features, models, generations or even ABIs. Hence we

222
src/basic/argv-util.c Normal file
View File

@@ -0,0 +1,222 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include <sched.h>
#include <sys/mman.h>
#include <sys/prctl.h>
#include <unistd.h>
#include "argv-util.h"
#include "errno-util.h"
#include "missing_sched.h"
#include "parse-util.h"
#include "path-util.h"
#include "process-util.h"
#include "string-util.h"
#include "strv.h"
int saved_argc = 0;
char **saved_argv = NULL;
bool invoked_as(char *argv[], const char *token) {
if (!argv || isempty(argv[0]))
return false;
if (isempty(token))
return false;
return strstr(last_path_component(argv[0]), token);
}
bool invoked_by_systemd(void) {
int r;
/* If the process is directly executed by PID1 (e.g. ExecStart= or generator), systemd-importd,
* or systemd-homed, then $SYSTEMD_EXEC_PID= is set, and read the command line. */
const char *e = getenv("SYSTEMD_EXEC_PID");
if (!e)
return false;
if (streq(e, "*"))
/* For testing. */
return true;
pid_t p;
r = parse_pid(e, &p);
if (r < 0) {
/* We know that systemd sets the variable correctly. Something else must have set it. */
log_debug_errno(r, "Failed to parse \"SYSTEMD_EXEC_PID=%s\", ignoring: %m", e);
return false;
}
return getpid_cached() == p;
}
bool argv_looks_like_help(int argc, char **argv) {
char **l;
/* Scans the command line for indications the user asks for help. This is supposed to be called by
* tools that do not implement getopt() style command line parsing because they are not primarily
* user-facing. Detects four ways of asking for help:
*
* 1. Passing zero arguments
* 2. Passing "help" as first argument
* 3. Passing --help as any argument
* 4. Passing -h as any argument
*/
if (argc <= 1)
return true;
if (streq_ptr(argv[1], "help"))
return true;
l = strv_skip(argv, 1);
return strv_contains(l, "--help") ||
strv_contains(l, "-h");
}
static int update_argv(const char name[], size_t l) {
static int can_do = -1;
if (can_do == 0)
return 0;
can_do = false; /* We'll set it to true only if the whole process works */
/* Let's not bother with this if we don't have euid == 0. Strictly speaking we should check for the
* CAP_SYS_RESOURCE capability which is independent of the euid. In our own code the capability generally is
* present only for euid == 0, hence let's use this as quick bypass check, to avoid calling mmap() if
* PR_SET_MM_ARG_{START,END} fails with EPERM later on anyway. After all geteuid() is dead cheap to call, but
* mmap() is not. */
if (geteuid() != 0)
return log_debug_errno(SYNTHETIC_ERRNO(EPERM),
"Skipping PR_SET_MM, as we don't have privileges.");
static size_t mm_size = 0;
static char *mm = NULL;
int r;
if (mm_size < l+1) {
size_t nn_size;
char *nn;
nn_size = PAGE_ALIGN(l+1);
nn = mmap(NULL, nn_size, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
if (nn == MAP_FAILED)
return log_debug_errno(errno, "mmap() failed: %m");
strncpy(nn, name, nn_size);
/* Now, let's tell the kernel about this new memory */
if (prctl(PR_SET_MM, PR_SET_MM_ARG_START, (unsigned long) nn, 0, 0) < 0) {
if (ERRNO_IS_PRIVILEGE(errno))
return log_debug_errno(errno, "PR_SET_MM_ARG_START failed: %m");
/* HACK: prctl() API is kind of dumb on this point. The existing end address may already be
* below the desired start address, in which case the kernel may have kicked this back due
* to a range-check failure (see linux/kernel/sys.c:validate_prctl_map() to see this in
* action). The proper solution would be to have a prctl() API that could set both start+end
* simultaneously, or at least let us query the existing address to anticipate this condition
* and respond accordingly. For now, we can only guess at the cause of this failure and try
* a workaround--which will briefly expand the arg space to something potentially huge before
* resizing it to what we want. */
log_debug_errno(errno, "PR_SET_MM_ARG_START failed, attempting PR_SET_MM_ARG_END hack: %m");
if (prctl(PR_SET_MM, PR_SET_MM_ARG_END, (unsigned long) nn + l + 1, 0, 0) < 0) {
r = log_debug_errno(errno, "PR_SET_MM_ARG_END hack failed, proceeding without: %m");
(void) munmap(nn, nn_size);
return r;
}
if (prctl(PR_SET_MM, PR_SET_MM_ARG_START, (unsigned long) nn, 0, 0) < 0)
return log_debug_errno(errno, "PR_SET_MM_ARG_START still failed, proceeding without: %m");
} else {
/* And update the end pointer to the new end, too. If this fails, we don't really know what
* to do, it's pretty unlikely that we can rollback, hence we'll just accept the failure,
* and continue. */
if (prctl(PR_SET_MM, PR_SET_MM_ARG_END, (unsigned long) nn + l + 1, 0, 0) < 0)
log_debug_errno(errno, "PR_SET_MM_ARG_END failed, proceeding without: %m");
}
if (mm)
(void) munmap(mm, mm_size);
mm = nn;
mm_size = nn_size;
} else {
strncpy(mm, name, mm_size);
/* Update the end pointer, continuing regardless of any failure. */
if (prctl(PR_SET_MM, PR_SET_MM_ARG_END, (unsigned long) mm + l + 1, 0, 0) < 0)
log_debug_errno(errno, "PR_SET_MM_ARG_END failed, proceeding without: %m");
}
can_do = true;
return 0;
}
int rename_process(const char name[]) {
bool truncated = false;
/* This is a like a poor man's setproctitle(). It changes the comm field, argv[0], and also the glibc's
* internally used name of the process. For the first one a limit of 16 chars applies; to the second one in
* many cases one of 10 (i.e. length of "/sbin/init") — however if we have CAP_SYS_RESOURCES it is unbounded;
* to the third one 7 (i.e. the length of "systemd". If you pass a longer string it will likely be
* truncated.
*
* Returns 0 if a name was set but truncated, > 0 if it was set but not truncated. */
if (isempty(name))
return -EINVAL; /* let's not confuse users unnecessarily with an empty name */
if (!is_main_thread())
return -EPERM; /* Let's not allow setting the process name from other threads than the main one, as we
* cache things without locking, and we make assumptions that PR_SET_NAME sets the
* process name that isn't correct on any other threads */
size_t l = strlen(name);
/* First step, change the comm field. The main thread's comm is identical to the process comm. This means we
* can use PR_SET_NAME, which sets the thread name for the calling thread. */
if (prctl(PR_SET_NAME, name) < 0)
log_debug_errno(errno, "PR_SET_NAME failed: %m");
if (l >= TASK_COMM_LEN) /* Linux userspace process names can be 15 chars at max */
truncated = true;
/* Second step, change glibc's ID of the process name. */
if (program_invocation_name) {
size_t k;
k = strlen(program_invocation_name);
strncpy(program_invocation_name, name, k);
if (l > k)
truncated = true;
}
/* Third step, completely replace the argv[] array the kernel maintains for us. This requires privileges, but
* has the advantage that the argv[] array is exactly what we want it to be, and not filled up with zeros at
* the end. This is the best option for changing /proc/self/cmdline. */
(void) update_argv(name, l);
/* Fourth step: in all cases we'll also update the original argv[], so that our own code gets it right too if
* it still looks here */
if (saved_argc > 0) {
if (saved_argv[0]) {
size_t k;
k = strlen(saved_argv[0]);
strncpy(saved_argv[0], name, k);
if (l > k)
truncated = true;
}
for (int i = 1; i < saved_argc; i++) {
if (!saved_argv[i])
break;
memzero(saved_argv[i], strlen(saved_argv[i]));
}
}
return !truncated;
}

25
src/basic/argv-util.h Normal file
View File

@@ -0,0 +1,25 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
#include <stdbool.h>
#include "macro.h"
extern int saved_argc;
extern char **saved_argv;
static inline void save_argc_argv(int argc, char **argv) {
/* Protect against CVE-2021-4034 style attacks */
assert_se(argc > 0);
assert_se(argv);
assert_se(argv[0]);
saved_argc = argc;
saved_argv = argv;
}
bool invoked_as(char *argv[], const char *token);
bool invoked_by_systemd(void);
bool argv_looks_like_help(int argc, char **argv);
int rename_process(const char name[]);

View File

@@ -12,7 +12,6 @@
#include "macro.h"
#include "process-util.h"
#include "signal-util.h"
#include "util.h"
int asynchronous_job(void* (*func)(void *p), void *arg) {
sigset_t ss, saved_ss;

View File

@@ -1,6 +1,10 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include <stdio.h>
#include "build.h"
#include "macro.h"
#include "version.h"
const char* const systemd_features =
@@ -226,3 +230,9 @@ const char* const systemd_features =
" default-hierarchy=" DEFAULT_HIERARCHY_NAME
;
int version(void) {
printf("systemd " STRINGIFY(PROJECT_VERSION) " (" GIT_VERSION ")\n%s\n",
systemd_features);
return 0;
}

View File

@@ -4,3 +4,5 @@
#include "version.h"
extern const char* const systemd_features;
int version(void);

View File

@@ -10,7 +10,6 @@
#include "macro.h"
#include "parse-util.h"
#include "stdio-util.h"
#include "util.h"
static const struct capability_name* lookup_capability(register const char *str, register GPERF_LEN_TYPE len);

View File

@@ -11,11 +11,11 @@
#include "cap-list.h"
#include "fileio.h"
#include "log.h"
#include "logarithm.h"
#include "macro.h"
#include "missing_prctl.h"
#include "parse-util.h"
#include "user-util.h"
#include "util.h"
int have_effective_cap(int value) {
_cleanup_cap_free_ cap_t cap = NULL;

View File

@@ -8,7 +8,6 @@
#include "macro.h"
#include "missing_capability.h"
#include "util.h"
#define CAP_ALL UINT64_MAX

View File

@@ -12,7 +12,7 @@
#include "alloc-util.h"
#include "cgroup-util.h"
#include "def.h"
#include "constants.h"
#include "dirent-util.h"
#include "extract-word.h"
#include "fd-util.h"

View File

@@ -9,7 +9,7 @@
#include <sys/statfs.h>
#include <sys/types.h>
#include "def.h"
#include "constants.h"
#include "set.h"
#define SYSTEMD_CGROUP_CONTROLLER_LEGACY "name=systemd"

View File

@@ -32,7 +32,6 @@
#include "string-table.h"
#include "string-util.h"
#include "unaligned.h"
#include "util.h"
#if HAVE_LZ4
DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(LZ4F_compressionContext_t, LZ4F_freeCompressionContext, NULL);

Some files were not shown because too many files have changed in this diff Show More