diff --git a/tests/.gitignore b/tests/.gitignore index 9da79900..1982cd68 100644 --- a/tests/.gitignore +++ b/tests/.gitignore @@ -8,3 +8,4 @@ src/bulk_create_paths src/find_xattrs src/stage_tmpfile src/create_xattr_loop +src/o_tmpfile_umask diff --git a/tests/Makefile b/tests/Makefile index fcc43df1..9de59268 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -11,7 +11,8 @@ BIN := src/createmany \ src/stage_tmpfile \ src/find_xattrs \ src/create_xattr_loop \ - src/fragmented_data_extents + src/fragmented_data_extents \ + src/o_tmpfile_umask DEPS := $(wildcard src/*.d) diff --git a/tests/golden/o_tmpfile b/tests/golden/o_tmpfile index a1d111f0..332bb36f 100644 --- a/tests/golden/o_tmpfile +++ b/tests/golden/o_tmpfile @@ -1,3 +1,10 @@ +== non-acl O_TMPFILE creation honors umask +umask 022 +fstat after open(0777): 0100755 +stat after linkat: 0100755 +umask 077 +fstat after open(0777): 0100700 +stat after linkat: 0100700 == stage from tmpfile total file size 33669120 00000000 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 |AAAAAAAAAAAAAAAA| diff --git a/tests/src/o_tmpfile_umask.c b/tests/src/o_tmpfile_umask.c new file mode 100644 index 00000000..4ac72c85 --- /dev/null +++ b/tests/src/o_tmpfile_umask.c @@ -0,0 +1,97 @@ +/* + * Show the modes of files as we create them with O_TMPFILE and link + * them into the namespace. + * + * Copyright (C) 2022 Versity Software, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License v2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static void linkat_tmpfile_modes(char *dir, char *lpath, mode_t mode) +{ + char proc_self[PATH_MAX]; + struct stat st; + int ret; + int fd; + + umask(mode); + printf("umask 0%o\n", mode); + + fd = open(dir, O_RDWR | O_TMPFILE, 0777); + if (fd < 0) { + perror("open(O_TMPFILE)"); + exit(1); + } + + ret = fstat(fd, &st); + if (ret < 0) { + perror("fstat"); + exit(1); + } + + printf("fstat after open(0777): 0%o\n", st.st_mode); + + snprintf(proc_self, sizeof(proc_self), "/proc/self/fd/%d", fd); + + ret = linkat(AT_FDCWD, proc_self, AT_FDCWD, lpath, AT_SYMLINK_FOLLOW); + if (ret < 0) { + perror("linkat"); + exit(1); + } + + close(fd); + + ret = stat(lpath, &st); + if (ret < 0) { + perror("fstat"); + exit(1); + } + + printf("stat after linkat: 0%o\n", st.st_mode); + + ret = unlink(lpath); + if (ret < 0) { + perror("unlink"); + exit(1); + } +} + +int main(int argc, char **argv) +{ + char *lpath; + char *dir; + + if (argc < 3) { + printf("%s \n", argv[0]); + return 1; + } + + dir = argv[1]; + lpath = argv[2]; + + linkat_tmpfile_modes(dir, lpath, 022); + linkat_tmpfile_modes(dir, lpath, 077); + + return 0; +} diff --git a/tests/tests/o_tmpfile.sh b/tests/tests/o_tmpfile.sh index 9de214ef..a157a969 100644 --- a/tests/tests/o_tmpfile.sh +++ b/tests/tests/o_tmpfile.sh @@ -4,6 +4,9 @@ t_require_commands stage_tmpfile hexdump +echo "== non-acl O_TMPFILE creation honors umask" +o_tmpfile_umask "$T_D0" "$T_D0/umask-file" + echo "== stage from tmpfile" DEST_FILE="$T_D0/dest_file" stage_tmpfile $T_D0 $DEST_FILE