From: Anoop C S Date: Fri, 20 Sep 2024 08:49:01 +0000 (+0530) Subject: client: Gracefully handle empty pathname for chownat() X-Git-Tag: testing/wip-jcollin-testing-20251001.014437-squid~14^2~2 X-Git-Url: http://git.apps.os.sepia.ceph.com/?a=commitdiff_plain;h=098403c50dffc98d6b52ff6e8a7f2576944b449d;p=ceph-ci.git client: Gracefully handle empty pathname for chownat() man fchownat(2)[1] says the following: . . . AT_EMPTY_PATH (since Linux 2.6.39) If pathname is an empty string, operate on the file referred to by dirfd (which may have been obtained using the open(2) O_PATH flag). In this case, dirfd can refer to any type of file, not just a directory. If dirfd is AT_FDCWD, the call operates on the current working directory. . . . Look out for an empty pathname and use the relative fd's inode in the presence of AT_EMPTY_PATH flag before calling internal _setattr(). Fixes: https://tracker.ceph.com/issues/68189 Review with: git show -w [1] https://www.man7.org/linux/man-pages/man2/fchownat.2.html Signed-off-by: Anoop C S (cherry picked from commit 829f38899226fcd1f603ba446b018f53c5b0921d) Conflicts: src/client/Client.cc - path_walk() refactor from https://github.com/ceph/ceph/pull/62095 included the required core changes. --- diff --git a/src/include/cephfs/libcephfs.h b/src/include/cephfs/libcephfs.h index 3c1c12fd97a..fc0e2f3c9bc 100644 --- a/src/include/cephfs/libcephfs.h +++ b/src/include/cephfs/libcephfs.h @@ -1180,7 +1180,7 @@ int ceph_lchown(struct ceph_mount_info *cmount, const char *path, int uid, int g * @param relpath the relpath of the file/directory to change the ownership of. * @param uid the user id to set on the file/directory. * @param gid the group id to set on the file/directory. - * @param flags bitfield that can be used to set AT_* modifier flags (AT_SYMLINK_NOFOLLOW) + * @param flags bitfield that can be used to set AT_* modifier flags (AT_SYMLINK_NOFOLLOW and AT_EMPTY_PATH) * @returns 0 on success or negative error code on failure. */ int ceph_chownat(struct ceph_mount_info *cmount, int dirfd, const char *relpath, diff --git a/src/test/libcephfs/test.cc b/src/test/libcephfs/test.cc index 946698f986e..cb684d338ce 100644 --- a/src/test/libcephfs/test.cc +++ b/src/test/libcephfs/test.cc @@ -3490,6 +3490,13 @@ TEST(LibCephFS, Chownat) { // change ownership to nobody -- we assume nobody exists and id is always 65534 ASSERT_EQ(ceph_conf_set(cmount, "client_permissions", "0"), 0); ASSERT_EQ(ceph_chownat(cmount, fd, rel_file_path, 65534, 65534, 0), 0); + // change relative fd ownership with AT_EMPTY_PATH +#if defined(__linux__) && defined(AT_EMPTY_PATH) + int file_fd = ceph_openat(cmount, fd, rel_file_path, O_RDONLY, 0); + ASSERT_LE(0, file_fd); + ASSERT_EQ(ceph_chownat(cmount, file_fd, "", 65534, 65534, AT_EMPTY_PATH), 0); + ceph_close(cmount, file_fd); +#endif ASSERT_EQ(ceph_conf_set(cmount, "client_permissions", "1"), 0); ceph_close(cmount, fd);