On Mon, Feb 22, 2016 at 06:31:00AM -0700, Todd C. Miller wrote: > On Sun, 21 Feb 2016 16:33:27 +0100, Stefan Kempf wrote: > > > Should we really mount the FS in that case? If the FS was of the > > "new" format, then short symlinks would store the destination path in the > > inode directly. I think we'd not be able to correctly follow these symlinks > > if we set fs_maxsymlinklen to 0 when encountering a negative value. > > I was concerned about old 4.2/4.3 filesystems having garbage in > that location. It's not really an issue since we'll never really > encounter such a file system that was not created by our own newfs > (which will zero it on the disk). > > Since fs_maxsymlinklen should be ignored for the old inode format > we could do something like this just to be safe.
Yeah, I think that's a good idea; updated diff below. natano Index: sys/mount.h =================================================================== RCS file: /cvs/src/sys/sys/mount.h,v retrieving revision 1.121 diff -u -p -r1.121 mount.h --- sys/mount.h 8 Sep 2014 01:47:06 -0000 1.121 +++ sys/mount.h 22 Feb 2016 14:53:23 -0000 @@ -355,7 +355,7 @@ struct mount { struct vnodelst mnt_vnodelist; /* list of vnodes this mount */ struct rwlock mnt_lock; /* mount structure lock */ int mnt_flag; /* flags */ - int mnt_maxsymlinklen; /* max size of short symlink */ + unsigned int mnt_maxsymlinklen; /* max size of short symlink */ struct statfs mnt_stat; /* cache of filesystem stats */ void *mnt_data; /* private data */ }; Index: ufs/ext2fs/ext2fs_readwrite.c =================================================================== RCS file: /cvs/src/sys/ufs/ext2fs/ext2fs_readwrite.c,v retrieving revision 1.37 diff -u -p -r1.37 ext2fs_readwrite.c --- ufs/ext2fs/ext2fs_readwrite.c 16 Feb 2016 17:56:12 -0000 1.37 +++ ufs/ext2fs/ext2fs_readwrite.c 22 Feb 2016 14:53:23 -0000 @@ -95,7 +95,7 @@ ext2_ind_read(struct vnode *vp, struct i panic("%s: mode", "ext2fs_read"); if (vp->v_type == VLNK) { - if ((int)ext2fs_size(ip) < vp->v_mount->mnt_maxsymlinklen || + if (ext2fs_size(ip) < vp->v_mount->mnt_maxsymlinklen || (vp->v_mount->mnt_maxsymlinklen == 0 && ip->i_e2fs_nblock == 0)) panic("%s: short symlink", "ext2fs_read"); Index: ufs/ext2fs/ext2fs_vnops.c =================================================================== RCS file: /cvs/src/sys/ufs/ext2fs/ext2fs_vnops.c,v retrieving revision 1.74 diff -u -p -r1.74 ext2fs_vnops.c --- ufs/ext2fs/ext2fs_vnops.c 16 Feb 2016 17:56:12 -0000 1.74 +++ ufs/ext2fs/ext2fs_vnops.c 22 Feb 2016 14:53:23 -0000 @@ -322,7 +322,7 @@ ext2fs_setattr(void *v) if (vap->va_mode != (mode_t)VNOVAL) { if (vp->v_mount->mnt_flag & MNT_RDONLY) return (EROFS); - error = ext2fs_chmod(vp, (int)vap->va_mode, cred, p); + error = ext2fs_chmod(vp, vap->va_mode, cred, p); } return (error); } Index: ufs/ffs/ffs_vfsops.c =================================================================== RCS file: /cvs/src/sys/ufs/ffs/ffs_vfsops.c,v retrieving revision 1.150 diff -u -p -r1.150 ffs_vfsops.c --- ufs/ffs/ffs_vfsops.c 12 Jan 2016 11:41:00 -0000 1.150 +++ ufs/ffs/ffs_vfsops.c 22 Feb 2016 14:53:23 -0000 @@ -642,6 +642,11 @@ ffs_validate(struct fs *fsp) if ((u_int)fsp->fs_frag > MAXFRAG || fragtbl[fsp->fs_frag] == NULL) return (0); /* Invalid number of fragments */ + if (fsp->fs_inodefmt == FS_42INODEFMT) + fsp->fs_maxsymlinklen = 0; + else if (fsp->fs_maxsymlinklen < 0) + return (0); /* Invalid max size of short symlink */ + return (1); /* Super block is okay */ } Index: ufs/ffs/ffs_vnops.c =================================================================== RCS file: /cvs/src/sys/ufs/ffs/ffs_vnops.c,v retrieving revision 1.82 diff -u -p -r1.82 ffs_vnops.c --- ufs/ffs/ffs_vnops.c 16 Feb 2016 17:56:12 -0000 1.82 +++ ufs/ffs/ffs_vnops.c 22 Feb 2016 14:53:23 -0000 @@ -207,7 +207,7 @@ ffs_read(void *v) panic("ffs_read: mode"); if (vp->v_type == VLNK) { - if ((int)DIP(ip, size) < vp->v_mount->mnt_maxsymlinklen || + if (DIP(ip, size) < vp->v_mount->mnt_maxsymlinklen || (vp->v_mount->mnt_maxsymlinklen == 0 && DIP(ip, blocks) == 0)) panic("ffs_read: short symlink");