Merge pull request #26969 from DaanDeMeyer/xopenat-label

fs-util: Add labelling support to xopenat()
This commit is contained in:
Daan De Meyer
2023-05-31 14:35:50 +02:00
committed by GitHub
51 changed files with 226 additions and 78 deletions
+9 -3
View File
@@ -325,7 +325,11 @@ int chaseat(int dir_fd, const char *path, ChaseFlags flags, char **ret_path, int
return r;
if (FLAGS_SET(flags, CHASE_MKDIR_0755) && !isempty(todo)) {
child = xopenat(fd, first, O_DIRECTORY|O_CREAT|O_EXCL|O_NOFOLLOW|O_CLOEXEC, 0755);
child = xopenat(fd,
first,
O_DIRECTORY|O_CREAT|O_EXCL|O_NOFOLLOW|O_CLOEXEC,
/* xopen_flags = */ 0,
0755);
if (child < 0)
return child;
} else if (FLAGS_SET(flags, CHASE_PARENT) && isempty(todo)) {
@@ -628,6 +632,7 @@ int chase_and_open(const char *path, const char *root, ChaseFlags chase_flags, i
/* Shortcut this call if none of the special features of this call are requested */
return RET_NERRNO(xopenat(AT_FDCWD, path,
open_flags | (FLAGS_SET(chase_flags, CHASE_NOFOLLOW) ? O_NOFOLLOW : 0),
/* xopen_flags = */ 0,
mode));
r = chase(path, root, CHASE_PARENT|chase_flags, &p, &path_fd);
@@ -645,7 +650,7 @@ int chase_and_open(const char *path, const char *root, ChaseFlags chase_flags, i
return r;
}
r = xopenat(path_fd, strempty(fname), open_flags|O_NOFOLLOW, mode);
r = xopenat(path_fd, strempty(fname), open_flags|O_NOFOLLOW, /* xopen_flags = */ 0, mode);
if (r < 0)
return r;
@@ -834,6 +839,7 @@ int chase_and_openat(int dir_fd, const char *path, ChaseFlags chase_flags, int o
/* Shortcut this call if none of the special features of this call are requested */
return RET_NERRNO(xopenat(dir_fd, path,
open_flags | (FLAGS_SET(chase_flags, CHASE_NOFOLLOW) ? O_NOFOLLOW : 0),
/* xopen_flags = */ 0,
mode));
r = chaseat(dir_fd, path, chase_flags|CHASE_PARENT, &p, &path_fd);
@@ -846,7 +852,7 @@ int chase_and_openat(int dir_fd, const char *path, ChaseFlags chase_flags, int o
return r;
}
r = xopenat(path_fd, strempty(fname), open_flags|O_NOFOLLOW, mode);
r = xopenat(path_fd, strempty(fname), open_flags|O_NOFOLLOW, /* xopen_flags = */ 0, mode);
if (r < 0)
return r;
+39 -11
View File
@@ -14,6 +14,7 @@
#include "fileio.h"
#include "fs-util.h"
#include "hostname-util.h"
#include "label.h"
#include "lock-util.h"
#include "log.h"
#include "macro.h"
@@ -1034,7 +1035,7 @@ int open_mkdir_at(int dirfd, const char *path, int flags, mode_t mode) {
path = fname;
}
fd = xopenat(dirfd, path, flags|O_CREAT|O_DIRECTORY|O_NOFOLLOW, mode);
fd = xopenat(dirfd, path, flags|O_CREAT|O_DIRECTORY|O_NOFOLLOW, /* xopen_flags = */ 0, mode);
if (IN_SET(fd, -ELOOP, -ENOTDIR))
return -EEXIST;
if (fd < 0)
@@ -1090,7 +1091,7 @@ int openat_report_new(int dirfd, const char *pathname, int flags, mode_t mode, b
}
}
int xopenat(int dir_fd, const char *path, int flags, mode_t mode) {
int xopenat(int dir_fd, const char *path, int open_flags, XOpenFlags xopen_flags, mode_t mode) {
_cleanup_close_ int fd = -EBADF;
bool made = false;
int r;
@@ -1099,14 +1100,20 @@ int xopenat(int dir_fd, const char *path, int flags, mode_t mode) {
assert(path);
if (isempty(path)) {
assert(!FLAGS_SET(flags, O_CREAT|O_EXCL));
return fd_reopen(dir_fd, flags & ~O_NOFOLLOW);
assert(!FLAGS_SET(open_flags, O_CREAT|O_EXCL));
return fd_reopen(dir_fd, open_flags & ~O_NOFOLLOW);
}
if (FLAGS_SET(flags, O_DIRECTORY|O_CREAT)) {
if (FLAGS_SET(open_flags, O_CREAT) && FLAGS_SET(xopen_flags, XO_LABEL)) {
r = label_ops_pre(dir_fd, path, FLAGS_SET(open_flags, O_DIRECTORY) ? S_IFDIR : S_IFREG);
if (r < 0)
return r;
}
if (FLAGS_SET(open_flags, O_DIRECTORY|O_CREAT)) {
r = RET_NERRNO(mkdirat(dir_fd, path, mode));
if (r == -EEXIST) {
if (FLAGS_SET(flags, O_EXCL))
if (FLAGS_SET(open_flags, O_EXCL))
return -EEXIST;
made = false;
@@ -1115,10 +1122,17 @@ int xopenat(int dir_fd, const char *path, int flags, mode_t mode) {
else
made = true;
flags &= ~(O_EXCL|O_CREAT);
if (FLAGS_SET(xopen_flags, XO_LABEL)) {
r = label_ops_post(dir_fd, path);
if (r < 0)
return r;
}
open_flags &= ~(O_EXCL|O_CREAT);
xopen_flags &= ~XO_LABEL;
}
fd = RET_NERRNO(openat(dir_fd, path, flags, mode));
fd = RET_NERRNO(openat(dir_fd, path, open_flags, mode));
if (fd < 0) {
if (IN_SET(fd,
/* We got ENOENT? then someone else immediately removed it after we
@@ -1137,10 +1151,24 @@ int xopenat(int dir_fd, const char *path, int flags, mode_t mode) {
return fd;
}
if (FLAGS_SET(open_flags, O_CREAT) && FLAGS_SET(xopen_flags, XO_LABEL)) {
r = label_ops_post(dir_fd, path);
if (r < 0)
return r;
}
return TAKE_FD(fd);
}
int xopenat_lock(int dir_fd, const char *path, int flags, mode_t mode, LockType locktype, int operation) {
int xopenat_lock(
int dir_fd,
const char *path,
int open_flags,
XOpenFlags xopen_flags,
mode_t mode,
LockType locktype,
int operation) {
_cleanup_close_ int fd = -EBADF;
int r;
@@ -1150,13 +1178,13 @@ int xopenat_lock(int dir_fd, const char *path, int flags, mode_t mode, LockType
/* POSIX/UNPOSIX locks don't work on directories (errno is set to -EBADF so let's return early with
* the same error here). */
if (FLAGS_SET(flags, O_DIRECTORY) && locktype != LOCK_BSD)
if (FLAGS_SET(open_flags, O_DIRECTORY) && locktype != LOCK_BSD)
return -EBADF;
for (;;) {
struct stat st;
fd = xopenat(dir_fd, path, flags, mode);
fd = xopenat(dir_fd, path, open_flags, xopen_flags, mode);
if (fd < 0)
return fd;
+6 -2
View File
@@ -132,6 +132,10 @@ int open_mkdir_at(int dirfd, const char *path, int flags, mode_t mode);
int openat_report_new(int dirfd, const char *pathname, int flags, mode_t mode, bool *ret_newly_created);
int xopenat(int dir_fd, const char *path, int flags, mode_t mode);
typedef enum XOpenFlags {
XO_LABEL = 1 << 0,
} XOpenFlags;
int xopenat_lock(int dir_fd, const char *path, int flags, mode_t mode, LockType locktype, int operation);
int xopenat(int dir_fd, const char *path, int open_flags, XOpenFlags xopen_flags, mode_t mode);
int xopenat_lock(int dir_fd, const char *path, int open_flags, XOpenFlags xopen_flags, mode_t mode, LockType locktype, int operation);
+30
View File
@@ -0,0 +1,30 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include <errno.h>
#include <stddef.h>
#include "label.h"
static const LabelOps *label_ops = NULL;
int label_ops_set(const LabelOps *ops) {
if (label_ops)
return -EBUSY;
label_ops = ops;
return 0;
}
int label_ops_pre(int dir_fd, const char *path, mode_t mode) {
if (!label_ops || !label_ops->pre)
return 0;
return label_ops->pre(dir_fd, path, mode);
}
int label_ops_post(int dir_fd, const char *path) {
if (!label_ops || !label_ops->post)
return 0;
return label_ops->post(dir_fd, path);
}
+14
View File
@@ -0,0 +1,14 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
#include <sys/types.h>
typedef struct LabelOps {
int (*pre)(int dir_fd, const char *path, mode_t mode);
int (*post)(int dir_fd, const char *path);
} LabelOps;
int label_ops_set(const LabelOps *label_ops);
int label_ops_pre(int dir_fd, const char *path, mode_t mode);
int label_ops_post(int dir_fd, const char *path);
+7 -1
View File
@@ -37,7 +37,13 @@ int make_lock_file_at(int dir_fd, const char *p, int operation, LockFile *ret) {
if (!t)
return -ENOMEM;
fd = xopenat_lock(dfd, p, O_CREAT|O_RDWR|O_NOFOLLOW|O_CLOEXEC|O_NOCTTY, 0600, LOCK_UNPOSIX, operation);
fd = xopenat_lock(dfd,
p,
O_CREAT|O_RDWR|O_NOFOLLOW|O_CLOEXEC|O_NOCTTY,
/* xopen_flags = */ 0,
0600,
LOCK_UNPOSIX,
operation);
if (fd < 0)
return fd == -EAGAIN ? -EBUSY : fd;
+1
View File
@@ -44,6 +44,7 @@ basic_sources = files(
'inotify-util.c',
'io-util.c',
'ioprio-util.c',
'label.c',
'limits-util.c',
'locale-util.c',
'lock-util.c',
+1 -1
View File
@@ -464,7 +464,7 @@ int xstatfsat(int dir_fd, const char *path, struct statfs *ret) {
assert(path);
assert(ret);
fd = xopenat(dir_fd, path, O_PATH|O_CLOEXEC|O_NOCTTY, 0);
fd = xopenat(dir_fd, path, O_PATH|O_CLOEXEC|O_NOCTTY, /* xopen_flags = */ 0, /* mode = */ 0);
if (fd < 0)
return fd;