"stat open" lseek(fd = -1)
Jeremy Allison
jra at samba.org
Fri Mar 1 21:36:49 UTC 2019
On Wed, Feb 27, 2019 at 04:52:28PM +0100, David Disseldorp via samba-technical wrote:
> Hi Samba archaeologists,
>
> Explicit "stat open" tracking was removed way back in 2002 with
> b9e91d2a8e41a43d7ebb7d7eed807a7d8de9b329. This change instead added a
> "fd == -1" check to the vfs_default lseek handler, which has remained to
> this day.
> Does anybody know whether this lseek(fd = -1) condition can still /
> could ever be triggered? If so, how?
Looking at current code in master, we have:
static off_t vfswrap_lseek(vfs_handle_struct *handle, files_struct *fsp, off_t offset, int whence)
{
off_t result = 0;
START_PROFILE(syscall_lseek);
/* Cope with 'stat' file opens. */
if (fsp->fh->fd != -1)
result = lseek(fsp->fh->fd, offset, whence);
/*
* We want to maintain the fiction that we can seek
* on a fifo for file system purposes. This allows
* people to set up UNIX fifo's that feed data to Windows
* applications. JRA.
*/
if((result == -1) && (errno == ESPIPE)) {
result = 0;
errno = 0;
}
END_PROFILE(syscall_lseek);
return result;
}
fsp->fh->fd == -1 can certainly happen - inside source3/smbd/open.c
we have:
1378 fsp->fh->fd = -1; /* What we used to call a stat open. */
1379 if (!file_existed) {
1380 /* File must exist for a stat open. */
1381 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1382 }
which occurs on SMB2_CREATE with an access mask of FILE_READ_ATTRIBUTES
only.
So the only question is SMB_VFS_LSEEK still used as we now use pread
for everything (or we should).
$ git grep SMB_VFS_LSEEK gives:
docs-xml/Samba-Developers-Guide/vfs.xml:#define SMB_VFS_LSEEK(fsp, fd, offset, whence) \
source3/include/vfs_macros.h:#define SMB_VFS_LSEEK(fsp, offset, whence) \
source3/smbd/reply.c: if((res = SMB_VFS_LSEEK(fsp,startpos,umode)) == -1) {
source3/smbd/reply.c: res = SMB_VFS_LSEEK(fsp,0,SEEK_SET);
source3/smbd/reply.c: ret = SMB_VFS_LSEEK(fsp2, 0, SEEK_END);
source3/smbd/smb2_ioctl_filesys.c: data_off = SMB_VFS_LSEEK(fsp, curr_off, SEEK_DATA);
source3/smbd/smb2_ioctl_filesys.c: hole_off = SMB_VFS_LSEEK(fsp, data_off, SEEK_HOLE);
source3/torture/cmd_vfs.c: pos = SMB_VFS_LSEEK(vfs->files[fd], offset, whence);
The calls inside smb2_ioctl_filesys.c are protected
by:
/* READ_DATA permission is required */
status = check_access_fsp(fsp, FILE_READ_DATA);
so they should be OK.
source3/torture/cmd_vfs.c is merely a test.
The calls in reply.c come from:
1). reply_lseek(), which doesn't check access permissions (so might
be called on a stat open).
2). reply_copy(), which opens src and dest as real, not stat
files.
So I think SMB1 with an SMBlseek call is the only possible
caller here.
Does that help ?
More information about the samba-technical
mailing list