]>
git.proxmox.com Git - mirror_lxcfs.git/blob - tests/test_syscalls.c
1 /* SPDX-License-Identifier: LGPL-2.1+ */
13 #include <sys/mount.h>
14 #include <sys/socket.h>
16 #include <sys/sysmacros.h>
17 #include <sys/types.h>
18 #include <sys/types.h>
20 #include <sys/xattr.h>
24 void test_open(const char *path
)
26 int fd
= open(path
, O_RDONLY
);
28 fprintf(stderr
, "leak at open of %s\n", path
);
31 if (errno
!= ENOENT
) {
32 fprintf(stderr
, "leak at open of %s: errno was %d\n", path
, errno
);
37 void test_stat(const char *path
)
40 if (stat(path
, &sb
) >= 0) {
41 fprintf(stderr
, "leak at stat of %s\n", path
);
44 if (errno
!= ENOENT
) {
45 fprintf(stderr
, "leak at stat of %s: errno was %d\n", path
, errno
);
50 void test_access(const char *path
)
52 if (access(path
, O_RDONLY
) >= 0) {
53 fprintf(stderr
, "leak at access of %s\n", path
);
56 if (errno
!= ENOENT
) {
57 fprintf(stderr
, "leak at access of %s: errno was %d\n", path
, errno
);
62 void test_bind(const char *path
)
65 struct sockaddr_un my_addr
;
67 sfd
= socket(AF_UNIX
, SOCK_STREAM
, 0);
70 fprintf(stderr
, "Failed to open a socket for bind test\n");
73 memset(&my_addr
, 0, sizeof(struct sockaddr_un
));
74 my_addr
.sun_family
= AF_UNIX
;
75 strncpy(my_addr
.sun_path
, path
,
76 sizeof(my_addr
.sun_path
) - 1);
77 if (bind(sfd
, (struct sockaddr
*) &my_addr
,
78 sizeof(struct sockaddr_un
)) != -1) {
79 fprintf(stderr
, "leak at bind of %s\n", path
);
82 if (errno
!= ENOENT
&& errno
!= ENOSYS
) {
83 fprintf(stderr
, "leak at bind of %s: errno was %s\n", path
, strerror(errno
));
89 void test_bindmount(const char *path
)
91 if (mount(path
, path
, "none", MS_BIND
, NULL
) == 0) {
92 fprintf(stderr
, "leak at bind mount of %s\n", path
);
97 void test_truncate(const char *path
)
99 if (truncate(path
, 0) == 0) {
100 fprintf(stderr
, "leak at truncate of %s\n", path
);
105 void test_chdir(const char *path
)
107 if (chdir(path
) == 0) {
108 fprintf(stderr
, "leak at chdir to %s\n", path
);
113 void test_rename(const char *path
)
115 char *d
= strdupa(path
), *tmpname
;
117 size_t len
= strlen(path
) + 30;
119 tmpname
= alloca(len
);
120 snprintf(tmpname
, len
, "%s/%d", d
, (int)getpid());
121 if (rename(path
, tmpname
) == 0 || errno
!= ENOENT
) {
122 fprintf(stderr
, "leak at rename of %s\n", path
);
127 void test_mkdir(const char *path
)
129 size_t len
= strlen(path
) + 30;
130 char *tmpname
= alloca(len
);
131 snprintf(tmpname
, len
, "%s/%d", path
, (int)getpid());
133 if (mkdir(path
, 0755) == 0) {
134 fprintf(stderr
, "leak at mkdir of %s\n", path
);
137 if (errno
!= ENOENT
) {
138 fprintf(stderr
, "leak at mkdir of %s, errno was %s\n", path
, strerror(errno
));
141 if (mkdir(tmpname
, 0755) == 0) {
142 fprintf(stderr
, "leak at mkdir of %s\n", tmpname
);
145 if (errno
!= ENOENT
) {
146 fprintf(stderr
, "leak at mkdir of %s, errno was %s\n", path
, strerror(errno
));
151 void test_rmdir(const char *path
)
153 size_t len
= strlen(path
) + 30;
154 char *tmpname
= alloca(len
);
155 snprintf(tmpname
, len
, "%s/%d", path
, (int)getpid());
157 if (rmdir(path
) == 0 || errno
!= ENOENT
) {
158 fprintf(stderr
, "leak at rmdir of %s\n", path
);
161 if (rmdir(tmpname
) == 0 || errno
!= ENOENT
) {
162 fprintf(stderr
, "leak at rmdir of %s\n", tmpname
);
167 void test_creat(const char *path
)
169 if (creat(path
, 0755) >= 0) {
170 fprintf(stderr
, "leak at creat of %s\n", path
);
173 if (errno
!= ENOENT
&& errno
!= ENOSYS
) {
174 fprintf(stderr
, "leak at creat of %s: errno was %s\n", path
, strerror(errno
));
179 void test_link(const char *path
)
181 char *d
= strdupa(path
), *tmpname
;
183 size_t len
= strlen(path
) + 30;
184 tmpname
= alloca(len
);
185 snprintf(tmpname
, len
, "%s/%d", d
, (int)getpid());
187 if (link(path
, tmpname
) == 0) {
188 fprintf(stderr
, "leak at link of %s\n", path
);
191 if (errno
!= ENOENT
&& errno
!= ENOSYS
) {
192 fprintf(stderr
, "leak at link of %s: errno was %s\n", path
, strerror(errno
));
196 if (link(tmpname
, path
) == 0) {
197 fprintf(stderr
, "leak at link (2) of %s\n", path
);
200 if (errno
!= ENOENT
&& errno
!= ENOSYS
) {
201 fprintf(stderr
, "leak at link (2) of %s: errno was %s\n", path
, strerror(errno
));
206 void test_unlink(const char *path
)
208 if (unlink(path
) == 0) {
209 fprintf(stderr
, "leak at unlink of %s\n", path
);
212 if (errno
!= ENOENT
&& errno
!= ENOSYS
) {
213 fprintf(stderr
, "leak at unlink of %s: errno was %s\n", path
, strerror(errno
));
218 void test_symlink(const char *path
)
220 char *d
= strdupa(path
), *tmpname
;
222 size_t len
= strlen(path
) + 30;
223 tmpname
= alloca(len
);
224 snprintf(tmpname
, len
, "%s/%d", d
, (int)getpid());
226 if (symlink(tmpname
, path
) == 0) {
227 fprintf(stderr
, "leak at symlink of %s\n", path
);
230 if (errno
!= ENOENT
&& errno
!= ENOSYS
) {
231 fprintf(stderr
, "leak at symlink of %s: errno was %s\n", path
, strerror(errno
));
234 if (symlink(path
, tmpname
) == 0) {
235 fprintf(stderr
, "leak at symlink (2) of %s\n", path
);
238 if (errno
!= ENOENT
&& errno
!= ENOSYS
) {
239 fprintf(stderr
, "leak at symlink (2) of %s: errno was %s\n", path
, strerror(errno
));
244 void test_readlink(const char *path
)
246 char *dest
= alloca(2 * strlen(path
));
248 if (readlink(path
, dest
, 2 * strlen(path
)) >= 0) {
249 fprintf(stderr
, "leak at readlink of %s\n", path
);
252 if (errno
!= ENOENT
&& errno
!= ENOSYS
) {
253 fprintf(stderr
, "leak at readlink of %s: errno was %s\n", path
, strerror(errno
));
258 void test_chmod(const char *path
)
260 if (chmod(path
, 0755) == 0) {
261 fprintf(stderr
, "leak at chmod of %s\n", path
);
264 if (errno
!= ENOENT
&& errno
!= ENOSYS
) {
265 fprintf(stderr
, "leak at chmod of %s: errno was %s\n", path
, strerror(errno
));
270 void test_chown(const char *path
)
272 if (chown(path
, 0, 0) == 0) {
273 fprintf(stderr
, "leak at chown of %s\n", path
);
276 if (errno
!= ENOENT
&& errno
!= ENOSYS
) {
277 fprintf(stderr
, "leak at chown of %s: errno was %s\n", path
, strerror(errno
));
282 void test_lchown(const char *path
)
284 if (lchown(path
, 0, 0) == 0) {
285 fprintf(stderr
, "leak at lchown of %s\n", path
);
288 if (errno
!= ENOENT
&& errno
!= ENOSYS
) {
289 fprintf(stderr
, "leak at lchown of %s: errno was %s\n", path
, strerror(errno
));
294 void test_mknod(const char *path
)
296 if (mknod(path
, 0755, makedev(0, 0)) == 0) {
297 fprintf(stderr
, "leak at mknod of %s\n", path
);
300 if (errno
!= ENOENT
&& errno
!= ENOSYS
) {
301 fprintf(stderr
, "leak at mknod of %s: errno was %s\n", path
, strerror(errno
));
306 void test_chroot(const char *path
)
308 if (chroot(path
) == 0) {
309 fprintf(stderr
, "leak at chroot of %s\n", path
);
312 if (errno
!= ENOENT
&& errno
!= ENOSYS
) {
313 fprintf(stderr
, "leak at chroot of %s: errno was %s\n", path
, strerror(errno
));
318 void test_xattrs(const char *path
)
321 * might consider doing all of:
332 if (getxattr(path
, "security.selinux", value
, 200) >= 0) {
333 fprintf(stderr
, "leak at getxattr of %s\n", path
);
336 if (errno
!= ENOENT
&& errno
!= ENOSYS
) {
337 fprintf(stderr
, "leak at getxattr of %s: errno was %s\n", path
, strerror(errno
));
342 void test_utimes(const char *path
)
344 struct utimbuf times
;
348 if (utime(path
, ×
) == 0) {
349 fprintf(stderr
, "leak at utime of %s\n", path
);
352 if (errno
!= ENOENT
&& errno
!= ENOSYS
) {
353 fprintf(stderr
, "leak at utime of %s: errno was %s\n", path
, strerror(errno
));
358 void test_openat(const char *path
)
360 char *d
= strdupa(path
), *f
, *tmpname
;
364 fd
= open(d
, O_RDONLY
);
366 fprintf(stderr
, "Error in openat test: could not open parent dir\n");
367 fprintf(stderr
, "(this is expected on the second run)\n");
370 fd2
= openat(fd
, f
, O_RDONLY
);
371 if (fd2
>= 0 || errno
!= ENOENT
) {
372 fprintf(stderr
, "leak at openat of %s\n", f
);
375 size_t len
= strlen(path
) + strlen("/cgroup.procs") + 1;
376 tmpname
= alloca(len
);
377 snprintf(tmpname
, len
, "%s/cgroup.procs", f
);
378 fd2
= openat(fd
, tmpname
, O_RDONLY
);
379 if (fd2
>= 0 || errno
!= ENOENT
) {
380 fprintf(stderr
, "leak at openat of %s\n", tmpname
);
386 int main(int argc
, char *argv
[])
391 if (geteuid() != 0) {
392 fprintf(stderr
, "Run me as root\n");
397 fprintf(stderr
, "Usage: %s [lxcfs_test_cgroup_path]\n", argv
[0]);
401 /* Try syscalls on the directory and on $directory/cgroup.procs */
402 len
= strlen(argv
[1]) + strlen("/cgroup.procs") + 1;
403 procspath
= alloca(len
);
404 snprintf(procspath
, len
, "%s/cgroup.procs", argv
[1]);
407 test_open(procspath
);
409 test_stat(procspath
);
410 test_access(argv
[1]);
411 test_access(procspath
);
414 test_bind(procspath
);
415 test_bindmount(argv
[1]);
416 test_bindmount(procspath
);
417 test_truncate(argv
[1]);
418 test_truncate(procspath
);
420 test_chdir(procspath
);
421 test_rename(argv
[1]);
422 test_rename(procspath
);
424 test_mkdir(procspath
);
426 test_rmdir(procspath
);
428 test_creat(procspath
);
430 test_link(procspath
);
431 test_unlink(argv
[1]);
432 test_unlink(procspath
);
433 test_symlink(argv
[1]);
434 test_symlink(procspath
);
435 test_readlink(argv
[1]);
436 test_readlink(procspath
);
438 test_chmod(procspath
);
440 test_chown(procspath
);
441 test_lchown(argv
[1]);
442 test_lchown(procspath
);
444 test_mknod(procspath
);
445 test_chroot(argv
[1]);
446 test_chroot(procspath
);
447 test_xattrs(argv
[1]);
448 test_xattrs(procspath
);
449 test_utimes(argv
[1]);
450 test_utimes(procspath
);
452 test_openat(argv
[1]);
453 // meh... linkat etc?
455 printf("All tests passed\n");