core/socket: several fixlets (#35637)

Fixes https://github.com/systemd/systemd/issues/35635
This commit is contained in:
Lennart Poettering
2025-01-02 18:20:48 +01:00
committed by GitHub
9 changed files with 218 additions and 142 deletions
+7 -11
View File
@@ -26,14 +26,9 @@ static bool ignore_dirent(const struct dirent *de, RecurseDirFlags flags) {
dot_or_dot_dot(de->d_name);
}
int readdir_all(int dir_fd,
RecurseDirFlags flags,
DirectoryEntries **ret) {
int readdir_all(int dir_fd, RecurseDirFlags flags, DirectoryEntries **ret) {
_cleanup_free_ DirectoryEntries *de = NULL;
struct dirent *entry;
DirectoryEntries *nde;
size_t add, sz, j;
int r;
assert(dir_fd >= 0);
@@ -77,11 +72,11 @@ int readdir_all(int dir_fd,
nde = realloc(de, bs);
if (!nde)
return -ENOMEM;
de = nde;
}
de->n_entries = 0;
struct dirent *entry;
FOREACH_DIRENT_IN_BUFFER(entry, de->buffer, de->buffer_size) {
if (ignore_dirent(entry, flags))
continue;
@@ -98,16 +93,17 @@ int readdir_all(int dir_fd,
de->n_entries++;
}
size_t sz, j;
sz = ALIGN(offsetof(DirectoryEntries, buffer) + de->buffer_size);
add = sizeof(struct dirent*) * de->n_entries;
if (add > SIZE_MAX - add)
if (!INC_SAFE(&sz, sizeof(struct dirent*) * de->n_entries))
return -ENOMEM;
nde = realloc(de, sz + add);
nde = realloc(de, sz);
if (!nde)
return -ENOMEM;
de = nde;
de->entries = (struct dirent**) ((uint8_t*) de + ALIGN(offsetof(DirectoryEntries, buffer) + de->buffer_size));
j = 0;
+22 -22
View File
@@ -8,6 +8,28 @@
#include "stat-util.h"
#include "macro.h"
typedef enum RecurseDirFlags {
/* Interpreted by readdir_all() */
RECURSE_DIR_SORT = 1 << 0, /* sort file directory entries before processing them */
RECURSE_DIR_IGNORE_DOT = 1 << 1, /* ignore all dot files ("." and ".." are always ignored) */
RECURSE_DIR_ENSURE_TYPE = 1 << 2, /* guarantees that 'd_type' field of 'de' is not DT_UNKNOWN */
/* Interpreted by recurse_dir() */
RECURSE_DIR_SAME_MOUNT = 1 << 3, /* skips over subdirectories that are submounts */
RECURSE_DIR_INODE_FD = 1 << 4, /* passes an opened inode fd (O_DIRECTORY fd in case of dirs, O_PATH otherwise) */
RECURSE_DIR_TOPLEVEL = 1 << 5, /* call RECURSE_DIR_ENTER/RECURSE_DIR_LEAVE once for top-level dir, too, with dir_fd=-1 and NULL dirent */
} RecurseDirFlags;
typedef struct DirectoryEntries {
size_t n_entries;
struct dirent **entries;
size_t buffer_size;
struct dirent buffer[];
} DirectoryEntries;
int readdir_all(int dir_fd, RecurseDirFlags flags, DirectoryEntries **ret);
int readdir_all_at(int fd, const char *path, RecurseDirFlags flags, DirectoryEntries **ret);
typedef enum RecurseDirEvent {
RECURSE_DIR_ENTER, /* only for dir inodes */
RECURSE_DIR_LEAVE, /* only for dir inodes */
@@ -56,27 +78,5 @@ typedef int (*recurse_dir_func_t)(
const struct statx *sx, /* statx data (only if statx_mask was non-zero) */
void *userdata);
typedef enum RecurseDirFlags {
/* Interpreted by readdir_all() */
RECURSE_DIR_SORT = 1 << 0, /* sort file directory entries before processing them */
RECURSE_DIR_IGNORE_DOT = 1 << 1, /* ignore all dot files ("." and ".." are always ignored) */
RECURSE_DIR_ENSURE_TYPE = 1 << 2, /* guarantees that 'd_type' field of 'de' is not DT_UNKNOWN */
/* Interpreted by recurse_dir() */
RECURSE_DIR_SAME_MOUNT = 1 << 3, /* skips over subdirectories that are submounts */
RECURSE_DIR_INODE_FD = 1 << 4, /* passes an opened inode fd (O_DIRECTORY fd in case of dirs, O_PATH otherwise) */
RECURSE_DIR_TOPLEVEL = 1 << 5, /* call RECURSE_DIR_ENTER/RECURSE_DIR_LEAVE once for top-level dir, too, with dir_fd=-1 and NULL dirent */
} RecurseDirFlags;
typedef struct DirectoryEntries {
size_t n_entries;
struct dirent** entries;
size_t buffer_size;
struct dirent buffer[];
} DirectoryEntries;
int readdir_all(int dir_fd, RecurseDirFlags flags, DirectoryEntries **ret);
int readdir_all_at(int fd, const char *path, RecurseDirFlags flags, DirectoryEntries **ret);
int recurse_dir(int dir_fd, const char *path, unsigned statx_mask, unsigned n_depth_max, RecurseDirFlags flags, recurse_dir_func_t func, void *userdata);
int recurse_dir_at(int atfd, const char *path, unsigned statx_mask, unsigned n_depth_max, RecurseDirFlags flags, recurse_dir_func_t func, void *userdata);
+1
View File
@@ -251,6 +251,7 @@ DEFINE_STRING_TABLE_LOOKUP(slice_state, SliceState);
static const char* const socket_state_table[_SOCKET_STATE_MAX] = {
[SOCKET_DEAD] = "dead",
[SOCKET_START_PRE] = "start-pre",
[SOCKET_START_OPEN] = "start-open",
[SOCKET_START_CHOWN] = "start-chown",
[SOCKET_START_POST] = "start-post",
[SOCKET_LISTENING] = "listening",
+1
View File
@@ -168,6 +168,7 @@ typedef enum SliceState {
typedef enum SocketState {
SOCKET_DEAD,
SOCKET_START_PRE,
SOCKET_START_OPEN,
SOCKET_START_CHOWN,
SOCKET_START_POST,
SOCKET_LISTENING,