Blame SOURCES/kexec-tools-2.0.4-makedumpfile-Fix-a-segmentation-fault-when-physical-addr.patch

422c26
From abce4d50fc28ff182bd7e0b714e21c0dfec62bd1 Mon Sep 17 00:00:00 2001
422c26
From: Jingbai Ma <jingbai.ma@hp.com>
422c26
Date: Fri, 18 Apr 2014 16:55:02 +0900
422c26
Subject: [PATCH] [PATCH v3] Fix a segmentation fault when physical address
422c26
 exceeds 8TB boundary.
422c26
422c26
This patch intends to fix a segmentation fault when physical address
422c26
exceeds 8TB boundary.
422c26
422c26
Changelog:
422c26
v3:
422c26
- Revise some comments according to Daisuke and Petr's feedback.
422c26
422c26
v2:
422c26
- Add more comments from Daisuke HATAYAMA.
422c26
422c26
In function is_on(), if the physical address higher than 8T, pfn (i) will
422c26
greater than 2G, it will be a negative value and will cause a segmentation
422c26
fault.
422c26
is_on(char *bitmap, int i)
422c26
{
422c26
        return bitmap[i>>3] & (1 << (i & 7));
422c26
}
422c26
422c26
Daisuke's detailed analysis:
422c26
static inline int
422c26
is_dumpable(struct dump_bitmap *bitmap, unsigned long long pfn)
422c26
{
422c26
        off_t offset;
422c26
        if (pfn == 0 || bitmap->no_block != pfn/PFN_BUFBITMAP) {
422c26
                offset = bitmap->offset + BUFSIZE_BITMAP*(pfn/PFN_BUFBITMAP);
422c26
                lseek(bitmap->fd, offset, SEEK_SET);
422c26
                read(bitmap->fd, bitmap->buf, BUFSIZE_BITMAP);
422c26
                if (pfn == 0)
422c26
                        bitmap->no_block = 0;
422c26
                else
422c26
                        bitmap->no_block = pfn/PFN_BUFBITMAP;
422c26
        }
422c26
        return is_on(bitmap->buf, pfn%PFN_BUFBITMAP);
422c26
}
422c26
422c26
PFN_BUFBTIMAP is constant 32 K. So, it seems that the 4 byte byte
422c26
length came here.
422c26
422c26
But right shift to signed integer is implementation defined. We should
422c26
not use right shift to signed integer. it looks gcc performs
422c26
arithmetic shift and this bahaviour is buggy in case of is_on().
422c26
422c26
static inline int
422c26
is_dumpable_cyclic(char *bitmap, unsigned long long pfn, struct cycle *cycle)
422c26
{
422c26
        if (pfn < cycle->start_pfn || cycle->end_pfn <= pfn)
422c26
                return FALSE;
422c26
        else
422c26
                return is_on(bitmap, pfn - cycle->start_pfn);
422c26
}
422c26
422c26
Simply, (pfn - cycle->start_pfn) could be ((info->max_mapnr - 1) - 0). It's
422c26
possible to pass more than 2 Gi by using system with more than 8 TiB
422c26
physical memory space.
422c26
422c26
So, in function is_on()
422c26
422c26
- i must be unsigned in order to make right shift operation
422c26
  meaningful, and
422c26
422c26
- i must have 8 byte for systems with more than 8 TiB physical memory
422c26
  space.
422c26
422c26
Petr's comments:
422c26
Why an unsigned long for the variable i is not sufficient?
422c26
It would be enough on 64-bit systems, where an unsigned long is just as big as
422c26
an unsigned long long (both 64 bits). But on 32-bit systems, an unsigned long
422c26
is 32-bit, but physical memory can be larger (e.g. 36 bits with PAE).
422c26
422c26
Signed-off-by: Jingbai Ma <jingbai.ma@hp.com>
422c26
---
422c26
 makedumpfile.h | 2 +-
422c26
 1 file changed, 1 insertion(+), 1 deletion(-)
422c26
422c26
diff --git a/makedumpfile.h b/makedumpfile.h
422c26
index a5826e0..33ab0cf 100644
422c26
--- a/makedumpfile-1.5.4/makedumpfile.h
422c26
+++ b/makedumpfile-1.5.4/makedumpfile.h
422c26
@@ -1546,7 +1546,7 @@ int get_xen_info_ia64(void);
422c26
 #endif	/* s390x */
422c26
 
422c26
 static inline int
422c26
-is_on(char *bitmap, int i)
422c26
+is_on(char *bitmap, unsigned long long i)
422c26
 {
422c26
 	return bitmap[i>>3] & (1 << (i & 7));
422c26
 }
422c26
-- 
422c26
1.9.3
422c26