From: Jeremy Allison Date: Fri, 25 Jun 2021 02:11:38 +0000 (-0700) Subject: s3: smbd: In openat_pathref_fsp(), just check we're opening the same file type, not... X-Git-Tag: tevent-0.11.0~201 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a6df051dd5e8c63f2fdfdb20ee01169d2bdb97dd;p=thirdparty%2Fsamba.git s3: smbd: In openat_pathref_fsp(), just check we're opening the same file type, not dev and inode. As this is an internal open and we don't have any locks around, we don't have to mandate the dev and ino pair are the same (and in fact not doing so fixes bugs when this is called by VFS modules that like to play tricks with ino number on stream paths (fruit, and streams_xattr are the two that currently do this). There's no security advantage to checking that, as the fd_openat() ensures this is safe. As fd_openat() does an FSTAT on the handle, update the smb_fname stat info with the "correct" values from the handle. Signed-off-by: Jeremy Allison Reviewed-by: Ralph Boehme --- diff --git a/source3/smbd/files.c b/source3/smbd/files.c index e8f3d0fc52e..6180ff17eab 100644 --- a/source3/smbd/files.c +++ b/source3/smbd/files.c @@ -529,18 +529,32 @@ NTSTATUS openat_pathref_fsp(const struct files_struct *dirfsp, goto fail; } - if (!check_same_dev_ino(&smb_fname->st, &fsp->fsp_name->st)) { - DBG_DEBUG("file [%s] - dev/ino mismatch. " - "Old (dev=%ju, ino=%ju). " - "New (dev=%ju, ino=%ju).\n", + /* + * As this is an internal open and we don't have any + * locks around, we don't have to mandate the dev and ino + * pair are the same (and in fact not doing so fixes bugs + * when this is called by VFS modules that like to play tricks + * with ino number on stream paths (fruit, and streams_xattr + * are the two that currently do this). + * + * There's no security advantage to checking that, as the + * fd_openat() above ensures this is safe. + */ + if ((S_IFMT & smb_fname->st.st_ex_mode) != (S_IFMT & fsp->fsp_name->st.st_ex_mode)) { + DBG_DEBUG("file [%s] - S_IFMT mismatch. " + "old = 0%o, new = 0%o\n", smb_fname_str_dbg(smb_fname), - (uintmax_t)smb_fname->st.st_ex_dev, - (uintmax_t)smb_fname->st.st_ex_ino, - (uintmax_t)fsp->fsp_name->st.st_ex_dev, - (uintmax_t)fsp->fsp_name->st.st_ex_ino); + (unsigned int)(S_IFMT & smb_fname->st.st_ex_mode), + (unsigned int)(S_IFMT & fsp->fsp_name->st.st_ex_mode)); status = NT_STATUS_ACCESS_DENIED; goto fail; } + /* + * fd_openat() has done an FSTAT on the handle + * so update the smb_fname stat info with "truth". + * from the handle. + */ + smb_fname->st = fsp->fsp_name->st; fsp->file_id = vfs_file_id_from_sbuf(conn, &fsp->fsp_name->st);