Hi: The various state destroy functions will crash when called on a state where the init_state function failed. This patch fixes it by checking x->data where appropriate. Cheers, -- Debian GNU/Linux 3.0 is out! ( http://www.debian.org/ ) Email: Herbert Xu ~{PmV>HI~} <herbert@gondor.apana.org.au> Home Page: http://gondor.apana.org.au/~herbert/ PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
Index: kernel-source-2.5/net/ipv4/ah4.c =================================================================== RCS file: /home/gondolin/herbert/src/CVS/debian/kernel-source-2.5/net/ipv4/ah4.c,v retrieving revision 1.3 diff -u -r1.3 ah4.c --- kernel-source-2.5/net/ipv4/ah4.c 29 Jul 2003 11:11:34 -0000 1.3 +++ kernel-source-2.5/net/ipv4/ah4.c 18 Aug 2003 10:50:50 -0000 @@ -308,6 +308,9 @@ { struct ah_data *ahp = x->data; + if (!ahp) + return; + if (ahp->work_icv) { kfree(ahp->work_icv); ahp->work_icv = NULL; Index: kernel-source-2.5/net/ipv4/esp4.c =================================================================== RCS file: /home/gondolin/herbert/src/CVS/debian/kernel-source-2.5/net/ipv4/esp4.c,v retrieving revision 1.3 diff -u -r1.3 esp4.c --- kernel-source-2.5/net/ipv4/esp4.c 29 Jul 2003 11:11:34 -0000 1.3 +++ kernel-source-2.5/net/ipv4/esp4.c 18 Aug 2003 10:50:34 -0000 @@ -437,6 +437,9 @@ { struct esp_data *esp = x->data; + if (!esp) + return; + if (esp->conf.tfm) { crypto_free_tfm(esp->conf.tfm); esp->conf.tfm = NULL; Index: kernel-source-2.5/net/ipv4/ipcomp.c =================================================================== RCS file: /home/gondolin/herbert/src/CVS/debian/kernel-source-2.5/net/ipv4/ipcomp.c,v retrieving revision 1.5 diff -u -r1.5 ipcomp.c --- kernel-source-2.5/net/ipv4/ipcomp.c 9 Aug 2003 03:42:54 -0000 1.5 +++ kernel-source-2.5/net/ipv4/ipcomp.c 18 Aug 2003 10:56:48 -0000 @@ -336,6 +336,8 @@ static void ipcomp_destroy(struct xfrm_state *x) { struct ipcomp_data *ipcd = x->data; + if (!ipcd) + return; ipcomp_free_data(ipcd); kfree(ipcd); } @@ -354,7 +356,6 @@ x->props.header_len = sizeof(struct ip_comp_hdr); if (x->props.mode) x->props.header_len += sizeof(struct iphdr); - x->data = ipcd; ipcd->scratch = kmalloc(IPCOMP_SCRATCH_SIZE, GFP_KERNEL); if (!ipcd->scratch) @@ -373,6 +374,7 @@ calg_desc = xfrm_calg_get_byname(x->calg->alg_name); BUG_ON(!calg_desc); ipcd->threshold = calg_desc->uinfo.comp.threshold; + x->data = ipcd; err = 0; out: return err; Index: kernel-source-2.5/net/ipv6/ah6.c =================================================================== RCS file: /home/gondolin/herbert/src/CVS/debian/kernel-source-2.5/net/ipv6/ah6.c,v retrieving revision 1.3 diff -u -r1.3 ah6.c --- kernel-source-2.5/net/ipv6/ah6.c 29 Jul 2003 11:11:34 -0000 1.3 +++ kernel-source-2.5/net/ipv6/ah6.c 18 Aug 2003 10:54:29 -0000 @@ -442,6 +442,9 @@ { struct ah_data *ahp = x->data; + if (!ahp) + return; + if (ahp->work_icv) { kfree(ahp->work_icv); ahp->work_icv = NULL; Index: kernel-source-2.5/net/ipv6/esp6.c =================================================================== RCS file: /home/gondolin/herbert/src/CVS/debian/kernel-source-2.5/net/ipv6/esp6.c,v retrieving revision 1.4 diff -u -r1.4 esp6.c --- kernel-source-2.5/net/ipv6/esp6.c 9 Aug 2003 11:29:21 -0000 1.4 +++ kernel-source-2.5/net/ipv6/esp6.c 18 Aug 2003 10:54:17 -0000 @@ -342,6 +342,9 @@ { struct esp_data *esp = x->data; + if (!esp) + return; + if (esp->conf.tfm) { crypto_free_tfm(esp->conf.tfm); esp->conf.tfm = NULL; Index: kernel-source-2.5/net/ipv6/ipcomp6.c =================================================================== RCS file: /home/gondolin/herbert/src/CVS/debian/kernel-source-2.5/net/ipv6/ipcomp6.c,v retrieving revision 1.3 diff -u -r1.3 ipcomp6.c --- kernel-source-2.5/net/ipv6/ipcomp6.c 29 Jul 2003 11:11:34 -0000 1.3 +++ kernel-source-2.5/net/ipv6/ipcomp6.c 18 Aug 2003 10:56:09 -0000 @@ -268,6 +268,8 @@ static void ipcomp6_destroy(struct xfrm_state *x) { struct ipcomp_data *ipcd = x->data; + if (!ipcd) + return; ipcomp6_free_data(ipcd); kfree(ipcd); } @@ -286,7 +288,6 @@ x->props.header_len = sizeof(struct ipv6_comp_hdr); if (x->props.mode) x->props.header_len += sizeof(struct ipv6hdr); - x->data = ipcd; ipcd->scratch = kmalloc(IPCOMP_SCRATCH_SIZE, GFP_KERNEL); if (!ipcd->scratch) @@ -299,6 +300,7 @@ calg_desc = xfrm_calg_get_byname(x->calg->alg_name); BUG_ON(!calg_desc); ipcd->threshold = calg_desc->uinfo.comp.threshold; + x->data = ipcd; err = 0; out: return err;