Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * Author: Aleksa Sarai <cyphar@cyphar.com>
0004  * Copyright (C) 2018-2019 SUSE LLC.
0005  */
0006 
0007 #define _GNU_SOURCE
0008 #include <errno.h>
0009 #include <fcntl.h>
0010 #include <stdbool.h>
0011 #include <string.h>
0012 #include <syscall.h>
0013 #include <limits.h>
0014 
0015 #include "helpers.h"
0016 
0017 bool needs_openat2(const struct open_how *how)
0018 {
0019     return how->resolve != 0;
0020 }
0021 
0022 int raw_openat2(int dfd, const char *path, void *how, size_t size)
0023 {
0024     int ret = syscall(__NR_openat2, dfd, path, how, size);
0025     return ret >= 0 ? ret : -errno;
0026 }
0027 
0028 int sys_openat2(int dfd, const char *path, struct open_how *how)
0029 {
0030     return raw_openat2(dfd, path, how, sizeof(*how));
0031 }
0032 
0033 int sys_openat(int dfd, const char *path, struct open_how *how)
0034 {
0035     int ret = openat(dfd, path, how->flags, how->mode);
0036     return ret >= 0 ? ret : -errno;
0037 }
0038 
0039 int sys_renameat2(int olddirfd, const char *oldpath,
0040           int newdirfd, const char *newpath, unsigned int flags)
0041 {
0042     int ret = syscall(__NR_renameat2, olddirfd, oldpath,
0043                       newdirfd, newpath, flags);
0044     return ret >= 0 ? ret : -errno;
0045 }
0046 
0047 int touchat(int dfd, const char *path)
0048 {
0049     int fd = openat(dfd, path, O_CREAT, 0700);
0050     if (fd >= 0)
0051         close(fd);
0052     return fd;
0053 }
0054 
0055 char *fdreadlink(int fd)
0056 {
0057     char *target, *tmp;
0058 
0059     E_asprintf(&tmp, "/proc/self/fd/%d", fd);
0060 
0061     target = malloc(PATH_MAX);
0062     if (!target)
0063         ksft_exit_fail_msg("fdreadlink: malloc failed\n");
0064     memset(target, 0, PATH_MAX);
0065 
0066     E_readlink(tmp, target, PATH_MAX);
0067     free(tmp);
0068     return target;
0069 }
0070 
0071 bool fdequal(int fd, int dfd, const char *path)
0072 {
0073     char *fdpath, *dfdpath, *other;
0074     bool cmp;
0075 
0076     fdpath = fdreadlink(fd);
0077     dfdpath = fdreadlink(dfd);
0078 
0079     if (!path)
0080         E_asprintf(&other, "%s", dfdpath);
0081     else if (*path == '/')
0082         E_asprintf(&other, "%s", path);
0083     else
0084         E_asprintf(&other, "%s/%s", dfdpath, path);
0085 
0086     cmp = !strcmp(fdpath, other);
0087 
0088     free(fdpath);
0089     free(dfdpath);
0090     free(other);
0091     return cmp;
0092 }
0093 
0094 bool openat2_supported = false;
0095 
0096 void __attribute__((constructor)) init(void)
0097 {
0098     struct open_how how = {};
0099     int fd;
0100 
0101     BUILD_BUG_ON(sizeof(struct open_how) != OPEN_HOW_SIZE_VER0);
0102 
0103     /* Check openat2(2) support. */
0104     fd = sys_openat2(AT_FDCWD, ".", &how);
0105     openat2_supported = (fd >= 0);
0106 
0107     if (fd >= 0)
0108         close(fd);
0109 }