git: c302f889e21f - main - nfsd: Limit parsing of layout errors to maxcnt bytes
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Mon, 13 Dec 2021 23:24:50 UTC
The branch main has been updated by rmacklem:
URL: https://cgit.FreeBSD.org/src/commit/?id=c302f889e21f73746a3b0917df5246e639df1481
commit c302f889e21f73746a3b0917df5246e639df1481
Author: Rick Macklem <rmacklem@FreeBSD.org>
AuthorDate: 2021-12-13 23:21:31 +0000
Commit: Rick Macklem <rmacklem@FreeBSD.org>
CommitDate: 2021-12-13 23:21:31 +0000
nfsd: Limit parsing of layout errors to maxcnt bytes
This patch decrements maxcnt by the appropriate
number of bytes during parsing and checks to see
if there is data remaining. If not, it just returns
from nfsrv_flexlayouterr() without further processing.
This prevents the tl pointer from running off the end
of the error data pointed at by layp, if there are
flaws in the data.
Reported by: rtm@lcs.mit.edu
Tested by: rtm@lcs.mit.edu
PR: 260293
MFC after: 2 weeks
---
sys/fs/nfsserver/nfs_nfsdstate.c | 13 ++++++++++++-
1 file changed, 12 insertions(+), 1 deletion(-)
diff --git a/sys/fs/nfsserver/nfs_nfsdstate.c b/sys/fs/nfsserver/nfs_nfsdstate.c
index 4cfac532f063..e7256345f11f 100644
--- a/sys/fs/nfsserver/nfs_nfsdstate.c
+++ b/sys/fs/nfsserver/nfs_nfsdstate.c
@@ -7001,14 +7001,25 @@ nfsrv_flexlayouterr(struct nfsrv_descript *nd, uint32_t *layp, int maxcnt,
char devid[NFSX_V4DEVICEID];
tl = layp;
- cnt = fxdr_unsigned(int, *tl++);
+ maxcnt -= NFSX_UNSIGNED;
+ if (maxcnt > 0)
+ cnt = fxdr_unsigned(int, *tl++);
+ else
+ cnt = 0;
NFSD_DEBUG(4, "flexlayouterr cnt=%d\n", cnt);
for (i = 0; i < cnt; i++) {
+ maxcnt -= NFSX_STATEID + 2 * NFSX_HYPER +
+ NFSX_UNSIGNED;
+ if (maxcnt <= 0)
+ break;
/* Skip offset, length and stateid for now. */
tl += (4 + NFSX_STATEID / NFSX_UNSIGNED);
errcnt = fxdr_unsigned(int, *tl++);
NFSD_DEBUG(4, "flexlayouterr errcnt=%d\n", errcnt);
for (j = 0; j < errcnt; j++) {
+ maxcnt -= NFSX_V4DEVICEID + 2 * NFSX_UNSIGNED;
+ if (maxcnt < 0)
+ break;
NFSBCOPY(tl, devid, NFSX_V4DEVICEID);
tl += (NFSX_V4DEVICEID / NFSX_UNSIGNED);
stat = fxdr_unsigned(int, *tl++);