Merge pull request #31419 from AdrianVovk/fixup-largefile-define

Fixup largefile define
This commit is contained in:
Mike Yuan
2024-02-21 13:12:30 +08:00
committed by GitHub
4 changed files with 42 additions and 8 deletions

View File

@@ -8,6 +8,7 @@
#include <sys/socket.h>
#include "macro.h"
#include "missing_fcntl.h"
#include "stdio-util.h"
/* maximum length of fdname */
@@ -21,6 +22,20 @@
#define EBADF_PAIR { -EBADF, -EBADF }
#define EBADF_TRIPLET { -EBADF, -EBADF, -EBADF }
/* Flags that are safe to have set on an FD given to a privileged service to operate on.
* This ensures that clients can't trick a privileged service into giving access to a file the client
* doesn't already have access to (especially via something like O_PATH).
*
* O_NOFOLLOW: For some reason the kernel will return this flag from fcntl; it doesn't go away immediately
* after open(). It should have no effect whatsoever to an already-opened FD, but if it does
* it's decreasing the risk to a privileged service since it disables symlink following.
*
* RAW_O_LARGEFILE: glibc secretly sets this and neglects to hide it from us if we call fcntl. See comment
* in missing_fcntl.h for more details about this.
*/
#define SAFE_FD_FLAGS (O_ACCMODE|O_NOFOLLOW|RAW_O_LARGEFILE)
#define UNSAFE_FD_FLAGS(flags) ((unsigned)(flags) & ~SAFE_FD_FLAGS)
int close_nointr(int fd);
int safe_close(int fd);
void safe_close_pair(int p[static 2]);

View File

@@ -69,9 +69,26 @@
/* So O_LARGEFILE is generally implied by glibc, and defined to zero hence, because we only build in LFS
* mode. However, when invoking fcntl(F_GETFL) the flag is ORed into the result anyway — glibc does not mask
* it away. Which sucks. Let's define the actual value here, so that we can mask it ourselves. */
* it away. Which sucks. Let's define the actual value here, so that we can mask it ourselves.
*
* The precise definition is arch specific, so we use the values defined in the kernel (note that some
* are hexa and others are octal; duplicated as-is from the kernel definitions):
* - alpha, arm, arm64, m68k, mips, parisc, powerpc, sparc: each has a specific value;
* - others: they use the "generic" value (defined in include/uapi/asm-generic/fcntl.h) */
#if O_LARGEFILE != 0
#define RAW_O_LARGEFILE O_LARGEFILE
#else
#define RAW_O_LARGEFILE 0100000
#if defined(__alpha__) || defined(__arm__) || defined(__aarch64__) || defined(__m68k__)
#define RAW_O_LARGEFILE 0400000
#elif defined(__mips__)
#define RAW_O_LARGEFILE 0x2000
#elif defined(__parisc__) || defined(__hppa__)
#define RAW_O_LARGEFILE 000004000
#elif defined(__powerpc__)
#define RAW_O_LARGEFILE 0200000
#elif defined(__sparc__)
#define RAW_O_LARGEFILE 0x40000
#else
#define RAW_O_LARGEFILE 00100000
#endif
#endif

View File

@@ -3,7 +3,6 @@
#include "fd-util.h"
#include "home-util.h"
#include "homed-bus.h"
#include "missing_fcntl.h"
#include "stat-util.h"
#include "strv.h"
@@ -120,8 +119,10 @@ int bus_message_read_blobs(sd_bus_message *m, Hashmap **ret, sd_bus_error *error
/* Refuse fds w/ unexpected flags set. In particular, we don't want to permit O_PATH FDs, since
* those don't actually guarantee that the client has access to the file. */
if ((flags & ~(O_ACCMODE|RAW_O_LARGEFILE)) != 0)
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "FD for %s has unexpected flags set", filename);
if (UNSAFE_FD_FLAGS(flags) != 0)
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
"FD for %s has unexpected flags set: 0%o",
filename, UNSAFE_FD_FLAGS(flags));
r = hashmap_put(blobs, filename, FD_TO_PTR(fd));
if (r < 0)

View File

@@ -22,7 +22,6 @@
#include "journald-wall.h"
#include "memfd-util.h"
#include "memory-util.h"
#include "missing_fcntl.h"
#include "parse-util.h"
#include "path-util.h"
#include "process-util.h"
@@ -363,8 +362,10 @@ void server_process_native_file(
return;
}
if ((flags & ~(O_ACCMODE|RAW_O_LARGEFILE)) != 0) {
log_ratelimit_error(JOURNAL_LOG_RATELIMIT, "Unexpected flags of passed memory fd, ignoring message: %m");
if (UNSAFE_FD_FLAGS(flags) != 0) {
log_ratelimit_error(JOURNAL_LOG_RATELIMIT,
"Unexpected flags of passed memory fd (0%o), ignoring message: %m",
UNSAFE_FD_FLAGS(flags));
return;
}