Report all fdescfs vnodes as VCHR for stat(2). Fake the unique

major/minor numbers of the devices.

Pretending that the vnodes are character devices prevents file tree
walkers from descending into the directories opened by current process.
Also, not doing stat on the filedescriptors prevents the recursive entry
into the VFS.

Requested by:	kientzle
Discussed with:	Jilles Tjoelker <jilles stack nl>
This commit is contained in:
Konstantin Belousov 2009-05-12 09:28:45 +00:00
parent ada3b6a9ea
commit 3fe65eb8fe

View file

@ -389,78 +389,34 @@ fdesc_getattr(ap)
{
struct vnode *vp = ap->a_vp;
struct vattr *vap = ap->a_vap;
struct thread *td = curthread;
struct file *fp;
struct stat stb;
u_int fd;
int error = 0;
vap->va_mode = S_IRUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH;
vap->va_fileid = VTOFDESC(vp)->fd_ix;
vap->va_uid = 0;
vap->va_gid = 0;
vap->va_blocksize = DEV_BSIZE;
vap->va_atime.tv_sec = boottime.tv_sec;
vap->va_atime.tv_nsec = 0;
vap->va_mtime = vap->va_atime;
vap->va_ctime = vap->va_mtime;
vap->va_gen = 0;
vap->va_flags = 0;
vap->va_bytes = 0;
vap->va_filerev = 0;
switch (VTOFDESC(vp)->fd_type) {
case Froot:
vap->va_mode = S_IRUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH;
vap->va_type = VDIR;
vap->va_nlink = 2;
vap->va_size = DEV_BSIZE;
vap->va_fileid = VTOFDESC(vp)->fd_ix;
vap->va_uid = 0;
vap->va_gid = 0;
vap->va_blocksize = DEV_BSIZE;
vap->va_atime.tv_sec = boottime.tv_sec;
vap->va_atime.tv_nsec = 0;
vap->va_mtime = vap->va_atime;
vap->va_ctime = vap->va_mtime;
vap->va_gen = 0;
vap->va_flags = 0;
vap->va_rdev = NODEV;
vap->va_bytes = 0;
vap->va_filerev = 0;
break;
case Fdesc:
fd = VTOFDESC(vp)->fd_fd;
if ((error = fget(td, fd, &fp)) != 0)
return (error);
bzero(&stb, sizeof(stb));
error = fo_stat(fp, &stb, td->td_ucred, td);
fdrop(fp, td);
if (error == 0) {
vap->va_type = IFTOVT(stb.st_mode);
vap->va_mode = stb.st_mode;
if (vap->va_type == VDIR)
vap->va_mode &= ~(S_IRUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH);
vap->va_nlink = 1;
vap->va_flags = 0;
vap->va_bytes = stb.st_blocks * stb.st_blksize;
vap->va_fileid = VTOFDESC(vp)->fd_ix;
vap->va_size = stb.st_size;
vap->va_blocksize = stb.st_blksize;
vap->va_rdev = stb.st_rdev;
/*
* If no time data is provided, use the current time.
*/
if (stb.st_atimespec.tv_sec == 0 &&
stb.st_atimespec.tv_nsec == 0)
nanotime(&stb.st_atimespec);
if (stb.st_ctimespec.tv_sec == 0 &&
stb.st_ctimespec.tv_nsec == 0)
nanotime(&stb.st_ctimespec);
if (stb.st_mtimespec.tv_sec == 0 &&
stb.st_mtimespec.tv_nsec == 0)
nanotime(&stb.st_mtimespec);
vap->va_atime = stb.st_atimespec;
vap->va_mtime = stb.st_mtimespec;
vap->va_ctime = stb.st_ctimespec;
vap->va_uid = stb.st_uid;
vap->va_gid = stb.st_gid;
vap->va_gen = 0;
vap->va_filerev = 0;
}
vap->va_type = VCHR;
vap->va_nlink = 1;
vap->va_size = 0;
vap->va_rdev = makedev(0, vap->va_fileid);
break;
default:
@ -468,9 +424,8 @@ fdesc_getattr(ap)
break;
}
if (error == 0)
vp->v_type = vap->va_type;
return (error);
vp->v_type = vap->va_type;
return (0);
}
static int