mirror of
https://github.com/systemd/systemd-stable.git
synced 2025-02-04 17:47:03 +03:00
commit
1af1c95e30
@ -163,26 +163,37 @@ int null_or_empty_fd(int fd) {
|
|||||||
return null_or_empty(&st);
|
return null_or_empty(&st);
|
||||||
}
|
}
|
||||||
|
|
||||||
int path_is_read_only_fs(const char *path) {
|
static int fd_is_read_only_fs(int fd) {
|
||||||
struct statvfs st;
|
struct statvfs st;
|
||||||
|
|
||||||
assert(path);
|
assert(fd >= 0);
|
||||||
|
|
||||||
if (statvfs(path, &st) < 0)
|
if (fstatvfs(fd, &st) < 0)
|
||||||
return -errno;
|
return -errno;
|
||||||
|
|
||||||
if (st.f_flag & ST_RDONLY)
|
if (st.f_flag & ST_RDONLY)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
/* On NFS, statvfs() might not reflect whether we can actually
|
/* On NFS, fstatvfs() might not reflect whether we can actually write to the remote share. Let's try
|
||||||
* write to the remote share. Let's try again with
|
* again with access(W_OK) which is more reliable, at least sometimes. */
|
||||||
* access(W_OK) which is more reliable, at least sometimes. */
|
if (access_fd(fd, W_OK) == -EROFS)
|
||||||
if (access(path, W_OK) < 0 && errno == EROFS)
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int path_is_read_only_fs(const char *path) {
|
||||||
|
_cleanup_close_ int fd = -EBADFD;
|
||||||
|
|
||||||
|
assert(path);
|
||||||
|
|
||||||
|
fd = open(path, O_CLOEXEC | O_PATH);
|
||||||
|
if (fd < 0)
|
||||||
|
return -errno;
|
||||||
|
|
||||||
|
return fd_is_read_only_fs(fd);
|
||||||
|
}
|
||||||
|
|
||||||
int files_same(const char *filea, const char *fileb, int flags) {
|
int files_same(const char *filea, const char *fileb, int flags) {
|
||||||
struct stat a, b;
|
struct stat a, b;
|
||||||
|
|
||||||
|
@ -190,6 +190,18 @@ static int parse_argv(int argc, char *argv[]) {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int binfmt_mounted_warn(void) {
|
||||||
|
int r;
|
||||||
|
|
||||||
|
r = binfmt_mounted();
|
||||||
|
if (r < 0)
|
||||||
|
return log_error_errno(r, "Failed to check if /proc/sys/fs/binfmt_misc is mounted: %m");
|
||||||
|
if (r == 0)
|
||||||
|
log_debug("/proc/sys/fs/binfmt_misc is not mounted in read-write mode, skipping.");
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
static int run(int argc, char *argv[]) {
|
static int run(int argc, char *argv[]) {
|
||||||
int r, k;
|
int r, k;
|
||||||
|
|
||||||
@ -206,13 +218,17 @@ static int run(int argc, char *argv[]) {
|
|||||||
if (arg_unregister)
|
if (arg_unregister)
|
||||||
return disable_binfmt();
|
return disable_binfmt();
|
||||||
|
|
||||||
if (argc > optind)
|
if (argc > optind) {
|
||||||
|
r = binfmt_mounted_warn();
|
||||||
|
if (r <= 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
for (int i = optind; i < argc; i++) {
|
for (int i = optind; i < argc; i++) {
|
||||||
k = apply_file(argv[i], false);
|
k = apply_file(argv[i], false);
|
||||||
if (k < 0 && r >= 0)
|
if (k < 0 && r >= 0)
|
||||||
r = k;
|
r = k;
|
||||||
}
|
}
|
||||||
else {
|
} else {
|
||||||
_cleanup_strv_free_ char **files = NULL;
|
_cleanup_strv_free_ char **files = NULL;
|
||||||
|
|
||||||
r = conf_files_list_strv(&files, ".conf", NULL, 0, (const char**) CONF_PATHS_STRV("binfmt.d"));
|
r = conf_files_list_strv(&files, ".conf", NULL, 0, (const char**) CONF_PATHS_STRV("binfmt.d"));
|
||||||
@ -225,6 +241,10 @@ static int run(int argc, char *argv[]) {
|
|||||||
return cat_files(NULL, files, 0);
|
return cat_files(NULL, files, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
r = binfmt_mounted_warn();
|
||||||
|
if (r <= 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
/* Flush out all rules */
|
/* Flush out all rules */
|
||||||
r = write_string_file("/proc/sys/fs/binfmt_misc/status", "-1", WRITE_STRING_FILE_DISABLE_BUFFER);
|
r = write_string_file("/proc/sys/fs/binfmt_misc/status", "-1", WRITE_STRING_FILE_DISABLE_BUFFER);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
|
@ -5,10 +5,30 @@
|
|||||||
#include <sys/vfs.h>
|
#include <sys/vfs.h>
|
||||||
|
|
||||||
#include "binfmt-util.h"
|
#include "binfmt-util.h"
|
||||||
|
#include "errno-util.h"
|
||||||
|
#include "fd-util.h"
|
||||||
#include "fileio.h"
|
#include "fileio.h"
|
||||||
|
#include "fs-util.h"
|
||||||
#include "missing_magic.h"
|
#include "missing_magic.h"
|
||||||
#include "stat-util.h"
|
#include "stat-util.h"
|
||||||
|
|
||||||
|
int binfmt_mounted(void) {
|
||||||
|
_cleanup_close_ int fd = -EBADF;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
fd = RET_NERRNO(open("/proc/sys/fs/binfmt_misc", O_CLOEXEC | O_DIRECTORY | O_PATH));
|
||||||
|
if (fd == -ENOENT)
|
||||||
|
return false;
|
||||||
|
if (fd < 0)
|
||||||
|
return fd;
|
||||||
|
|
||||||
|
r = fd_is_fs_type(fd, BINFMTFS_MAGIC);
|
||||||
|
if (r <= 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
return access_fd(fd, W_OK) >= 0;
|
||||||
|
}
|
||||||
|
|
||||||
int disable_binfmt(void) {
|
int disable_binfmt(void) {
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
@ -18,13 +38,13 @@ int disable_binfmt(void) {
|
|||||||
* We are a bit careful here, since binfmt_misc might still be an autofs which we don't want to
|
* We are a bit careful here, since binfmt_misc might still be an autofs which we don't want to
|
||||||
* trigger. */
|
* trigger. */
|
||||||
|
|
||||||
r = path_is_fs_type("/proc/sys/fs/binfmt_misc", BINFMTFS_MAGIC);
|
r = binfmt_mounted();
|
||||||
if (r == 0 || r == -ENOENT) {
|
|
||||||
log_debug("binfmt_misc is not mounted, not detaching entries.");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_warning_errno(r, "Failed to determine whether binfmt_misc is mounted: %m");
|
return log_warning_errno(r, "Failed to determine whether binfmt_misc is mounted: %m");
|
||||||
|
if (r == 0) {
|
||||||
|
log_debug("binfmt_misc is not mounted in read-write mode, not detaching entries.");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
r = write_string_file("/proc/sys/fs/binfmt_misc/status", "-1", WRITE_STRING_FILE_DISABLE_BUFFER);
|
r = write_string_file("/proc/sys/fs/binfmt_misc/status", "-1", WRITE_STRING_FILE_DISABLE_BUFFER);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
int binfmt_mounted(void);
|
||||||
int disable_binfmt(void);
|
int disable_binfmt(void);
|
||||||
|
@ -18,7 +18,7 @@ After=proc-sys-fs-binfmt_misc.automount
|
|||||||
After=proc-sys-fs-binfmt_misc.mount
|
After=proc-sys-fs-binfmt_misc.mount
|
||||||
After=local-fs.target
|
After=local-fs.target
|
||||||
Before=sysinit.target shutdown.target
|
Before=sysinit.target shutdown.target
|
||||||
ConditionPathIsReadWrite=/proc/sys/
|
ConditionPathIsMountPoint=/proc/sys/fs/binfmt_misc
|
||||||
ConditionDirectoryNotEmpty=|/lib/binfmt.d
|
ConditionDirectoryNotEmpty=|/lib/binfmt.d
|
||||||
ConditionDirectoryNotEmpty=|/usr/lib/binfmt.d
|
ConditionDirectoryNotEmpty=|/usr/lib/binfmt.d
|
||||||
ConditionDirectoryNotEmpty=|/usr/local/lib/binfmt.d
|
ConditionDirectoryNotEmpty=|/usr/local/lib/binfmt.d
|
||||||
|
Loading…
x
Reference in New Issue
Block a user