summaryrefslogtreecommitdiff
path: root/src/basic/io-util.h
diff options
context:
space:
mode:
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2022-11-28 12:12:55 +0100
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2022-12-07 21:11:08 +0100
commit3e4d0f6cf99f8677edd6a237382a65bfe758de03 (patch)
tree248f05e651c5cc61702e6bbbea7c28af95f75485 /src/basic/io-util.h
parent510a146634f3e095b34e2a26023b1b1f99dcb8c0 (diff)
downloadsystemd-3e4d0f6cf99f8677edd6a237382a65bfe758de03.tar.gz
coredump: do not allow user to access coredumps with changed uid/gid/capabilities
When the user starts a program which elevates its permissions via setuid, setgid, or capabilities set on the file, it may access additional information which would then be visible in the coredump. We shouldn't make the the coredump visible to the user in such cases. Reported-by: Matthias Gerstner <mgerstner@suse.de> This reads the /proc/<pid>/auxv file and attaches it to the process metadata as PROC_AUXV. Before the coredump is submitted, it is parsed and if either at_secure was set (which the kernel will do for processes that are setuid, setgid, or setcap), or if the effective uid/gid don't match uid/gid, the file is not made accessible to the user. If we can't access this data, we assume the file should not be made accessible either. In principle we could also access the auxv data from a note in the core file, but that is much more complex and it seems better to use the stand-alone file that is provided by the kernel. Attaching auxv is both convient for this patch (because this way it's passed between the stages along with other fields), but I think it makes sense to save it in general. We use the information early in the core file to figure out if the program was 32-bit or 64-bit and its endianness. This way we don't need heuristics to guess whether the format of the auxv structure. This test might reject some cases on fringe architecutes. But the impact would be limited: we just won't grant the user permissions to view the coredump file. If people report that we're missing some cases, we can always enhance this to support more architectures. I tested auxv parsing on amd64, 32-bit program on amd64, arm64, arm32, and ppc64el, but not the whole coredump handling.
Diffstat (limited to 'src/basic/io-util.h')
-rw-r--r--src/basic/io-util.h9
1 files changed, 9 insertions, 0 deletions
diff --git a/src/basic/io-util.h b/src/basic/io-util.h
index 39728e06bc..3afb134266 100644
--- a/src/basic/io-util.h
+++ b/src/basic/io-util.h
@@ -91,7 +91,16 @@ struct iovec_wrapper *iovw_new(void);
struct iovec_wrapper *iovw_free(struct iovec_wrapper *iovw);
struct iovec_wrapper *iovw_free_free(struct iovec_wrapper *iovw);
void iovw_free_contents(struct iovec_wrapper *iovw, bool free_vectors);
+
int iovw_put(struct iovec_wrapper *iovw, void *data, size_t len);
+static inline int iovw_consume(struct iovec_wrapper *iovw, void *data, size_t len) {
+ /* Move data into iovw or free on error */
+ int r = iovw_put(iovw, data, len);
+ if (r < 0)
+ free(data);
+ return r;
+}
+
int iovw_put_string_field(struct iovec_wrapper *iovw, const char *field, const char *value);
int iovw_put_string_field_free(struct iovec_wrapper *iovw, const char *field, char *value);
void iovw_rebase(struct iovec_wrapper *iovw, char *old, char *new);