1
0
mirror of https://github.com/samba-team/samba.git synced 2025-01-07 17:18:11 +03:00

vfs_ceph_new: handle case of readlinkat with empty name string

Commit 53c9269b (vfs_ceph_new: use low-level APIs for symlink/readlink)
introduced readlinkat using libcephfs low-level APIs. However, it does
not handle properly the case where readlinkat operates on empty name
string (see man readlinkat(2)), such as:

  fd = openat(dirfd, symname, O_PATH | O_NOFOLLOW, 0);
  readlinkat(fd, "", buf, bufsiz);

Handle this special case of readlinkat with empty name string by using
a reference to the symlink inode itself.

BUG: https://bugzilla.samba.org/show_bug.cgi?id=15686

Signed-off-by: Shachar Sharon <ssharon@redhat.com>
Reviewed-by: Anoop C S <anoopcs@samba.org>
Reviewed-by: Guenther Deschner <gd@samba.org>

Autobuild-User(master): Anoop C S <anoopcs@samba.org>
Autobuild-Date(master): Fri Aug 30 10:42:27 UTC 2024 on atb-devel-224

(cherry picked from commit 22182f90e8)

Autobuild-User(v4-21-test): Jule Anger <janger@samba.org>
Autobuild-Date(v4-21-test): Mon Sep  2 10:01:41 UTC 2024 on atb-devel-224
This commit is contained in:
Shachar Sharon 2024-08-20 12:45:07 +03:00 committed by Jule Anger
parent 06cf7b7b6f
commit 6071ea8333

View File

@ -2455,7 +2455,6 @@ static int vfs_ceph_readlinkat(struct vfs_handle_struct *handle,
size_t bufsiz)
{
int result = -1;
struct vfs_ceph_iref iref = {0};
struct vfs_ceph_fh *dircfh = NULL;
DBG_DEBUG("[CEPH] readlinkat(%p, %s, %p, %llu)\n",
@ -2468,17 +2467,29 @@ static int vfs_ceph_readlinkat(struct vfs_handle_struct *handle,
if (result != 0) {
goto out;
}
result = vfs_ceph_ll_lookupat(handle,
dircfh,
smb_fname->base_name,
&iref);
if (result != 0) {
goto out;
if (strcmp(smb_fname->base_name, "") != 0) {
struct vfs_ceph_iref iref = {0};
result = vfs_ceph_ll_lookupat(handle,
dircfh,
smb_fname->base_name,
&iref);
if (result != 0) {
goto out;
}
result = vfs_ceph_ll_readlinkat(handle,
dircfh,
&iref,
buf,
bufsiz);
vfs_ceph_iput(handle, &iref);
} else {
result = vfs_ceph_ll_readlinkat(handle,
dircfh,
&dircfh->iref,
buf,
bufsiz);
}
result = vfs_ceph_ll_readlinkat(handle, dircfh, &iref, buf, bufsiz);
vfs_ceph_iput(handle, &iref);
out:
DBG_DEBUG("[CEPH] readlinkat(...) = %d\n", result);
return status_code(result);