aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSalva Peiró <speirofr@gmail.com>2015-07-23 08:26:19 -0400
committerJoerg Roedel <jroedel@suse.de>2015-08-03 11:23:41 -0400
commite203db293863fa15b4b1917d4398fb5bd63c4e88 (patch)
treef5f4dcbded8e90623ee1aab4d5519a032e25a86a
parent5835b6a64ce39434d5cc9857769c73982d488b42 (diff)
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: Salva Peiró <speirofr@gmail.com> Signed-off-by: Joerg Roedel <jroedel@suse.de>
-rw-r--r--drivers/iommu/omap-iommu-debug.c48
1 files changed, 14 insertions, 34 deletions
diff --git a/drivers/iommu/omap-iommu-debug.c b/drivers/iommu/omap-iommu-debug.c
index e9f116f18531..0717aa96ce39 100644
--- a/drivers/iommu/omap-iommu-debug.c
+++ b/drivers/iommu/omap-iommu-debug.c
@@ -133,26 +133,18 @@ __dump_tlb_entries(struct omap_iommu *obj, struct cr_regs *crs, int num)
133} 133}
134 134
135static ssize_t iotlb_dump_cr(struct omap_iommu *obj, struct cr_regs *cr, 135static ssize_t iotlb_dump_cr(struct omap_iommu *obj, struct cr_regs *cr,
136 char *buf) 136 struct seq_file *s)
137{ 137{
138 char *p = buf; 138 return seq_printf(s, "%08x %08x %01x\n", cr->cam, cr->ram,
139 139 (cr->cam & MMU_CAM_P) ? 1 : 0);
140 /* FIXME: Need more detail analysis of cam/ram */
141 p += sprintf(p, "%08x %08x %01x\n", cr->cam, cr->ram,
142 (cr->cam & MMU_CAM_P) ? 1 : 0);
143
144 return p - buf;
145} 140}
146 141
147static size_t omap_dump_tlb_entries(struct omap_iommu *obj, char *buf, 142static size_t omap_dump_tlb_entries(struct omap_iommu *obj, struct seq_file *s)
148 ssize_t bytes)
149{ 143{
150 int i, num; 144 int i, num;
151 struct cr_regs *cr; 145 struct cr_regs *cr;
152 char *p = buf;
153 146
154 num = bytes / sizeof(*cr); 147 num = obj->nr_tlb_entries;
155 num = min(obj->nr_tlb_entries, num);
156 148
157 cr = kcalloc(num, sizeof(*cr), GFP_KERNEL); 149 cr = kcalloc(num, sizeof(*cr), GFP_KERNEL);
158 if (!cr) 150 if (!cr)
@@ -160,40 +152,28 @@ static size_t omap_dump_tlb_entries(struct omap_iommu *obj, char *buf,
160 152
161 num = __dump_tlb_entries(obj, cr, num); 153 num = __dump_tlb_entries(obj, cr, num);
162 for (i = 0; i < num; i++) 154 for (i = 0; i < num; i++)
163 p += iotlb_dump_cr(obj, cr + i, p); 155 iotlb_dump_cr(obj, cr + i, s);
164 kfree(cr); 156 kfree(cr);
165 157
166 return p - buf; 158 return 0;
167} 159}
168 160
169static ssize_t debug_read_tlb(struct file *file, char __user *userbuf, 161static int debug_read_tlb(struct seq_file *s, void *data)
170 size_t count, loff_t *ppos)
171{ 162{
172 struct omap_iommu *obj = file->private_data; 163 struct omap_iommu *obj = s->private;
173 char *p, *buf;
174 ssize_t bytes, rest;
175 164
176 if (is_omap_iommu_detached(obj)) 165 if (is_omap_iommu_detached(obj))
177 return -EPERM; 166 return -EPERM;
178 167
179 buf = kmalloc(count, GFP_KERNEL);
180 if (!buf)
181 return -ENOMEM;
182 p = buf;
183
184 mutex_lock(&iommu_debug_lock); 168 mutex_lock(&iommu_debug_lock);
185 169
186 p += sprintf(p, "%8s %8s\n", "cam:", "ram:"); 170 seq_printf(s, "%8s %8s\n", "cam:", "ram:");
187 p += sprintf(p, "-----------------------------------------\n"); 171 seq_puts(s, "-----------------------------------------\n");
188 rest = count - (p - buf); 172 omap_dump_tlb_entries(obj, s);
189 p += omap_dump_tlb_entries(obj, p, rest);
190
191 bytes = simple_read_from_buffer(userbuf, count, ppos, buf, p - buf);
192 173
193 mutex_unlock(&iommu_debug_lock); 174 mutex_unlock(&iommu_debug_lock);
194 kfree(buf);
195 175
196 return bytes; 176 return 0;
197} 177}
198 178
199static void dump_ioptable(struct seq_file *s) 179static void dump_ioptable(struct seq_file *s)
@@ -268,7 +248,7 @@ static int debug_read_pagetable(struct seq_file *s, void *data)
268 } 248 }
269 249
270DEBUG_FOPS_RO(regs); 250DEBUG_FOPS_RO(regs);
271DEBUG_FOPS_RO(tlb); 251DEBUG_SEQ_FOPS_RO(tlb);
272DEBUG_SEQ_FOPS_RO(pagetable); 252DEBUG_SEQ_FOPS_RO(pagetable);
273 253
274#define __DEBUG_ADD_FILE(attr, mode) \ 254#define __DEBUG_ADD_FILE(attr, mode) \