diff options
| author | Alfred Perlstein <alfred@FreeBSD.org> | 1999-09-16 02:02:16 +0000 |
|---|---|---|
| committer | Alfred Perlstein <alfred@FreeBSD.org> | 1999-09-16 02:02:16 +0000 |
| commit | 0df360701eb64ee65574101f6c7f99990bf114dc (patch) | |
| tree | 46fd957528d194f601524b104030134334b4e8c9 /sys | |
| parent | ecb11b29b4a2b9b494b666faf327fd1c81553bae (diff) | |
Notes
Diffstat (limited to 'sys')
| -rw-r--r-- | sys/kern/vfs_cache.c | 10 | ||||
| -rw-r--r-- | sys/kern/vfs_subr.c | 1 | ||||
| -rw-r--r-- | sys/sys/vnode.h | 3 |
3 files changed, 13 insertions, 1 deletions
diff --git a/sys/kern/vfs_cache.c b/sys/kern/vfs_cache.c index 7c7afa3bd0fa..a4b362895abc 100644 --- a/sys/kern/vfs_cache.c +++ b/sys/kern/vfs_cache.c @@ -105,6 +105,12 @@ static u_long numposhits; STATNODE(CTLFLAG_RD, numposhits, &numposhits); static u_long numnegzaps; STATNODE(CTLFLAG_RD, numnegzaps, &numnegzaps); static u_long numneghits; STATNODE(CTLFLAG_RD, numneghits, &numneghits); +/* + * Max aliases to a name, avoids DoS of the system via hardlinks + */ +static int ncmaxaliases = 4; +SYSCTL_INT(_vfs_cache, OID_AUTO, maxaliases, CTLFLAG_RW, &ncmaxaliases, 4, + "Maximum amount of cache entries that can point to a particular file"); static void cache_zap __P((struct namecache *ncp)); @@ -126,6 +132,7 @@ cache_zap(ncp) vdrop(ncp->nc_dvp); if (ncp->nc_vp) { TAILQ_REMOVE(&ncp->nc_vp->v_cache_dst, ncp, nc_dst); + ncp->nc_vp->v_cache_dst_count--; } else { TAILQ_REMOVE(&ncneg, ncp, nc_dst); numneg--; @@ -296,6 +303,9 @@ cache_enter(dvp, vp, cnp) vhold(dvp); LIST_INSERT_HEAD(&dvp->v_cache_src, ncp, nc_src); if (vp) { + while (vp->v_cache_dst_count > ncmaxaliases) + cache_zap(TAILQ_LAST(&vp->v_cache_dst, cdst)); + vp->v_cache_dst_count++; TAILQ_INSERT_HEAD(&vp->v_cache_dst, ncp, nc_dst); } else { TAILQ_INSERT_TAIL(&ncneg, ncp, nc_dst); diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c index 90f3f6ff4ea9..c7375a2b0979 100644 --- a/sys/kern/vfs_subr.c +++ b/sys/kern/vfs_subr.c @@ -487,6 +487,7 @@ getnewvnode(tag, mp, vops, vpp) vp->v_socket = 0; vp->v_writecount = 0; /* XXX */ vp->v_maxio = 0; + vp->v_cache_dst_count = 0; } else { simple_unlock(&vnode_free_list_slock); vp = (struct vnode *) zalloc(vnode_zone); diff --git a/sys/sys/vnode.h b/sys/sys/vnode.h index e89a871b3561..dd0f51450ca0 100644 --- a/sys/sys/vnode.h +++ b/sys/sys/vnode.h @@ -116,7 +116,8 @@ struct vnode { enum vtagtype v_tag; /* type of underlying data */ void *v_data; /* private data for fs */ LIST_HEAD(, namecache) v_cache_src; /* Cache entries from us */ - TAILQ_HEAD(, namecache) v_cache_dst; /* Cache entries to us */ + TAILQ_HEAD(cdst, namecache) v_cache_dst; /* Cache entries to us */ + int v_cache_dst_count; /* number of cache entries pointing to us */ struct vnode *v_dd; /* .. vnode */ u_long v_ddid; /* .. capability identifier */ struct { |
