From 3593da9e81dfa63c779fb14253b6b090a56d49c2 Mon Sep 17 00:00:00 2001 From: Maxim Konovalov Date: Wed, 31 May 2006 13:15:29 +0000 Subject: [PATCH] o According to POSIX, the result of ftruncate(2) is unspecified for file types other than VREG, VDIR and shared memory objects. We already handle VREG, VLNK and VDIR cases. Silently ignore truncate requests for all the rest. Adjust comments. PR: kern/98064 Submitted by: bde Security: local DoS Regress. test: regression/fifo/fifo_misc MFC after: 2 weeks --- sys/ufs/ufs/ufs_vnops.c | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/sys/ufs/ufs/ufs_vnops.c b/sys/ufs/ufs/ufs_vnops.c index a76d6bab02e..ffd295c62cd 100644 --- a/sys/ufs/ufs/ufs_vnops.c +++ b/sys/ufs/ufs/ufs_vnops.c @@ -509,22 +509,40 @@ ufs_setattr(ap) } if (vap->va_size != VNOVAL) { /* - * Disallow write attempts on read-only filesystems; - * unless the file is a socket, fifo, or a block or - * character device resident on the filesystem. + * XXX most of this checking should be in callers instead + * of in N filesystems. The VDIR check mostly already is. */ switch (vp->v_type) { case VDIR: return (EISDIR); case VLNK: case VREG: + /* + * Truncation should have an effect in these cases. + * Disallow it if the filesystem is read-only or + * the file is being snapshotted. + * + * XXX unfortunately the snapshot check can't be + * more global since we want to check other things + * first so as to return better error codes. But + * we miss several cases (file flags and ownership + * changes at least) by not doing a central check. + */ if (vp->v_mount->mnt_flag & MNT_RDONLY) return (EROFS); if ((ip->i_flags & SF_SNAPSHOT) != 0) return (EPERM); break; default: - break; + /* + * According to POSIX, the result is unspecified + * for file types other than regular files, + * directories and shared memory objects. We + * don't support shared memory objects in the file + * system, and have dubious support for truncating + * symlinks. Just ignore the request in other cases. + */ + return (0); } if ((error = UFS_TRUNCATE(vp, vap->va_size, IO_NORMAL, cred, td)) != 0)