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