Commit e203db29 authored by Salva Peiró's avatar Salva Peiró Committed by Joerg Roedel

iommu/omap: Fix debug_read_tlb() to use seq_printf()

The debug_read_tlb() uses the sprintf() functions directly on the buffer
allocated by buf = kmalloc(count), without taking into account the size
of the buffer, with the consequence corrupting the heap, depending on
the count requested by the user.

The patch fixes the issue replacing sprintf() by seq_printf().
Signed-off-by: default avatarSalva Peiró <speirofr@gmail.com>
Signed-off-by: default avatarJoerg Roedel <jroedel@suse.de>
parent 5835b6a6
...@@ -133,26 +133,18 @@ __dump_tlb_entries(struct omap_iommu *obj, struct cr_regs *crs, int num) ...@@ -133,26 +133,18 @@ __dump_tlb_entries(struct omap_iommu *obj, struct cr_regs *crs, int num)
} }
static ssize_t iotlb_dump_cr(struct omap_iommu *obj, struct cr_regs *cr, static ssize_t iotlb_dump_cr(struct omap_iommu *obj, struct cr_regs *cr,
char *buf) struct seq_file *s)
{ {
char *p = buf; return seq_printf(s, "%08x %08x %01x\n", cr->cam, cr->ram,
(cr->cam & MMU_CAM_P) ? 1 : 0);
/* FIXME: Need more detail analysis of cam/ram */
p += sprintf(p, "%08x %08x %01x\n", cr->cam, cr->ram,
(cr->cam & MMU_CAM_P) ? 1 : 0);
return p - buf;
} }
static size_t omap_dump_tlb_entries(struct omap_iommu *obj, char *buf, static size_t omap_dump_tlb_entries(struct omap_iommu *obj, struct seq_file *s)
ssize_t bytes)
{ {
int i, num; int i, num;
struct cr_regs *cr; struct cr_regs *cr;
char *p = buf;
num = bytes / sizeof(*cr); num = obj->nr_tlb_entries;
num = min(obj->nr_tlb_entries, num);
cr = kcalloc(num, sizeof(*cr), GFP_KERNEL); cr = kcalloc(num, sizeof(*cr), GFP_KERNEL);
if (!cr) if (!cr)
...@@ -160,40 +152,28 @@ static size_t omap_dump_tlb_entries(struct omap_iommu *obj, char *buf, ...@@ -160,40 +152,28 @@ static size_t omap_dump_tlb_entries(struct omap_iommu *obj, char *buf,
num = __dump_tlb_entries(obj, cr, num); num = __dump_tlb_entries(obj, cr, num);
for (i = 0; i < num; i++) for (i = 0; i < num; i++)
p += iotlb_dump_cr(obj, cr + i, p); iotlb_dump_cr(obj, cr + i, s);
kfree(cr); kfree(cr);
return p - buf; return 0;
} }
static ssize_t debug_read_tlb(struct file *file, char __user *userbuf, static int debug_read_tlb(struct seq_file *s, void *data)
size_t count, loff_t *ppos)
{ {
struct omap_iommu *obj = file->private_data; struct omap_iommu *obj = s->private;
char *p, *buf;
ssize_t bytes, rest;
if (is_omap_iommu_detached(obj)) if (is_omap_iommu_detached(obj))
return -EPERM; return -EPERM;
buf = kmalloc(count, GFP_KERNEL);
if (!buf)
return -ENOMEM;
p = buf;
mutex_lock(&iommu_debug_lock); mutex_lock(&iommu_debug_lock);
p += sprintf(p, "%8s %8s\n", "cam:", "ram:"); seq_printf(s, "%8s %8s\n", "cam:", "ram:");
p += sprintf(p, "-----------------------------------------\n"); seq_puts(s, "-----------------------------------------\n");
rest = count - (p - buf); omap_dump_tlb_entries(obj, s);
p += omap_dump_tlb_entries(obj, p, rest);
bytes = simple_read_from_buffer(userbuf, count, ppos, buf, p - buf);
mutex_unlock(&iommu_debug_lock); mutex_unlock(&iommu_debug_lock);
kfree(buf);
return bytes; return 0;
} }
static void dump_ioptable(struct seq_file *s) static void dump_ioptable(struct seq_file *s)
...@@ -268,7 +248,7 @@ static int debug_read_pagetable(struct seq_file *s, void *data) ...@@ -268,7 +248,7 @@ static int debug_read_pagetable(struct seq_file *s, void *data)
} }
DEBUG_FOPS_RO(regs); DEBUG_FOPS_RO(regs);
DEBUG_FOPS_RO(tlb); DEBUG_SEQ_FOPS_RO(tlb);
DEBUG_SEQ_FOPS_RO(pagetable); DEBUG_SEQ_FOPS_RO(pagetable);
#define __DEBUG_ADD_FILE(attr, mode) \ #define __DEBUG_ADD_FILE(attr, mode) \
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment