From 1f888fc4b3fd96766e2eaf87ee3bfd65340ff0d0 Mon Sep 17 00:00:00 2001 From: Charles Mirabile Date: Mon, 20 Nov 2023 05:31:33 -0500 Subject: [PATCH 1/4] test/hardlink: Cleanup error handling There is a lot of code duplication between the error exit labels that can be avoided by just always trying to unlink each path that might have been created. Signed-off-by: Charles Mirabile --- test/hardlink.c | 47 +++++++++++++++++------------------------------ 1 file changed, 17 insertions(+), 30 deletions(-) diff --git a/test/hardlink.c b/test/hardlink.c index 1b0ca4a0e..f565574bf 100644 --- a/test/hardlink.c +++ b/test/hardlink.c @@ -71,7 +71,7 @@ int main(int argc, char *argv[]) static const char linkname[] = "io_uring-linkat-test-link"; static const char symlinkname[] = "io_uring-linkat-test-symlink"; struct io_uring ring; - int ret; + int ret, exit_status = T_EXIT_FAIL; if (argc > 1) return T_EXIT_SKIP; @@ -85,78 +85,65 @@ int main(int argc, char *argv[]) ret = open(target, O_CREAT | O_RDWR | O_EXCL, 0600); if (ret < 0) { perror("open"); - goto err; + goto out; } if (write(ret, "linktest", 8) != 8) { close(ret); - goto err1; + goto out; } close(ret); ret = symlink(target, symlinkname); if (ret < 0) { perror("open"); - goto err1; + goto out; } ret = do_linkat(&ring, target, linkname, 0); if (ret < 0) { if (ret == -EBADF || ret == -EINVAL) { fprintf(stdout, "linkat not supported, skipping\n"); - goto skip; + exit_status = T_EXIT_SKIP; + goto out; } fprintf(stderr, "linkat: %s\n", strerror(-ret)); - goto err2; + goto out; } else if (ret) { - goto err2; + goto out; } if (!files_linked_ok(linkname, target)) - goto err3; + goto out; unlinkat(AT_FDCWD, linkname, 0); ret = do_linkat(&ring, symlinkname, linkname, AT_SYMLINK_FOLLOW); if (ret < 0) { fprintf(stderr, "linkat: %s\n", strerror(-ret)); - goto err2; + goto out; } else if (ret) { - goto err2; + goto out; } if (!files_linked_ok(symlinkname, target)) - goto err3; + goto out; ret = do_linkat(&ring, target, linkname, 0); if (ret != -EEXIST) { fprintf(stderr, "test_linkat linkname already exists failed: %d\n", ret); - goto err3; + goto out; } ret = do_linkat(&ring, target, "surely/this/does/not/exist", 0); if (ret != -ENOENT) { fprintf(stderr, "test_linkat no parent failed: %d\n", ret); - goto err3; + goto out; } - - unlinkat(AT_FDCWD, symlinkname, 0); - unlinkat(AT_FDCWD, linkname, 0); - unlinkat(AT_FDCWD, target, 0); - io_uring_queue_exit(&ring); - return T_EXIT_PASS; -skip: + exit_status = T_EXIT_PASS; +out: unlinkat(AT_FDCWD, symlinkname, 0); unlinkat(AT_FDCWD, linkname, 0); unlinkat(AT_FDCWD, target, 0); io_uring_queue_exit(&ring); - return T_EXIT_SKIP; -err3: - unlinkat(AT_FDCWD, linkname, 0); -err2: - unlinkat(AT_FDCWD, symlinkname, 0); -err1: - unlinkat(AT_FDCWD, target, 0); -err: - io_uring_queue_exit(&ring); - return T_EXIT_FAIL; + return exit_status; } From db74d3e0aa17f6af48c32ed8f585e073c3a32377 Mon Sep 17 00:00:00 2001 From: Charles Mirabile Date: Mon, 20 Nov 2023 05:33:32 -0500 Subject: [PATCH 2/4] test/hardlink: add parameter for old's dirfd to `do_linkat` In preparation for adding a test that uses `AT_EMPTY_PATH` and needs to use a value other than `AT_FDCWD` as the dirfd, introduce that paremeter and update existing callsites. Signed-off-by: Charles Mirabile --- test/hardlink.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/test/hardlink.c b/test/hardlink.c index f565574bf..0d755b328 100644 --- a/test/hardlink.c +++ b/test/hardlink.c @@ -12,7 +12,7 @@ #include "liburing.h" #include "helpers.h" -static int do_linkat(struct io_uring *ring, const char *oldname, +static int do_linkat(struct io_uring *ring, int olddirfd, const char *oldname, const char *newname, int flags) { struct io_uring_sqe *sqe; @@ -24,7 +24,7 @@ static int do_linkat(struct io_uring *ring, const char *oldname, fprintf(stderr, "sqe get failed\n"); return 1; } - io_uring_prep_linkat(sqe, AT_FDCWD, oldname, AT_FDCWD, newname, flags); + io_uring_prep_linkat(sqe, olddirfd, oldname, AT_FDCWD, newname, flags); ret = io_uring_submit(ring); if (ret != 1) { @@ -99,7 +99,7 @@ int main(int argc, char *argv[]) goto out; } - ret = do_linkat(&ring, target, linkname, 0); + ret = do_linkat(&ring, AT_FDCWD, target, linkname, 0); if (ret < 0) { if (ret == -EBADF || ret == -EINVAL) { fprintf(stdout, "linkat not supported, skipping\n"); @@ -117,7 +117,7 @@ int main(int argc, char *argv[]) unlinkat(AT_FDCWD, linkname, 0); - ret = do_linkat(&ring, symlinkname, linkname, AT_SYMLINK_FOLLOW); + ret = do_linkat(&ring, AT_FDCWD, symlinkname, linkname, AT_SYMLINK_FOLLOW); if (ret < 0) { fprintf(stderr, "linkat: %s\n", strerror(-ret)); goto out; @@ -128,13 +128,13 @@ int main(int argc, char *argv[]) if (!files_linked_ok(symlinkname, target)) goto out; - ret = do_linkat(&ring, target, linkname, 0); + ret = do_linkat(&ring, AT_FDCWD, target, linkname, 0); if (ret != -EEXIST) { fprintf(stderr, "test_linkat linkname already exists failed: %d\n", ret); goto out; } - ret = do_linkat(&ring, target, "surely/this/does/not/exist", 0); + ret = do_linkat(&ring, AT_FDCWD, target, "surely/this/does/not/exist", 0); if (ret != -ENOENT) { fprintf(stderr, "test_linkat no parent failed: %d\n", ret); goto out; From 37ad6a572ae6e59678bddcaf84161b989def9e1c Mon Sep 17 00:00:00 2001 From: Charles Mirabile Date: Mon, 20 Nov 2023 05:35:51 -0500 Subject: [PATCH 3/4] test/hardlink: introduce `fd` variable to hold the file open file descriptor In preparation for adding a test that uses `AT_EMPTY_PATH` and will want a reference to an existing open file descriptor refering to some file, introduce a new variable to hold the return value of `open` so that `ret` can be modified by the test without losing the number of the file descriptor so it can be closed. Signed-off-by: Charles Mirabile --- test/hardlink.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/test/hardlink.c b/test/hardlink.c index 0d755b328..9e09c6cec 100644 --- a/test/hardlink.c +++ b/test/hardlink.c @@ -71,7 +71,7 @@ int main(int argc, char *argv[]) static const char linkname[] = "io_uring-linkat-test-link"; static const char symlinkname[] = "io_uring-linkat-test-symlink"; struct io_uring ring; - int ret, exit_status = T_EXIT_FAIL; + int ret, fd, exit_status = T_EXIT_FAIL; if (argc > 1) return T_EXIT_SKIP; @@ -82,16 +82,16 @@ int main(int argc, char *argv[]) return ret; } - ret = open(target, O_CREAT | O_RDWR | O_EXCL, 0600); + ret = fd = open(target, O_CREAT | O_RDWR | O_EXCL, 0600); if (ret < 0) { perror("open"); goto out; } - if (write(ret, "linktest", 8) != 8) { - close(ret); + if (write(fd, "linktest", 8) != 8) { + close(fd); goto out; } - close(ret); + close(fd); ret = symlink(target, symlinkname); if (ret < 0) { From f0fe0515ca3c162fac545528ffddc45398d7d181 Mon Sep 17 00:00:00 2001 From: Charles Mirabile Date: Mon, 20 Nov 2023 05:38:35 -0500 Subject: [PATCH 4/4] test/hardlink: Add test for `AT_EMPTY_PATH` flag The `AT_EMPTY_PATH` flag requires the `DAC_READ_SEARCH` capability so this test is skipped when non root. Signed-off-by: Charles Mirabile --- test/hardlink.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/test/hardlink.c b/test/hardlink.c index 9e09c6cec..cf170d025 100644 --- a/test/hardlink.c +++ b/test/hardlink.c @@ -68,6 +68,7 @@ static int files_linked_ok(const char* fn1, const char *fn2) int main(int argc, char *argv[]) { static const char target[] = "io_uring-linkat-test-target"; + static const char emptyname[] = "io_uring-linkat-test-empty"; static const char linkname[] = "io_uring-linkat-test-link"; static const char symlinkname[] = "io_uring-linkat-test-symlink"; struct io_uring ring; @@ -91,6 +92,25 @@ int main(int argc, char *argv[]) close(fd); goto out; } + if(geteuid()) { + fprintf(stdout, "not root, skipping AT_EMPTY_PATH test\n"); + } else { + ret = do_linkat(&ring, fd, "", emptyname, AT_EMPTY_PATH); + if (ret < 0) { + if (ret == -EBADF || ret == -EINVAL) { + fprintf(stdout, "linkat not supported, skipping\n"); + exit_status = T_EXIT_SKIP; + goto out; + } + fprintf(stderr, "linkat: %s\n", strerror(-ret)); + goto out; + } else if (ret) { + goto out; + } + if (!files_linked_ok(emptyname, target)) + goto out; + unlinkat(AT_FDCWD, emptyname, 0); + } close(fd); ret = symlink(target, symlinkname); @@ -143,6 +163,7 @@ int main(int argc, char *argv[]) out: unlinkat(AT_FDCWD, symlinkname, 0); unlinkat(AT_FDCWD, linkname, 0); + unlinkat(AT_FDCWD, emptyname, 0); unlinkat(AT_FDCWD, target, 0); io_uring_queue_exit(&ring); return exit_status;