diff options
author | Duncan Sands <duncan.sands@math.u-psud.fr> | 2006-02-26 22:09:48 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@infradead.org> | 2006-02-26 22:09:48 -0500 |
commit | 4a287cfeea7056dc71d2bc352ae490a2a5bcceb0 (patch) | |
tree | 627c7b3c8d893f02d79f3a57b400ecaa2dcbde8d /drivers/media/video | |
parent | 6457af5f7eac49ff8e072fdc98c986d4ac874b04 (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/video')
-rw-r--r-- | drivers/media/video/bttv-risc.c | 12 | ||||
-rw-r--r-- | drivers/media/video/cx88/cx88-core.c | 4 |
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 | ||