brintos

brintos / linux-shallow public Read only

0
0
Text · 2.1 KiB · 5074681 Raw
110 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * Author: Aleksa Sarai <cyphar@cyphar.com>4 * Copyright (C) 2018-2019 SUSE LLC.5 */6 7#define _GNU_SOURCE8#include <errno.h>9#include <fcntl.h>10#include <stdbool.h>11#include <string.h>12#include <syscall.h>13#include <limits.h>14 15#include "helpers.h"16 17bool needs_openat2(const struct open_how *how)18{19	return how->resolve != 0;20}21 22int raw_openat2(int dfd, const char *path, void *how, size_t size)23{24	int ret = syscall(__NR_openat2, dfd, path, how, size);25	return ret >= 0 ? ret : -errno;26}27 28int sys_openat2(int dfd, const char *path, struct open_how *how)29{30	return raw_openat2(dfd, path, how, sizeof(*how));31}32 33int sys_openat(int dfd, const char *path, struct open_how *how)34{35	int ret = openat(dfd, path, how->flags, how->mode);36	return ret >= 0 ? ret : -errno;37}38 39int sys_renameat2(int olddirfd, const char *oldpath,40		  int newdirfd, const char *newpath, unsigned int flags)41{42	int ret = syscall(__NR_renameat2, olddirfd, oldpath,43					  newdirfd, newpath, flags);44	return ret >= 0 ? ret : -errno;45}46 47int touchat(int dfd, const char *path)48{49	int fd = openat(dfd, path, O_CREAT, 0700);50	if (fd >= 0)51		close(fd);52	return fd;53}54 55char *fdreadlink(int fd)56{57	char *target, *tmp;58 59	E_asprintf(&tmp, "/proc/self/fd/%d", fd);60 61	target = malloc(PATH_MAX);62	if (!target)63		ksft_exit_fail_msg("fdreadlink: malloc failed\n");64	memset(target, 0, PATH_MAX);65 66	E_readlink(tmp, target, PATH_MAX);67	free(tmp);68	return target;69}70 71bool fdequal(int fd, int dfd, const char *path)72{73	char *fdpath, *dfdpath, *other;74	bool cmp;75 76	fdpath = fdreadlink(fd);77	dfdpath = fdreadlink(dfd);78 79	if (!path)80		E_asprintf(&other, "%s", dfdpath);81	else if (*path == '/')82		E_asprintf(&other, "%s", path);83	else84		E_asprintf(&other, "%s/%s", dfdpath, path);85 86	cmp = !strcmp(fdpath, other);87 88	free(fdpath);89	free(dfdpath);90	free(other);91	return cmp;92}93 94bool openat2_supported = false;95 96void __attribute__((constructor)) init(void)97{98	struct open_how how = {};99	int fd;100 101	BUILD_BUG_ON(sizeof(struct open_how) != OPEN_HOW_SIZE_VER0);102 103	/* Check openat2(2) support. */104	fd = sys_openat2(AT_FDCWD, ".", &how);105	openat2_supported = (fd >= 0);106 107	if (fd >= 0)108		close(fd);109}110