aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media
diff options
context:
space:
mode:
authorDuncan Sands <duncan.sands@math.u-psud.fr>2006-02-26 22:09:48 -0500
committerMauro Carvalho Chehab <mchehab@infradead.org>2006-02-26 22:09:48 -0500
commit4a287cfeea7056dc71d2bc352ae490a2a5bcceb0 (patch)
tree627c7b3c8d893f02d79f3a57b400ecaa2dcbde8d /drivers/media
parent6457af5f7eac49ff8e072fdc98c986d4ac874b04 (diff)
V4L/DVB (3394): Bttv: correct bttv_risc_packed buffer size
This patch fixes the strange crashes I was seeing after using bttv card, caused by a buffer overflow in bttv_risc_packed. The instruction buffer size calculation contains two errors: (a) a non-zero padding value can push the start of the next bpl section to just before a page border, leading to more scanline splits and thus additional instructions. (b) the first DMA region can be smaller than one page, so there can be a scanline split even if bpl*lines is smaller than PAGE_SIZE. For example, consider the case where offset is 0, bpl is 2, padding is 4094, lines is smaller than 2048, the first DMA region has size 1 and all others have size PAGE_SIZE, assumed to equal 4096. Then all bpl regions cross page borders and the number of instructions written is 2*lines+2, rather than lines+2 (the current estimate). With this patch the number of instructions for this example is estimated to be 2*lines+3. Also, the BUG_ON that was supposed to catch buffer overflows contained a thinko causing it fire only if the buffer was overrun by a factor of 16 or more, so it fixes the the BUG_ON's (using sizeof rather than "4"). Signed-off-by: Duncan Sands <baldrick@free.fr> Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers/media')
-rw-r--r--drivers/media/video/bttv-risc.c12
-rw-r--r--drivers/media/video/cx88/cx88-core.c4
2 files changed, 9 insertions, 7 deletions
diff --git a/drivers/media/video/bttv-risc.c b/drivers/media/video/bttv-risc.c
index b40e9734bf08..a60c211c9e31 100644
--- a/drivers/media/video/bttv-risc.c
+++ b/drivers/media/video/bttv-risc.c
@@ -51,8 +51,10 @@ bttv_risc_packed(struct bttv *btv, struct btcx_riscmem *risc,
51 int rc; 51 int rc;
52 52
53 /* estimate risc mem: worst case is one write per page border + 53 /* estimate risc mem: worst case is one write per page border +
54 one write per scan line + sync + jump (all 2 dwords) */ 54 one write per scan line + sync + jump (all 2 dwords). padding
55 instructions = (bpl * lines) / PAGE_SIZE + lines; 55 can cause next bpl to start close to a page border. First DMA
56 region may be smaller than PAGE_SIZE */
57 instructions = 1 + ((bpl + padding) * lines) / PAGE_SIZE + lines;
56 instructions += 2; 58 instructions += 2;
57 if ((rc = btcx_riscmem_alloc(btv->c.pci,risc,instructions*8)) < 0) 59 if ((rc = btcx_riscmem_alloc(btv->c.pci,risc,instructions*8)) < 0)
58 return rc; 60 return rc;
@@ -104,7 +106,7 @@ bttv_risc_packed(struct bttv *btv, struct btcx_riscmem *risc,
104 106
105 /* save pointer to jmp instruction address */ 107 /* save pointer to jmp instruction address */
106 risc->jmp = rp; 108 risc->jmp = rp;
107 BUG_ON((risc->jmp - risc->cpu + 2) / 4 > risc->size); 109 BUG_ON((risc->jmp - risc->cpu + 2) * sizeof(*risc->cpu) > risc->size);
108 return 0; 110 return 0;
109} 111}
110 112
@@ -222,7 +224,7 @@ bttv_risc_planar(struct bttv *btv, struct btcx_riscmem *risc,
222 224
223 /* save pointer to jmp instruction address */ 225 /* save pointer to jmp instruction address */
224 risc->jmp = rp; 226 risc->jmp = rp;
225 BUG_ON((risc->jmp - risc->cpu + 2) / 4 > risc->size); 227 BUG_ON((risc->jmp - risc->cpu + 2) * sizeof(*risc->cpu) > risc->size);
226 return 0; 228 return 0;
227} 229}
228 230
@@ -307,7 +309,7 @@ bttv_risc_overlay(struct bttv *btv, struct btcx_riscmem *risc,
307 309
308 /* save pointer to jmp instruction address */ 310 /* save pointer to jmp instruction address */
309 risc->jmp = rp; 311 risc->jmp = rp;
310 BUG_ON((risc->jmp - risc->cpu + 2) / 4 > risc->size); 312 BUG_ON((risc->jmp - risc->cpu + 2) * sizeof(*risc->cpu) > risc->size);
311 kfree(skips); 313 kfree(skips);
312 return 0; 314 return 0;
313} 315}
diff --git a/drivers/media/video/cx88/cx88-core.c b/drivers/media/video/cx88/cx88-core.c
index eda7cd8b2d4a..25be3a976d09 100644
--- a/drivers/media/video/cx88/cx88-core.c
+++ b/drivers/media/video/cx88/cx88-core.c
@@ -163,7 +163,7 @@ int cx88_risc_buffer(struct pci_dev *pci, struct btcx_riscmem *risc,
163 163
164 /* save pointer to jmp instruction address */ 164 /* save pointer to jmp instruction address */
165 risc->jmp = rp; 165 risc->jmp = rp;
166 BUG_ON((risc->jmp - risc->cpu + 2) / 4 > risc->size); 166 BUG_ON((risc->jmp - risc->cpu + 2) * sizeof (*risc->cpu) > risc->size);
167 return 0; 167 return 0;
168} 168}
169 169
@@ -188,7 +188,7 @@ int cx88_risc_databuffer(struct pci_dev *pci, struct btcx_riscmem *risc,
188 188
189 /* save pointer to jmp instruction address */ 189 /* save pointer to jmp instruction address */
190 risc->jmp = rp; 190 risc->jmp = rp;
191 BUG_ON((risc->jmp - risc->cpu + 2) / 4 > risc->size); 191 BUG_ON((risc->jmp - risc->cpu + 2) * sizeof (*risc->cpu) > risc->size);
192 return 0; 192 return 0;
193} 193}
194 194