nfs_clsubs.c: Fix ncl_getcookie() when "pos" is negative

In ncl_getcookie(), a very large value for "off" for
a directory can result in "pos" being set to a bogus
value (including a negative one), due to truncation.
When "pos" is negative, is can skip past the
while (pos >= NFSNUMCOOKIES) loop and return a
bogus pointer instead of NULL.

This patch changes the type to u_int and also adds
a sanity check for a very large "off" to ensure that
a NULL pointer is returned for this case.

This bug has been in the code for decades and I am
not aware of any report of it causing a problem for
users.

Reviewed by:	markj
Reported by:	Joshua Rogers of AISLE Research Team
MFC after:	2 weeks
Differential Revision:	https://reviews.freebsd.org/D56779
This commit is contained in:
Rick Macklem
2026-05-06 07:54:55 -07:00
parent e3e5b86e3b
commit 448b4c3f7f
2 changed files with 10 additions and 2 deletions
+9 -1
View File
@@ -263,9 +263,17 @@ nfsuint64 *
ncl_getcookie(struct nfsnode *np, off_t off, int add)
{
struct nfsdmap *dp, *dp2;
int pos;
u_int pos;
nfsuint64 *retval = NULL;
/*
* Limiting "off" to 50Gbytes sets a limit of 100 million directory
* entries of maximum filename length. Much more with shorter
* file names. This limit ensures "pos" will not be truncated
* in the devision below.
*/
if (off > 53687091200ull)
goto out;
pos = (uoff_t)off / NFS_DIRBLKSIZ;
if (pos == 0 || off < 0) {
KASSERT(!add, ("nfs getcookie add at <= 0"));
+1 -1
View File
@@ -61,7 +61,7 @@ struct sillyrename {
struct nfsdmap {
LIST_ENTRY(nfsdmap) ndm_list;
int ndm_eocookie;
u_int ndm_eocookie;
union {
nfsuint64 ndmu3_cookies[NFSNUMCOOKIES];
uint64_t ndmu4_cookies[NFSNUMCOOKIES];