Updated variant:
--- vfs_syscalls.c.old Sat Aug 11 02:14:18 2001
+++ vfs_syscalls.c Sun Aug 19 05:01:32 2001
@@ -1614,29 +1614,44 @@
register struct filedesc *fdp = p->p_fd;
register struct file *fp;
struct vattr vattr;
- int error;
+ struct vnode *vp;
+ off_t offset;
+ int error, noneg;
if ((u_int)SCARG(uap, fd) >= fdp->fd_nfiles ||
(fp = fdp->fd_ofiles[SCARG(uap, fd)]) == NULL)
return (EBADF);
if (fp->f_type != DTYPE_VNODE)
return (ESPIPE);
+ vp = (struct vnode *)fp->f_data;
+ noneg = (vp->v_type != VCHR);
+ offset = SCARG(uap, offset);
switch (SCARG(uap, whence)) {
case L_INCR:
- fp->f_offset += SCARG(uap, offset);
+ if (noneg &&
+ ((offset > 0 && fp->f_offset > OFF_MAX - offset) ||
+ (offset < 0 && fp->f_offset < OFF_MIN - offset)))
+ return (EOVERFLOW);
+ offset += fp->f_offset;
break;
case L_XTND:
- error=VOP_GETATTR((struct vnode *)fp->f_data, &vattr, cred, p);
+ error = VOP_GETATTR(vp, &vattr, cred, p);
if (error)
return (error);
- fp->f_offset = SCARG(uap, offset) + vattr.va_size;
+ if (noneg &&
+ ((offset > 0 && vattr.va_size > OFF_MAX - offset) ||
+ (offset < 0 && vattr.va_size < OFF_MIN - offset)))
+ return (EOVERFLOW);
+ offset += vattr.va_size;
break;
case L_SET:
- fp->f_offset = SCARG(uap, offset);
break;
default:
return (EINVAL);
}
+ if (noneg && offset < 0)
+ return (EINVAL);
+ fp->f_offset = offset;
*(off_t *)(p->p_retval) = fp->f_offset;
return (0);
}
--
Andrey A. Chernov
http://ache.pp.ru/
To Unsubscribe: send mail to [EMAIL PROTECTED]
with "unsubscribe freebsd-current" in the body of the message