summaryrefslogtreecommitdiffstats
path: root/sys/ufs
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2012-06-21 09:20:07 +0000
committerkib <kib@FreeBSD.org>2012-06-21 09:20:07 +0000
commit7e14b6838bca79d6c18eb00c4fe8c0a3e3b066ff (patch)
tree01adac257d485894b5ea4edc255ff795afc07789 /sys/ufs
parentdf9f3d2faa1df2bb13d274183876fe227e259a65 (diff)
downloadFreeBSD-src-7e14b6838bca79d6c18eb00c4fe8c0a3e3b066ff.zip
FreeBSD-src-7e14b6838bca79d6c18eb00c4fe8c0a3e3b066ff.tar.gz
Fix unbounded-length malloc, controlled from usermode. The added check
is performed before exact size of the buffer is calculated, but the buffer cannot have size greater then the total space allocated for extended attributes. The existing check is executing with precise size, but it is too late, since buffer needs to be allocated in advance. Also, adapt to uio_resid being of ssize_t type. Use lblktosize instead of multiplying by fs block size by hand as well. Reported and tested by: pho MFC after: 1 week
Diffstat (limited to 'sys/ufs')
-rw-r--r--sys/ufs/ffs/ffs_vnops.c10
1 files changed, 7 insertions, 3 deletions
diff --git a/sys/ufs/ffs/ffs_vnops.c b/sys/ufs/ffs/ffs_vnops.c
index 6259911..ee6733b 100644
--- a/sys/ufs/ffs/ffs_vnops.c
+++ b/sys/ufs/ffs/ffs_vnops.c
@@ -1648,7 +1648,8 @@ vop_setextattr {
struct inode *ip;
struct fs *fs;
uint32_t ealength, ul;
- int ealen, olen, eapad1, eapad2, error, i, easize;
+ ssize_t ealen;
+ int olen, eapad1, eapad2, error, i, easize;
u_char *eae, *p;
ip = VTOI(ap->a_vp);
@@ -1667,6 +1668,10 @@ vop_setextattr {
if (ap->a_vp->v_mount->mnt_flag & MNT_RDONLY)
return (EROFS);
+ ealen = ap->a_uio->uio_resid;
+ if (ealen < 0 || ealen > lblktosize(fs, NXADDR))
+ return (EINVAL);
+
error = extattr_check_cred(ap->a_vp, ap->a_attrnamespace,
ap->a_cred, ap->a_td, VWRITE);
if (error) {
@@ -1684,7 +1689,6 @@ vop_setextattr {
if (error)
return (error);
- ealen = ap->a_uio->uio_resid;
ealength = sizeof(uint32_t) + 3 + strlen(ap->a_name);
eapad1 = 8 - (ealength % 8);
if (eapad1 == 8)
@@ -1712,7 +1716,7 @@ vop_setextattr {
easize += (ealength - ul);
}
}
- if (easize > NXADDR * fs->fs_bsize) {
+ if (easize > lblktosize(fs, NXADDR)) {
free(eae, M_TEMP);
ffs_close_ea(ap->a_vp, 0, ap->a_cred, ap->a_td);
if (ip->i_ea_area != NULL && ip->i_ea_error == 0)
OpenPOWER on IntegriCloud