Skip to content

Instantly share code, notes, and snippets.

@cynecx
Created November 22, 2020 20:34
Show Gist options
  • Select an option

  • Save cynecx/d49014672d558f82b3256e579b02d0da to your computer and use it in GitHub Desktop.

Select an option

Save cynecx/d49014672d558f82b3256e579b02d0da to your computer and use it in GitHub Desktop.
read procfs with fsopen/fsmount (without actually attaching the mount to the visible vfs)
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <cstdint>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <linux/unistd.h>
#include <linux/mount.h>
namespace {
inline int fsopen(const char *fs_name, unsigned int flags)
{
return syscall(__NR_fsopen, fs_name, flags);
}
inline int fsmount(int fsfd, unsigned int flags, unsigned int ms_flags)
{
return syscall(__NR_fsmount, fsfd, flags, ms_flags);
}
inline int fsconfig(int fsfd, unsigned int cmd,
const char *key, const void *val, int aux)
{
return syscall(__NR_fsconfig, fsfd, cmd, key, val, aux);
}
constexpr unsigned int MOUNT_FLAGS = MOUNT_ATTR_RDONLY
| MOUNT_ATTR_NODEV
| MOUNT_ATTR_NOSUID
| MOUNT_ATTR_NOEXEC
| MOUNT_ATTR_RELATIME;
}
int main() {
int ret = 0;
int pid = getpid();
printf("pid=%d\n", pid);
int fsfd = fsopen("proc", FSOPEN_CLOEXEC);
if (fsfd == -1) {
printf("fsopen=%d, errno=%d (%s)\n", fsfd, errno, strerror(errno));
return 1;
}
ret = fsconfig(fsfd, FSCONFIG_CMD_CREATE, NULL, NULL, 0);
if (ret == -1) {
printf("fsconfig=%d, errno=%d (%s)\n", fsfd, errno, strerror(errno));
close(fsfd);
return 1;
}
printf("fsfd=%d\n", fsfd);
int mfd = fsmount(fsfd, FSMOUNT_CLOEXEC, MOUNT_FLAGS);
if (mfd == -1) {
printf("fsmount=%d, errno=%d (%s)\n", mfd, errno, strerror(errno));
close(fsfd);
return 1;
}
close(fsfd);
printf("mfd=%d\n", mfd);
int verfd = openat(mfd, "version", O_RDONLY | O_CLOEXEC);
if (verfd == -1) {
printf("openat, errno=%d (%s)\n", errno, strerror(errno));
close(mfd);
return 1;
}
printf("verfd=%d\n", verfd);
uint8_t buf[255] {};
int r = read(verfd, buf, sizeof(buf));
if (r > 0) {
buf[sizeof(buf) - 1] = 0;
printf("%s\n", buf);
} else {
printf("read failed with %d errno=%d (%s)\n", r, errno, strerror(errno));
}
close(verfd);
close(mfd);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment