proc-vmcore: wrong data type casting fix
Subsystems (4)
PATCH 2/2 proc-vmcore: wrong data type casting fix
On i686 PAE enabled machine the contiguous physical area could be large and it can cause triming down variables in below calculation in read_vmcore() and mmap_vmcore():
tsz = min_t(size_t, m->offset + m->size - *fpos, buflen);
Then the real size passed down is not correct any more. Suppose m->offset + m->size - *fpos being truncated to 0, buflen >0 then we will get tsz = 0. It is of course not an expected result.
During out test there are two problems caused by it:
1) read_vmcore will refuse to continue so makedumpfile fails.
2) mmap_vmcore will trigger BUG_ON() in remap_pfn_range().
Use min_lt instead so that the variables are not truncated.
--- fs/proc/vmcore.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
fs/proc/vmcore.c +3 -2
@@ -231,7 +231,8 @@ static ssize_t __read_vmcore(char *buffelist_for_each_entry (m, &vmcore_list, list) {if (*fpos < m->offset + m->size) { - tsz =min_t (size_t, m->offset + m->size - *fpos, buflen); + tsz = (size_t )min_lt (m->offset + m->size - *fpos, + buflen); start = m->paddr + *fpos - m->offset; tmp =read_from_oldmem (buffer, tsz, &start, userbuf);if (tmp <0 )
@@ -461,7 +462,7 @@ static int mmap_vmcore(struct file *fileif (start < m->offset + m->size) {u64 paddr =0 ; - tsz =min_t (size_t, m->offset + m->size - start, size); + tsz = (size_t )min_lt (m->offset + m->size - start, size); paddr = m->paddr + start - m->offset; if (vmcore_remap_oldmem_pfn(vma, vma->vm_start + len, paddr >> PAGE_SHIFT, tsz,
Quoted 11 lines · On 03/11/16 at 02:21pm, [email protected] wrote:
fs/proc/vmcore.c +2
-1@@ -231,7 +231,8 @@ static ssize_t __read_vmcore(char *buffelist_for_each_entry (m, &vmcore_list, list) {if (*fpos < m->offset + m->size) { - tsz =min_t (size_t, m->offset + m->size - *fpos, buflen); + tsz = (size_t )min_lt (m->offset + m->size - *fpos, + buflen); start = m->paddr + *fpos - m->offset; tmp =read_from_oldmem (buffer, tsz, &start, userbuf);if (tmp <0 )
fs/proc/vmcore.c static int mmap_vmcore(struct file *file · line 468
Quoted 8 lines
fs/proc/vmcore.c +1
-1@@ -461,7 +462,7 @@ static int mmap_vmcore(struct file *fileif (start < m->offset + m->size) {u64 paddr =0 ; - tsz =min_t (size_t, m->offset + m->size - start, size); + tsz = (size_t )min_lt (m->offset + m->size - start, size); paddr = m->paddr + start - m->offset; if (vmcore_remap_oldmem_pfn(vma, vma->vm_start + len, paddr >> PAGE_SHIFT, tsz,
Hi, Dave.
Seems the previous parameter is unsigned long long, and the later one is size_t. The size of both these types doesn't change in running time, why not use min_t(unsigned long long, a, b) instead?
Thanks
Minfei
Hi, Minfei
Quoted 23 lines · Minfei Huang
Quoted 11 lines · On 03/11/16 at 02:21pm, [email protected] wrote:
fs/proc/vmcore.c +2
-1@@ -231,7 +231,8 @@ static ssize_t __read_vmcore(char *buffelist_for_each_entry (m, &vmcore_list, list) {if (*fpos < m->offset + m->size) { - tsz =min_t (size_t, m->offset + m->size - *fpos, buflen); + tsz = (size_t )min_lt (m->offset + m->size - *fpos, + buflen); start = m->paddr + *fpos - m->offset; tmp =read_from_oldmem (buffer, tsz, &start, userbuf);if (tmp <0 )fs/proc/vmcore.c static int mmap_vmcore(struct file *file · line 468
Quoted 8 lines
fs/proc/vmcore.c +1
-1@@ -461,7 +462,7 @@ static int mmap_vmcore(struct file *fileif (start < m->offset + m->size) {u64 paddr =0 ; - tsz =min_t (size_t, m->offset + m->size - start, size); + tsz = (size_t )min_lt (m->offset + m->size - start, size); paddr = m->paddr + start - m->offset; if (vmcore_remap_oldmem_pfn(vma, vma->vm_start + len, paddr >> PAGE_SHIFT, tsz,Hi, Dave.
Quoted 3 lines
Seems the previous parameter is unsigned long long, and the later one is
size_t. The size of both these types doesn't change in running time, why not usemin_t(unsigned long long, a, b)instead?
Just want a common macro so it can benefit other users so that we can simply use it without knowning type details and avoid such similar bugs also.
Thanks
Dave