[PATCH] omap-crypto - fix kernel oops and output buffer update

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hello,
In omap_crypto_cleanup(),:
        if (orig && (flags & OMAP_CRYPTO_COPY_MASK))
            scatterwalk_map_and_copy(buf, orig, offset, len, 1);
implies that scatterwalk_map_and_copy() is called if flag is set to OMAP_CRYPTO_SG_COPIED. If the output buffer crosses a page boundary, the second and subsequent pages are overwritten.
The test should be : if(orig && (flags & OMAP_CRYPTO_DATA_COPIED))

The variable buf is always assigned but not used if flags == OMAP_CRYPTO_SG_COPIED.
In:
        buf = sg_virt(sg);
sg_page(sg) can be NULL, leading to a kernel crash:

    [   37.624352] Unable to handle kernel NULL pointer dereference at virtual address 00000000
    [   37.632502] pgd = ec150000
    [   37.635238] [00000000] *pgd=00000000
    [   37.638842] Internal error: Oops: 5 [#1] SMP ARM

    Entering kdb (current=0xec173080, pid 1125) on processor 0 Oops: (null)
    due to oops @ 0xc02c04f4
    CPU: 0 PID: 1125 Comm: ping Tainted: G         C 4.14.13-ti-r25 #62
    Hardware name: Generic DRA74X (Flattened Device Tree)
    task: ec173080 task.stack: ec0a8000
    PC is at pa> <ge_address+0x18/0xf4
    LR is at omap_crypto_cleanup+0x44/0x110
    pc : [<c02c04f4>]    lr : [<c0b33b78>]    psr: 40080113
    sp : ec0a9cf8  ip : ec0a9d20  fp : ec0a9d1c
    r10: 00000000  r9 : ec1918c0  r8 : 00000100
    r7 : 0000000a  r6 : ec0c6780  r5 : 00000000  r4 : 00000002
    r3 : 00000100  r2 : 00000000  r1 : ec1918c0  r0 : 00000000
    Flags: nZcv  IRQs on  FIQs on  Mode SVC_32  ISA ARM Segment none
    Control: 10c5387d  Table: ac15006a  DAC: 00000051
    CPU: 0 PID: 1125 Comm: ping Tainted: G         C 4.14.13-ti-r25 #62
    Hardware name: Generic DRA74X (Flattened Device Tree)

    [<c0d87df8>] (__dabt_svc) from [<c02c04f4>] (page_address+0x18/0xf4)
    [<c02c04f4>] (page_address) from [<c0b33b78>] (omap_crypto_cleanup+0x44/0x110)     [<c0b33b78>] (omap_crypto_cleanup) from [<c0b371f4>] (omap_aes_done_task+0x1a0/0x440)     [<c0b371f4>] (omap_aes_done_task) from [<c0149388>] (tasklet_action+0x70/0x104)     [<c0149388>] (tasklet_action) from [<c0101704>] (__do_softirq+0x124/0x378)
    [<c0101704>] (__do_softirq) from [<c0148d68>] (irq_exit+0xe8/0x150)
    [<c0148d68>] (irq_exit) from [<c01acd5c>] (__handle_domain_irq+0x70/0xc4)     [<c01acd5c>] (__handle_domain_irq) from [<c01015a0>] (gic_handle_irq+0x4c/0x88)
    [<c01015a0>] (gic_handle_irq) from [<c0d87e8c>] (__irq_svc+0x6c/0x90)

Here it is simpler to reorder the code to fix the issues.


Signed-off-by: Francis Le Bourse<francis.lebourse@xxxxxx>                                                         
---
 drivers/crypto/omap-crypto.c       | 24 +++++++++++-----------
 1 file changed, 12 insertions(+), 12 deletions(-)

diff --git a/drivers/crypto/omap-crypto.c b/drivers/crypto/omap-crypto.c
index 2c42e4b..5056c4b 100644
--- a/drivers/crypto/omap-crypto.c
+++ b/drivers/crypto/omap-crypto.c
@@ -161,24 +161,24 @@ void omap_crypto_cleanup(struct scatterlist *sg, struct scatterlist *orig,
 			 int offset, int len, u8 flags_shift,
 			 unsigned long flags)
 {
-	void *buf;
-	int pages;
-
 	flags >>= flags_shift;
-	flags &= OMAP_CRYPTO_COPY_MASK;
 
-	if (!flags)
-		return;
+	if (flags & OMAP_CRYPTO_DATA_COPIED) {
+		void *buf;
+		int pages;
 
-	buf = sg_virt(sg);
-	pages = get_order(len);
+		if (WARN_ON(sg_page(sg) == NULL))
+			return;
 
-	if (orig && (flags & OMAP_CRYPTO_COPY_MASK))
-		scatterwalk_map_and_copy(buf, orig, offset, len, 1);
+		buf = sg_virt(sg);
+		pages = get_order(len);
 
-	if (flags & OMAP_CRYPTO_DATA_COPIED)
+		if (orig)
+			scatterwalk_map_and_copy(buf, orig, offset, len, 1);
 		free_pages((unsigned long)buf, pages);
-	else if (flags & OMAP_CRYPTO_SG_COPIED)
+	}
+
+	if (flags & OMAP_CRYPTO_SG_COPIED)
 		kfree(sg);
 }
 EXPORT_SYMBOL_GPL(omap_crypto_cleanup);

[Index of Archives]     [Kernel]     [Gnu Classpath]     [Gnu Crypto]     [DM Crypt]     [Netfilter]     [Bugtraq]

  Powered by Linux