kernel crash in iov_iter_advance (caused by nfs-kernel-server)
Bug #231746 reported by
deti
This bug affects 1 person
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
linux (Ubuntu) |
Fix Released
|
Undecided
|
Unassigned | ||
Hardy |
Fix Released
|
Medium
|
Stefan Bader |
Bug Description
Binary package hint: linux-image-
Description: Ubuntu 8.04
Release: 8.04
linux-image-
Installed: 2.6.24-16.30zng1
Candidate: 2.6.24-16.30zng1
Version table:
*** 2.6.24-16.30zng1 0
100 /var/lib/
2.6.24-16.30 0
500 http://
When using the nfs kernel server with a very simple export file like this:
/lvm/backup *(rw,no_
a crash in the kernel occurs. See log attached.
This kernel is patched to make xen networking work. There is no way to test nfsd functionality in this setup by using the original ubuntu kernel.
Changed in linux: | |
status: | New → Confirmed |
status: | Confirmed → Fix Committed |
To post a comment you must log in.
There was a fix commited by Nick Piggin (http:// linux.derkeiler .com/Mailing- Lists/Kernel/ 2008-03/ msg08396. html) which was included in 2.6.25-rc6. Please apply this patch to standard 8.04 kernel.
--- a/mm/filemap.c copy_from_ user(struct pa SYMBOL( iov_iter_ copy_from_ user);
+++ b/mm/filemap.c
@@ -1725,21 +1725,27 @@ size_t iov_iter_
}
EXPORT_
-static void __iov_iter_ advance_ iov(struct iov_iter *i, size_t bytes) advance( struct iov_iter *i, size_t bytes)
+void iov_iter_
{
+ BUG_ON(i->count < bytes);
+
if (likely(i->nr_segs == 1)) {
i->iov_offset += bytes;
+ i->count -= bytes;
} else {
const struct iovec *iov = i->iov;
size_t base = i->iov_offset;
/* !iov->iov_ len && i->count)) {
* The !iov->iov_len check ensures we skip over unlikely
- * zero-length segments.
+ * zero-length segments (without overruning the iovec).
*/
- while (bytes || !iov->iov_len) {
- int copy = min(bytes, iov->iov_len - base);
+ while (bytes || unlikely(
+ int copy;
+ copy = min(bytes, iov->iov_len - base); advance_ iov(struc advance( struct iov_iter *i, size_t bytes) advance_ iov(i, bytes); SYMBOL( iov_iter_ advance) ;
+ BUG_ON(!i->count || i->count < copy);
+ i->count -= copy;
bytes -= copy;
base += copy;
if (iov->iov_len == base) {
@@ -1751,14 +1757,6 @@ static void __iov_iter_
i->iov_offset = base;
}
}
-
-void iov_iter_
-{
- BUG_ON(i->count < bytes);
-
- __iov_iter_
- i->count -= bytes;
-}
EXPORT_
/*