1*a3322868SAlexey Dobriyan /*
2*a3322868SAlexey Dobriyan * Copyright (c) 2019 Alexey Dobriyan <adobriyan@gmail.com>
3*a3322868SAlexey Dobriyan *
4*a3322868SAlexey Dobriyan * Permission to use, copy, modify, and distribute this software for any
5*a3322868SAlexey Dobriyan * purpose with or without fee is hereby granted, provided that the above
6*a3322868SAlexey Dobriyan * copyright notice and this permission notice appear in all copies.
7*a3322868SAlexey Dobriyan *
8*a3322868SAlexey Dobriyan * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9*a3322868SAlexey Dobriyan * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10*a3322868SAlexey Dobriyan * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11*a3322868SAlexey Dobriyan * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12*a3322868SAlexey Dobriyan * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13*a3322868SAlexey Dobriyan * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14*a3322868SAlexey Dobriyan * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15*a3322868SAlexey Dobriyan */
16*a3322868SAlexey Dobriyan /* Test that open(O_TMPFILE), linkat() doesn't screw accounting. */
17*a3322868SAlexey Dobriyan #include <errno.h>
18*a3322868SAlexey Dobriyan #include <sched.h>
19*a3322868SAlexey Dobriyan #include <stdio.h>
20*a3322868SAlexey Dobriyan #include <sys/types.h>
21*a3322868SAlexey Dobriyan #include <sys/stat.h>
22*a3322868SAlexey Dobriyan #include <fcntl.h>
23*a3322868SAlexey Dobriyan #include <sys/mount.h>
24*a3322868SAlexey Dobriyan #include <unistd.h>
25*a3322868SAlexey Dobriyan
main(void)26*a3322868SAlexey Dobriyan int main(void)
27*a3322868SAlexey Dobriyan {
28*a3322868SAlexey Dobriyan int fd;
29*a3322868SAlexey Dobriyan
30*a3322868SAlexey Dobriyan if (unshare(CLONE_NEWNS) == -1) {
31*a3322868SAlexey Dobriyan if (errno == ENOSYS || errno == EPERM) {
32*a3322868SAlexey Dobriyan fprintf(stderr, "error: unshare, errno %d\n", errno);
33*a3322868SAlexey Dobriyan return 4;
34*a3322868SAlexey Dobriyan }
35*a3322868SAlexey Dobriyan fprintf(stderr, "error: unshare, errno %d\n", errno);
36*a3322868SAlexey Dobriyan return 1;
37*a3322868SAlexey Dobriyan }
38*a3322868SAlexey Dobriyan if (mount(NULL, "/", NULL, MS_PRIVATE|MS_REC, NULL) == -1) {
39*a3322868SAlexey Dobriyan fprintf(stderr, "error: mount '/', errno %d\n", errno);
40*a3322868SAlexey Dobriyan return 1;
41*a3322868SAlexey Dobriyan }
42*a3322868SAlexey Dobriyan
43*a3322868SAlexey Dobriyan /* Our heroes: 1 root inode, 1 O_TMPFILE inode, 1 permanent inode. */
44*a3322868SAlexey Dobriyan if (mount(NULL, "/tmp", "tmpfs", 0, "nr_inodes=3") == -1) {
45*a3322868SAlexey Dobriyan fprintf(stderr, "error: mount tmpfs, errno %d\n", errno);
46*a3322868SAlexey Dobriyan return 1;
47*a3322868SAlexey Dobriyan }
48*a3322868SAlexey Dobriyan
49*a3322868SAlexey Dobriyan fd = openat(AT_FDCWD, "/tmp", O_WRONLY|O_TMPFILE, 0600);
50*a3322868SAlexey Dobriyan if (fd == -1) {
51*a3322868SAlexey Dobriyan fprintf(stderr, "error: open 1, errno %d\n", errno);
52*a3322868SAlexey Dobriyan return 1;
53*a3322868SAlexey Dobriyan }
54*a3322868SAlexey Dobriyan if (linkat(fd, "", AT_FDCWD, "/tmp/1", AT_EMPTY_PATH) == -1) {
55*a3322868SAlexey Dobriyan fprintf(stderr, "error: linkat, errno %d\n", errno);
56*a3322868SAlexey Dobriyan return 1;
57*a3322868SAlexey Dobriyan }
58*a3322868SAlexey Dobriyan close(fd);
59*a3322868SAlexey Dobriyan
60*a3322868SAlexey Dobriyan fd = openat(AT_FDCWD, "/tmp", O_WRONLY|O_TMPFILE, 0600);
61*a3322868SAlexey Dobriyan if (fd == -1) {
62*a3322868SAlexey Dobriyan fprintf(stderr, "error: open 2, errno %d\n", errno);
63*a3322868SAlexey Dobriyan return 1;
64*a3322868SAlexey Dobriyan }
65*a3322868SAlexey Dobriyan
66*a3322868SAlexey Dobriyan return 0;
67*a3322868SAlexey Dobriyan }
68