From 69cc1d0d7f3445d3671e05dcb7baabe7e36c5ed9 Mon Sep 17 00:00:00 2001 From: "Andrey A. Chernov" Date: Thu, 23 Aug 2001 07:42:40 +0000 Subject: [PATCH] Detect off_t EOVERFLOW of start/end offsets calculations for adv. lock, as POSIX require. --- sys/kern/kern_descrip.c | 17 +++++++++++++++-- sys/kern/kern_lockf.c | 13 ++++++++++++- 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c index b72bf26e70b..78ac1a00d45 100644 --- a/sys/kern/kern_descrip.c +++ b/sys/kern/kern_descrip.c @@ -40,6 +40,7 @@ */ #include "opt_compat.h" +#include #include #include #include @@ -303,8 +304,14 @@ fcntl(p, uap) fdrop(fp, p); return (error); } - if (fl.l_whence == SEEK_CUR) + if (fl.l_whence == SEEK_CUR) { + if ((fl.l_start > 0 && + fp->f_offset > OFF_MAX - fl.l_start) || + (fl.l_start < 0 && + fp->f_offset < OFF_MIN - fl.l_start)) + return (EOVERFLOW); fl.l_start += fp->f_offset; + } switch (fl.l_type) { case F_RDLCK: @@ -356,8 +363,14 @@ fcntl(p, uap) fdrop(fp, p); return (EINVAL); } - if (fl.l_whence == SEEK_CUR) + if (fl.l_whence == SEEK_CUR) { + if ((fl.l_start > 0 && + fp->f_offset > OFF_MAX - fl.l_start) || + (fl.l_start < 0 && + fp->f_offset < OFF_MIN - fl.l_start)) + return (EOVERFLOW); fl.l_start += fp->f_offset; + } error = VOP_ADVLOCK(vp, (caddr_t)p->p_leader, F_GETLK, &fl, F_POSIX); fdrop(fp, p); diff --git a/sys/kern/kern_lockf.c b/sys/kern/kern_lockf.c index ad3cb70051d..b93b541a882 100644 --- a/sys/kern/kern_lockf.c +++ b/sys/kern/kern_lockf.c @@ -39,6 +39,7 @@ #include "opt_debug_lockf.h" +#include #include #include #include @@ -105,6 +106,8 @@ lf_advlock(ap, head, size) off_t start, end; int error; + if (fl->l_len < 0) + return (EINVAL); /* * Convert the flock structure into a start and end. */ @@ -120,6 +123,9 @@ lf_advlock(ap, head, size) break; case SEEK_END: + /* size always >= 0 */ + if (fl->l_start > 0 && size > OFF_MAX - fl->l_start) + return (EOVERFLOW); start = size + fl->l_start; break; @@ -131,7 +137,12 @@ lf_advlock(ap, head, size) if (fl->l_len == 0) end = -1; else { - end = start + fl->l_len - 1; + off_t oadd = fl->l_len - 1; + + /* fl->l_len & start are non-negative */ + if (oadd > OFF_MAX - start) + return (EOVERFLOW); + end = start + oadd; if (end < start) return (EINVAL); }