NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

kern/38336: NULL deref in nfs_lookup



>Number:         38336
>Category:       kern
>Synopsis:       NULL deref in nfs_lookup
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    kern-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Sat Mar 29 23:15:00 +0000 2008
>Originator:     Andrew Doran
>Release:        4.99.58
>Organization:
The NetBSD Project
>Environment:
4.99.58 + local changes to socket code
>Description:
nfs_vnops.c:

    925         nfsm_request(np, NFSPROC_LOOKUP, curlwp, cnp->cn_cred);
    926         if (error) {
    927                 nfsm_postop_attr(dvp, attrflag, 0);
    928                 m_freem(mrep);
    929                 goto nfsmout;
    930         }

nfsm_request() fills 'error' and typically 'md'. In case of error,
'md' is sometimes not filled and can contain junk from the stack,
but nfsm_postop_attr() assumes that 'md' is always filled. Here is 
nfsm_postop_attr() partially decrypted:

        struct vnode *ttvp = dvp;
        {
                t1 = ((char *) ((md)->m_hdr.mh_data)) + md->m_hdr.mh_len - dpos;
                if (t1 >= (4) && 1) {
                        (tl) = (u_int32_t *) (dpos);
                        dpos += (4);
                } else if ((t1 = nfsm_disct(&md, &dpos, (4), t1, &cp2)) != 0) {
                        error = t1;
                        m_freem(mrep);
                        goto nfsmout; 
                } else {
                        (tl) = (u_int32_t *) cp2;
                } }; if (((attrflag) = ((int)
        (__builtin_constant_p(((__uint32_t) ((__int32_t) (*tl)))) ?
        (((((__uint32_t) ((__int32_t) (*tl))) & 0xff000000) >> 24) |
        ((((__uint32_t) ((__int32_t) (*tl))) & 0x00ff0000) >> 8) |
        ((((__uint32_t) ((__int32_t) (*tl))) & 0x0000ff00) << 8) |
        ((((__uint32_t) ((__int32_t) (*tl))) & 0x000000ff) << 24)) :
        __byte_swap_u32_variable((__uint32_t) ((__int32_t) (*tl)))))) != 0)
        {
                if ((t1 = nfsm_loadattrcache(&ttvp, &md, &dpos, (struct vattr 
*) 0, (0))) != 0) {
                        error = t1;
                        (attrflag) = 0;
                        m_freem(mrep);
                        goto nfsmout;
                }
                (dvp) = ttvp;
        }
        m_freem(mrep);
        goto nfsmout;



>How-To-Repeat:
Make nfsm_request() fail.

>Fix:
Not yet known.



Home | Main Index | Thread Index | Old Index