Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 25 Jan 2016 23:58:10 +0000
From:      bugzilla-noreply@freebsd.org
To:        freebsd-bugs@FreeBSD.org
Subject:   [Bug 206626] Integer overflow in nfssvc system call
Message-ID:  <bug-206626-8@https.bugs.freebsd.org/bugzilla/>

next in thread | raw e-mail | index | archive | help
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=3D206626

            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@FreeBSD.org
          Reporter: ecturt@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) !=3D 0)
                        error =3D copyin(uap->argp, &nid, sizeof(nid));
                else {
                        error =3D copyin(uap->argp, &onid, sizeof(onid));
                        if (error =3D=3D 0) {
                                nid.nid_flag =3D onid.nid_flag;
                                nid.nid_uid =3D onid.nid_uid;
                                nid.nid_gid =3D onid.nid_gid;
                                nid.nid_usermax =3D onid.nid_usermax;
                                nid.nid_usertimeout =3D onid.nid_usertimeou=
t;
                                nid.nid_name =3D onid.nid_name;
                                nid.nid_namelen =3D onid.nid_namelen;
                                nid.nid_ngroup =3D 0;
                                nid.nid_grps =3D NULL;
                        }
                }
                if (error)
                        goto out;
                error =3D 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 attribute=
s.
 */
APPLESTATIC int
nfssvc_idname(struct nfsd_idargs *nidp)
{
        ...

        if (nidp->nid_flag & NFSID_INITIALIZE) {
                cp =3D malloc(nidp->nid_namelen + 1, M_NFSSTRING, M_WAITOK);
                error =3D copyin(CAST_USER_ADDR_T(nidp->nid_name), cp,
                    nidp->nid_namelen);
                if (error !=3D 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` b=
ytes
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 furthe=
r:
https://gist.github.com/CTurt/957360482a4dc453f6a4

--=20
You are receiving this mail because:
You are the assignee for the bug.=



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?bug-206626-8>