Module Name: src Committed By: dholland Date: Sun Jun 16 00:13:58 UTC 2013
Modified Files: src/sys/ufs/ufs: ufs_vnops.c Log Message: Add a comment about a matched pair of off-by-one tests that make the maximum size of short symlinks one byte less than one would think it should be. Caution against changing it; that would break compatibility with existing disk images. Behavior noticed by qjsgkem on freenode. If my analysis is wrong, please correct... To generate a diff of this commit: cvs rdiff -u -r1.215 -r1.216 src/sys/ufs/ufs/ufs_vnops.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/ufs/ufs/ufs_vnops.c diff -u src/sys/ufs/ufs/ufs_vnops.c:1.215 src/sys/ufs/ufs/ufs_vnops.c:1.216 --- src/sys/ufs/ufs/ufs_vnops.c:1.215 Sun Jun 9 18:54:05 2013 +++ src/sys/ufs/ufs/ufs_vnops.c Sun Jun 16 00:13:58 2013 @@ -1,4 +1,4 @@ -/* $NetBSD: ufs_vnops.c,v 1.215 2013/06/09 18:54:05 christos Exp $ */ +/* $NetBSD: ufs_vnops.c,v 1.216 2013/06/16 00:13:58 dholland Exp $ */ /*- * Copyright (c) 2008 The NetBSD Foundation, Inc. @@ -66,7 +66,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ufs_vnops.c,v 1.215 2013/06/09 18:54:05 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ufs_vnops.c,v 1.216 2013/06/16 00:13:58 dholland Exp $"); #if defined(_KERNEL_OPT) #include "opt_ffs.h" @@ -1267,6 +1267,13 @@ ufs_symlink(void *v) vp = *vpp; len = strlen(ap->a_target); ip = VTOI(vp); + /* + * This test is off by one. um_maxsymlinklen contains the + * number of bytes available, and we aren't storing a \0, so + * the test should properly be <=. However, it cannot be + * changed as this would break compatibility with existing fs + * images -- see the way ufs_readlink() works. + */ if (len < ip->i_ump->um_maxsymlinklen) { memcpy((char *)SHORTLINK(ip), ap->a_target, len); ip->i_size = len; @@ -1453,6 +1460,12 @@ ufs_readlink(void *v) struct ufsmount *ump = VFSTOUFS(vp->v_mount); int isize; + /* + * The test against um_maxsymlinklen is off by one; it should + * theoretically be <=, not <. However, it cannot be changed + * as that would break compatibility with existing fs images. + */ + isize = ip->i_size; if (isize < ump->um_maxsymlinklen || (ump->um_maxsymlinklen == 0 && DIP(ip, blocks) == 0)) {