xfs
[Top] [All Lists]

[PATCH 1/2]segmentation fault in xfs_io mread/mwrite command

To: xfs@xxxxxxxxxxx
Subject: [PATCH 1/2]segmentation fault in xfs_io mread/mwrite command
From: Utako Kusaka <utako@xxxxxxxxxxxxxx>
Date: Wed, 29 Nov 2006 09:26:38 +0900
Sender: xfs-bounce@xxxxxxxxxxx
Hi,

I found the following issues in xfs_io.
 mread command:
  a) Causes a segmentation fault.
     Because "length"+1 bytes data is copied to buffer in read_mapping(),
     but buffer size is "length".
  b) Reads from wrong offset.
  c) The first byte of dump data is incorrect when length > page size.
 mwrite command:
  d) Data placement is incorrect when -r option is specified
     because of wrong for-loop counter.

This patch fixes them.

Signed-off-by: Utako Kusaka <utako@xxxxxxxxxxxxxx>
---

--- xfsprogs-2.8.11-orgn/io/mmap.c      2006-06-26 14:01:15.000000000 +0900
+++ xfsprogs-2.8.11/io/mmap.c   2006-11-14 16:46:18.651458839 +0900
@@ -323,26 +323,6 @@ msync_f(
        return 0;
 }
 
-static int
-read_mapping(
-       char            *dest,
-       off64_t         offset,
-       int             dump,
-       off64_t         dumpoffset,
-       size_t          dumplength)
-{
-       *dest = *(((char *)mapping->addr) + offset);
-
-       if (offset % pagesize == 0) {
-               if (dump == 2)
-                       dumpoffset += mapping->offset;
-               if (dump)
-                       dump_buffer(dumpoffset, dumplength);
-               return 1;
-       }
-       return 0;
-}
-
 static void
 mread_help(void)
 {
@@ -373,9 +353,9 @@ mread_f(
        int             argc,
        char            **argv)
 {
-       off64_t         offset, tmp;
+       off64_t         offset, tmp, dumpoffset, printoffset;
        ssize_t         length;
-       size_t          dumplen;
+       size_t          dumplen, cnt = 0;
        char            *bp;
        void            *start;
        int             dump = 0, rflag = 0, c;
@@ -422,6 +402,11 @@ mread_f(
        start = check_mapping_range(mapping, offset, length, 0);
        if (!start)
                return 0;
+       dumpoffset = offset - mapping->offset;
+       if (dump == 2)
+               printoffset = offset;
+       else
+               printoffset = dumpoffset;
 
        if (alloc_buffer(pagesize, 0, 0) < 0)
                return 0;
@@ -432,28 +417,35 @@ mread_f(
                dumplen = pagesize;
 
        if (rflag) {
-               for (tmp = length, c = 0; tmp > 0; tmp--, bp++, c = 1)
-                       if (read_mapping(bp, tmp, c? dump:0, offset, dumplen)) {
+               for (tmp = length - 1, c = 0; tmp >= 0; tmp--, c = 1) {
+                       *bp = *(((char *)mapping->addr) + dumpoffset + tmp);
+                       cnt++;
+                       if (c && cnt == dumplen) {
+                               if (dump) {
+                                       dump_buffer(printoffset, dumplen);
+                                       printoffset += dumplen;
+                               }
                                bp = (char *)buffer;
                                dumplen = pagesize;
+                               cnt = 0;
+                       } else {
+                               bp++;
                        }
+               }
        } else {
-               for (tmp = 0, c = 0; tmp < length; tmp++, bp++, c = 1)
-                       if (read_mapping(bp, tmp, c? dump:0, offset, dumplen)) {
+               for (tmp = 0, c = 0; tmp < length; tmp++, c = 1) {
+                       *bp = *(((char *)mapping->addr) + dumpoffset + tmp);
+                       cnt++;
+                       if (c && cnt == dumplen) {
+                               if (dump)
+                                       dump_buffer(printoffset + tmp -
+                                               (dumplen - 1), dumplen);
                                bp = (char *)buffer;
                                dumplen = pagesize;
+                               cnt = 0;
+                       } else {
+                               bp++;
                        }
-       }
-       /* dump the remaining (partial page) part of the read buffer */
-       if (dump) {
-               if (rflag)
-                       dumplen = length % pagesize;
-               else
-                       dumplen = tmp % pagesize;
-               if (dumplen) {
-                       if (dump == 2)
-                               tmp += mapping->offset;
-                       dump_buffer(tmp, dumplen);
                }
        }
        return 0;
@@ -571,7 +563,7 @@ mwrite_f(
                return 0;
 
        if (rflag) {
-               for (tmp = offset + length; tmp > offset; tmp--)
+               for (tmp = offset + length -1; tmp >= offset; tmp--)
                        ((char *)mapping->addr)[tmp] = seed;
        } else {
                for (tmp = offset; tmp < offset + length; tmp++)


<Prev in Thread] Current Thread [Next in Thread>