From fde1d802203869236ae5678082626cca55f1f50d Mon Sep 17 00:00:00 2001 From: Mattias Andrée Date: Wed, 29 Jan 2025 21:07:06 +0100 Subject: First commit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Mattias Andrée --- nokeyrings.c | 127 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 127 insertions(+) create mode 100644 nokeyrings.c (limited to 'nokeyrings.c') diff --git a/nokeyrings.c b/nokeyrings.c new file mode 100644 index 0000000..aaa32c7 --- /dev/null +++ b/nokeyrings.c @@ -0,0 +1,127 @@ +/* See LICENSE file for copyright and license details. */ +#include +#ifndef OPEN_TREE_CLONE +# define MISSING_OPEN_TREE +#endif +#ifndef MOVE_MOUNT_F_EMPTY_PATH +# define MISSING_MOVE_MOUNT +#endif +#if defined(MISSING_OPEN_TREE) || defined(MISSING_MOVE_MOUNT) +# include +# include +#endif +#include +#include +#include + +NUSAGE(125, "utility [argument] ..."); + + + +#ifdef MISSING_OPEN_TREE +static int +open_tree(int dirfd, const char *path, int flags) +{ + return syscall(SYS_open_tree, dirfd, path, flags); +} +#endif + + +#ifdef MISSING_MOVE_MOUNT +static int +move_mount(int dirfd1, const char *path1, int dirfd2, const char *path2, int flags) +{ + return syscall(SYS_move_mount, dirfd1, path1, dirfd2, path2, flags); +} +#endif + + +int +main(int argc, char *argv[]) +{ + struct stat st; + int emptyfd = -1; + int keyringsfd = -1; + char *path = NULL; + struct passwd *pwd; + + libsimple_default_failure_exit = 125; + + ARGBEGIN { + default: + usage(); + } ARGEND; + + if (!argc) + usage(); + + errno = 0; + pwd = getpwuid(getuid()); + if (!pwd) { + if (!errno) { + eprintf("your user does not exist"); + } else if (errno == EIO) { + weprintf("getpwuid :"); + eprintf("this usually indicates that the user not exist"); + } else { + eprintf("getpwuid :"); + } + } + if (!pwd->pw_dir || !*pwd->pw_dir) + eprintf("your user does not have a home directory"); + + path = emalloc(strlen(pwd->pw_dir) + sizeof("/.local/share/keyrings")); + stpcpy(stpcpy(path, pwd->pw_dir), "/.local/share/keyrings"); + + keyringsfd = open(path, O_DIRECTORY); + if (keyringsfd < 0) { + if (errno != ENOENT) + weprintf("open %s O_DIRECTORY:", path); + goto exec; + } + + if (unshare(CLONE_NEWNS)) { + weprintf("unshare CLONE_NEWNS:"); + goto exec; + } + if (mount("none", "/", NULL, MS_REC | MS_SLAVE, NULL)) { + weprintf("mount none / NULL MS_REC|MS_SLAVE NULL:"); + goto exec; + } + + emptyfd = open_tree(AT_FDCWD, "/var/empty", OPEN_TREE_CLONE | OPEN_TREE_CLOEXEC); + if (emptyfd < 0) { + weprintf("open_tree AT_FDCWD /var/empty OPEN_TREE_CLONE|OPEN_TREE_CLOEXEC:"); + goto exec; + } + + if (fstatat(emptyfd, "", &st, AT_EMPTY_PATH | AT_SYMLINK_NOFOLLOW)) { + weprintf("fstatat /var/empty \"\" AT_EMPTY_PATH | AT_SYMLINK_NOFOLLOW:"); + goto exec; + } + if (!S_ISDIR(st.st_mode)) { + weprintf("/var/empty exists but is not a directory:"); + goto exec; + } + + if (move_mount(emptyfd, "", AT_FDCWD, path, MOVE_MOUNT_F_EMPTY_PATH)) { + weprintf("move_mount /var/empty \"\" AT_FDCWD %s MOVE_MOUNT_F_EMPTY_PATH:", path); + goto exec; + } + +exec: + free(path); + if (emptyfd >= 0) + close(emptyfd); + if (keyringsfd >= 0) + close(keyringsfd); + + if (setegid(getgid())) + eprintf("setegid :"); + if (seteuid(getuid())) + eprintf("seteuid :"); + + execvp(argv[0], argv); + enprintf(errno == ENOENT ? 127 : 126, "execvp %s:", argv[0]); + return 0; +} -- cgit v1.2.3-70-g09d2