Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 30 Mar 2002 08:12:55 -0500 (EST)
From:      Robert Watson <rwatson@FreeBSD.org>
To:        bugs@FreeBSD.org
Subject:   I think I found & fixed a FreeBSD kernel bug - what should I do? (fwd)
Message-ID:  <Pine.NEB.3.96L.1020330081130.73912R-100000@fledge.watson.org>

next in thread | raw e-mail | index | archive | help

I've e-mailed Dorr asking him to submit this as a PR or via other bugs
reporting mechanisms, but I want to make sure it doesn't get lost.
Unfortunately, due to a family medical emergency, I don't have time to
follow through on this at this time, and probably won't be able to get to
it until a week or two from now.  Would be much better if someone else
could pick it up.

Thanks,

Robert N M Watson             FreeBSD Core Team, TrustedBSD Project
robert@fledge.watson.org      NAI Labs, Safeport Network Services

---------- Forwarded message ----------
Date: Wed, 27 Mar 2002 15:53:33 -0800 (PST)
From: "Dorr H. Clark" <dclark@applmath.scu.edu>
To: John Baldwin <jhb@FreeBSD.ORG>, Robert Watson <rwatson@FreeBSD.ORG>
Subject: I think I found & fixed a FreeBSD kernel bug - what should I do?


Hello-

I've been working with the FreeBSD 4.4 release
and I believe I found and fixed a kernel bug
that is still present at TOT.  

If I'm following the wrong process by approaching
you two please forgive me, maybe you can steer
me in the right direction?  Also, maybe based
on your insights you can explain why it's not
really a bug (but I did get a real crash).

I am using the changes in my own system now.  
Also, maybe it's real but someone can show 
how to fix it better than my implementation.
My goal was to minimize code changes and try to match
the existing style.

The problem is that unlike other parts of the kernel,
vnode_pager_alloc assumes that the call to vm_object_allocate
will succeed.  If the allocation fails, the kernel
crashes immediately.  I have put in a defensive check
for this, and also changed the error handling in 
the calling routine to account for the allocation failure.

My fix touches two files, vm/vnode_pager.c and kern/vfs_default.c.
The changes are presented at the bottom of this email.

I would welcome your advice as to how to proceed from here.

Thanks,

-Dorr H. Clark


Here are the diffs with some code context:

ORIGINAL CODE in vm/vnode_pager.c lines 147-159 (TOT version)

        if (object == NULL) {
                /*
                 * And an object of the appropriate size
                 */
                object = vm_object_allocate(OBJT_VNODE,
OFF_TO_IDX(round_page(size)));
                object->flags = 0;

                object->un_pager.vnp.vnp_size = size;

                object->handle = handle;
                vp->v_object = object;
                vp->v_usecount++;
        } else {

END ORIGINAL CODE vm/vnode_pager.c

MY CHANGES to this file

        if (object == NULL) {
                /*
                 * And an object of the appropriate size
                 */
                object = vm_object_allocate(OBJT_VNODE, 
OFF_TO_IDX(round_page(size)));
                if (object) {
                        object->flags = 0;
                        object->un_pager.vnp.vnp_size = size;
                        object->handle = handle;
                        vp->v_object = object;
                        vp->v_usecount++;
                }
        } else {

END MY CHANGES vm/vnode_pager.c

ORIGINAL CODE in kern/vfs_default.c lines 572-607

        if ((object = vp->v_object) == NULL) {
                if (vp->v_type == VREG || vp->v_type == VDIR) {
                        if ((error = VOP_GETATTR(vp, &vat, cred, td)) !=
0)
                                goto retn;
                        object = vnode_pager_alloc(vp, vat.va_size, 0, 0);
                } else if (devsw(vp->v_rdev) != NULL) {
                        /*
                         * This simply allocates the biggest object
possible
                         * for a disk vnode.  This should be fixed, but
doesn't
                         * cause any problems (yet).
                         */
                        object = vnode_pager_alloc(vp,
IDX_TO_OFF(INT_MAX), 0,
0);
                } else {
                        goto retn;
                }
                /*
                 * Dereference the reference we just created.  This
assumes
                 * that the object is associated with the vp.
                 */
                object->ref_count--;
                vp->v_usecount--;
        } else {
                if (object->flags & OBJ_DEAD) {
                        VOP_UNLOCK(vp, 0, td);
                        tsleep(object, PVM, "vodead", 0);
                        vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
                        goto retry;
                }
        }

        KASSERT(vp->v_object != NULL, ("vfs_object_create: NULL object"));
        vp->v_flag |= VOBJBUF;

retn:
        return (error);
}

END ORIGINAL CODE kern/vfs_default.c

MY CHANGES to this file

        if ((object = vp->v_object) == NULL) {
                if (vp->v_type == VREG || vp->v_type == VDIR) {
                        if (((error = VOP_GETATTR(vp, &vat, cred, p)) !=
0) ||
                        (!(object = vnode_pager_alloc(vp, vat.va_size, 0,
0))))
                                goto retn;
                } else if (devsw(vp->v_rdev) != NULL) {
                        /*
                         * This simply allocates the biggest object
possible
                         * for a disk vnode.  This should be fixed, but
doesn't
                         * cause any problems (yet).
                         */
                        if (!(object = vnode_pager_alloc(vp,
IDX_TO_OFF(INT_MAX), 0, 0)))
                                goto retn;
                } else {
                        goto retn;
                }
                /*
                 * Dereference the reference we just created.  This
assumes
                 * that the object is associated with the vp.
                 */

                object->ref_count--;
                vp->v_usecount--;
        } else {
                if (object->flags & OBJ_DEAD) {
                        VOP_UNLOCK(vp, 0, p);
                        tsleep(object, PVM, "vodead", 0);
                        vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
                        goto retry;
                }
        }

        KASSERT(vp->v_object != NULL, ("vfs_object_create: NULL
object"));
        vp->v_flag |= VOBJBUF;

retn:
        return (error);
}

END MY CHANGES to vfs_default.c





To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?Pine.NEB.3.96L.1020330081130.73912R-100000>