Correct file descriptor leaks in lseek and do_dup.

The leak in lseek was introduced in vfs_syscalls.c revision 1.218.
The leak in do_dup was introduced in kern_descrip.c revision 1.158.

Submitted by:	iedowse
This commit is contained in:
nectar 2003-01-06 13:19:05 +00:00
parent a7aae2379c
commit 266526442d
3 changed files with 33 additions and 18 deletions

View File

@ -483,6 +483,7 @@ do_dup(td, type, old, new, retval)
error = fdalloc(td, new, &newfd);
if (error) {
FILEDESC_UNLOCK(fdp);
fdrop(fp, td);
return (error);
}
}

View File

@ -1326,8 +1326,10 @@ lseek(td, uap)
case L_INCR:
if (noneg &&
(fp->f_offset < 0 ||
(offset > 0 && fp->f_offset > OFF_MAX - offset)))
return (EOVERFLOW);
(offset > 0 && fp->f_offset > OFF_MAX - offset))) {
error = EOVERFLOW;
break;
}
offset += fp->f_offset;
break;
case L_XTND:
@ -1335,21 +1337,26 @@ lseek(td, uap)
error = VOP_GETATTR(vp, &vattr, cred, td);
VOP_UNLOCK(vp, 0, td);
if (error)
return (error);
break;
if (noneg &&
(vattr.va_size > OFF_MAX ||
(offset > 0 && vattr.va_size > OFF_MAX - offset)))
return (EOVERFLOW);
(offset > 0 && vattr.va_size > OFF_MAX - offset))) {
error = EOVERFLOW;
break;
}
offset += vattr.va_size;
break;
case L_SET:
break;
default:
fdrop(fp, td);
return (EINVAL);
error = EINVAL;
}
if (error == 0 && noneg && offset < 0)
error = EINVAL;
if (error != 0) {
fdrop(fp, td);
return (error);
}
if (noneg && offset < 0)
return (EINVAL);
fp->f_offset = offset;
*(off_t *)(td->td_retval) = fp->f_offset;
fdrop(fp, td);

View File

@ -1326,8 +1326,10 @@ lseek(td, uap)
case L_INCR:
if (noneg &&
(fp->f_offset < 0 ||
(offset > 0 && fp->f_offset > OFF_MAX - offset)))
return (EOVERFLOW);
(offset > 0 && fp->f_offset > OFF_MAX - offset))) {
error = EOVERFLOW;
break;
}
offset += fp->f_offset;
break;
case L_XTND:
@ -1335,21 +1337,26 @@ lseek(td, uap)
error = VOP_GETATTR(vp, &vattr, cred, td);
VOP_UNLOCK(vp, 0, td);
if (error)
return (error);
break;
if (noneg &&
(vattr.va_size > OFF_MAX ||
(offset > 0 && vattr.va_size > OFF_MAX - offset)))
return (EOVERFLOW);
(offset > 0 && vattr.va_size > OFF_MAX - offset))) {
error = EOVERFLOW;
break;
}
offset += vattr.va_size;
break;
case L_SET:
break;
default:
fdrop(fp, td);
return (EINVAL);
error = EINVAL;
}
if (error == 0 && noneg && offset < 0)
error = EINVAL;
if (error != 0) {
fdrop(fp, td);
return (error);
}
if (noneg && offset < 0)
return (EINVAL);
fp->f_offset = offset;
*(off_t *)(td->td_retval) = fp->f_offset;
fdrop(fp, td);