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>