[Bug 206626] Integer overflow in nfssvc system call
bugzilla-noreply at freebsd.org
bugzilla-noreply at freebsd.org
Mon Jan 25 23:58:10 UTC 2016
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=206626
Bug ID: 206626
Summary: Integer overflow in nfssvc system call
Product: Base System
Version: 11.0-CURRENT
Hardware: Any
OS: Any
Status: New
Severity: Affects Many People
Priority: ---
Component: kern
Assignee: freebsd-bugs at FreeBSD.org
Reporter: ecturt at gmail.com
The system call `sys_nfssvc` calls `nfssvc_call`, which copies in some user
data, and calls `nfssvc_idname`:
if (uap->flag & NFSSVC_IDNAME) {
if ((uap->flag & NFSSVC_NEWSTRUCT) != 0)
error = copyin(uap->argp, &nid, sizeof(nid));
else {
error = copyin(uap->argp, &onid, sizeof(onid));
if (error == 0) {
nid.nid_flag = onid.nid_flag;
nid.nid_uid = onid.nid_uid;
nid.nid_gid = onid.nid_gid;
nid.nid_usermax = onid.nid_usermax;
nid.nid_usertimeout = onid.nid_usertimeout;
nid.nid_name = onid.nid_name;
nid.nid_namelen = onid.nid_namelen;
nid.nid_ngroup = 0;
nid.nid_grps = NULL;
}
}
if (error)
goto out;
error = nfssvc_idname(&nid);
goto out;
In `nfssvc_idname`, `nidp->nid_namelen` is user controllable, and is used
without any bound checks:
/*
* This function is called from the nfssvc(2) system call, to update the
* kernel user/group name list(s) for the V4 owner and ownergroup attributes.
*/
APPLESTATIC int
nfssvc_idname(struct nfsd_idargs *nidp)
{
...
if (nidp->nid_flag & NFSID_INITIALIZE) {
cp = malloc(nidp->nid_namelen + 1, M_NFSSTRING, M_WAITOK);
error = copyin(CAST_USER_ADDR_T(nidp->nid_name), cp,
nidp->nid_namelen);
if (error != 0) {
free(cp, M_NFSSTRING);
goto out;
}
...
}
Let's look at the disassembly of how `malloc` is called:
.text:FFFFFFFF807651AD mov edi, [rdi+20h]
.text:FFFFFFFF807651B0 mov edx, 2
.text:FFFFFFFF807651B5 mov rsi, offset M_NEWNFSSTRING
.text:FFFFFFFF807651BC add edi, 1
.text:FFFFFFFF807651BF movsxd rdi, edi
.text:FFFFFFFF807651C2 call malloc
If a `nid_namelen` of `0xffffffff` is supplied, an allocation size of `0` bytes
will be passed to `malloc`.
We then have `copyin` of `0xffffffff` bytes on this allocation of size `0`.
The bug is only triggerable as `root`, and I couldn't get any way to panic from
writing to allocation of 0 bytes.
Code to play with if anyone is interested in exploring its potential further:
https://gist.github.com/CTurt/957360482a4dc453f6a4
--
You are receiving this mail because:
You are the assignee for the bug.
More information about the freebsd-bugs
mailing list