1
0
mirror of https://github.com/systemd/systemd.git synced 2024-12-23 21:35:11 +03:00

Merge pull request #14370 from poettering/homed-preparation-misc

four smaller preparation patches from the homed PR
This commit is contained in:
Yu Watanabe 2019-12-18 11:17:59 +09:00 committed by GitHub
commit 51692fab56
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 114 additions and 3 deletions

View File

@ -169,6 +169,8 @@ basic_sources = files('''
process-util.h
procfs-util.c
procfs-util.h
quota-util.c
quota-util.h
random-util.c
random-util.h
ratelimit.c

41
src/basic/quota-util.c Normal file
View File

@ -0,0 +1,41 @@
/* SPDX-License-Identifier: LGPL-2.1+ */
#include <sys/quota.h>
#include "alloc-util.h"
#include "blockdev-util.h"
#include "quota-util.h"
#include "stat-util.h"
int quotactl_devno(int cmd, dev_t devno, int id, void *addr) {
_cleanup_free_ char *devnode = NULL;
int r;
/* Like quotactl() but takes a dev_t instead of a path to a device node, and fixes caddr_t → void*,
* like we should, today */
r = device_path_make_major_minor(S_IFBLK, devno, &devnode);
if (r < 0)
return r;
if (quotactl(cmd, devnode, id, addr) < 0)
return -errno;
return 0;
}
int quotactl_path(int cmd, const char *path, int id, void *addr) {
dev_t devno;
int r;
/* Like quotactl() but takes a path to some fs object, and changes the backing file system. I.e. the
* argument shouldn't be a block device but a regular file system object */
r = get_block_device(path, &devno);
if (r < 0)
return r;
if (devno == 0)
return -ENODEV;
return quotactl_devno(cmd, devno, id, addr);
}

19
src/basic/quota-util.h Normal file
View File

@ -0,0 +1,19 @@
/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
#include <inttypes.h>
#include <sys/quota.h>
#include <sys/types.h>
/* Wrapper around the QCMD() macro of linux/quota.h that removes some undefined behaviour. A typical quota
* command such as QCMD(Q_GETQUOTA, USRQUOTA) cannot be resolved on platforms where "int" is 32bit, as it is
* larger than INT_MAX. Yikes, because that are basically all platforms Linux supports. Let's add a wrapper
* that explicitly takes its arguments as unsigned 32bit, and then converts the shift result explicitly to
* int, acknowledging the undefined behaviour of the kernel headers. This doesn't remove the undefined
* behaviour, but it stops ubsan from complaining about it. */
static inline int QCMD_FIXED(uint32_t cmd, uint32_t type) {
return (int) QCMD(cmd, type);
}
int quotactl_devno(int cmd, dev_t devno, int id, void *addr);
int quotactl_path(int cmd, const char *path, int id, void *addr);

View File

@ -22,8 +22,6 @@ libcore_sources = '''
bpf-firewall.h
cgroup.c
cgroup.h
chown-recursive.c
chown-recursive.h
dbus-automount.c
dbus-automount.h
dbus-cgroup.c

View File

@ -139,3 +139,40 @@ int path_chown_recursive(
return chown_recursive_internal(TAKE_FD(fd), &st, uid, gid, mask); /* we donate the fd to the call, regardless if it succeeded or failed */
}
int fd_chown_recursive(
int fd,
uid_t uid,
gid_t gid,
mode_t mask) {
int duplicated_fd = -1;
struct stat st;
/* Note that the slightly different order of fstat() and the checks here and in
* path_chown_recursive(). That's because when we open the dirctory ourselves we can specify
* O_DIRECTORY and we always want to ensure we are operating on a directory before deciding whether
* the operation is otherwise redundant. */
if (fstat(fd, &st) < 0)
return -errno;
if (!S_ISDIR(st.st_mode))
return -ENOTDIR;
if (!uid_is_valid(uid) && !gid_is_valid(gid) && (mask & 07777) == 07777)
return 0; /* nothing to do */
/* Shortcut, as above */
if ((!uid_is_valid(uid) || st.st_uid == uid) &&
(!gid_is_valid(gid) || st.st_gid == gid) &&
((st.st_mode & ~mask & 07777) == 0))
return 0;
/* Let's duplicate the fd here, as opendir() wants to take possession of it and close it afterwards */
duplicated_fd = fcntl(fd, F_DUPFD_CLOEXEC, 3);
if (duplicated_fd < 0)
return -errno;
return chown_recursive_internal(duplicated_fd, &st, uid, gid, mask); /* fd donated even on failure */
}

View File

@ -4,3 +4,5 @@
#include <sys/types.h>
int path_chown_recursive(const char *path, uid_t uid, gid_t gid, mode_t mask);
int fd_chown_recursive(int fd, uid_t uid, gid_t gid, mode_t mask);

View File

@ -37,6 +37,8 @@ shared_sources = files('''
cgroup-setup.h
cgroup-show.c
cgroup-show.h
chown-recursive.c
chown-recursive.h
clean-ipc.c
clean-ipc.h
clock-util.c

View File

@ -1193,6 +1193,15 @@ int varlink_close(Varlink *v) {
return 1;
}
Varlink* varlink_close_unref(Varlink *v) {
if (!v)
return NULL;
(void) varlink_close(v);
return varlink_unref(v);
}
Varlink* varlink_flush_close_unref(Varlink *v) {
if (!v)
@ -1200,7 +1209,6 @@ Varlink* varlink_flush_close_unref(Varlink *v) {
(void) varlink_flush(v);
(void) varlink_close(v);
return varlink_unref(v);
}

View File

@ -73,6 +73,7 @@ int varlink_flush(Varlink *v);
int varlink_close(Varlink *v);
Varlink* varlink_flush_close_unref(Varlink *v);
Varlink* varlink_close_unref(Varlink *v);
/* Enqueue method call, not expecting a reply */
int varlink_send(Varlink *v, const char *method, JsonVariant *parameters);
@ -152,6 +153,7 @@ int varlink_server_set_connections_max(VarlinkServer *s, unsigned m);
int varlink_server_set_description(VarlinkServer *s, const char *description);
DEFINE_TRIVIAL_CLEANUP_FUNC(Varlink *, varlink_unref);
DEFINE_TRIVIAL_CLEANUP_FUNC(Varlink *, varlink_close_unref);
DEFINE_TRIVIAL_CLEANUP_FUNC(Varlink *, varlink_flush_close_unref);
DEFINE_TRIVIAL_CLEANUP_FUNC(VarlinkServer *, varlink_server_unref);