Commit 4e03b6969f71e0ea113236aa50cba852e14a4e45

Authored by Salva Peiró
Committed by Suman Anna
1 parent ffd06e9cec

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

[ Upstream commit e203db293863fa15b4b1917d4398fb5bd63c4e88 ]

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>
[s-anna@ti.com: cherry-pick commit 'e203db293863' from v4.3]
Signed-off-by: Suman Anna <s-anna@ti.com>

Showing 1 changed file with 14 additions and 34 deletions Side-by-side Diff

drivers/iommu/omap-iommu-debug.c
... ... @@ -133,26 +133,18 @@
133 133 }
134 134  
135 135 static 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;
139   -
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;
  138 + return seq_printf(s, "%08x %08x %01x\n", cr->cam, cr->ram,
  139 + (cr->cam & MMU_CAM_P) ? 1 : 0);
145 140 }
146 141  
147   -static size_t omap_dump_tlb_entries(struct omap_iommu *obj, char *buf,
148   - ssize_t bytes)
  142 +static size_t omap_dump_tlb_entries(struct omap_iommu *obj, struct seq_file *s)
149 143 {
150 144 int i, num;
151 145 struct cr_regs *cr;
152   - char *p = buf;
153 146  
154   - num = bytes / sizeof(*cr);
155   - num = min(obj->nr_tlb_entries, num);
  147 + num = obj->nr_tlb_entries;
156 148  
157 149 cr = kcalloc(num, sizeof(*cr), GFP_KERNEL);
158 150 if (!cr)
159 151  
160 152  
161 153  
162 154  
163 155  
164 156  
165 157  
166 158  
... ... @@ -160,40 +152,28 @@
160 152  
161 153 num = __dump_tlb_entries(obj, cr, num);
162 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 156 kfree(cr);
165 157  
166   - return p - buf;
  158 + return 0;
167 159 }
168 160  
169   -static ssize_t debug_read_tlb(struct file *file, char __user *userbuf,
170   - size_t count, loff_t *ppos)
  161 +static int debug_read_tlb(struct seq_file *s, void *data)
171 162 {
172   - struct omap_iommu *obj = file->private_data;
173   - char *p, *buf;
174   - ssize_t bytes, rest;
  163 + struct omap_iommu *obj = s->private;
175 164  
176 165 if (is_omap_iommu_detached(obj))
177 166 return -EPERM;
178 167  
179   - buf = kmalloc(count, GFP_KERNEL);
180   - if (!buf)
181   - return -ENOMEM;
182   - p = buf;
183   -
184 168 mutex_lock(&iommu_debug_lock);
185 169  
186   - p += sprintf(p, "%8s %8s\n", "cam:", "ram:");
187   - p += sprintf(p, "-----------------------------------------\n");
188   - rest = count - (p - buf);
189   - p += omap_dump_tlb_entries(obj, p, rest);
  170 + seq_printf(s, "%8s %8s\n", "cam:", "ram:");
  171 + seq_puts(s, "-----------------------------------------\n");
  172 + omap_dump_tlb_entries(obj, s);
190 173  
191   - bytes = simple_read_from_buffer(userbuf, count, ppos, buf, p - buf);
192   -
193 174 mutex_unlock(&iommu_debug_lock);
194   - kfree(buf);
195 175  
196   - return bytes;
  176 + return 0;
197 177 }
198 178  
199 179 static void dump_ioptable(struct seq_file *s)
... ... @@ -268,7 +248,7 @@
268 248 }
269 249  
270 250 DEBUG_FOPS_RO(regs);
271   -DEBUG_FOPS_RO(tlb);
  251 +DEBUG_SEQ_FOPS_RO(tlb);
272 252 DEBUG_SEQ_FOPS_RO(pagetable);
273 253  
274 254 #define __DEBUG_ADD_FILE(attr, mode) \