diff options
Diffstat (limited to 'recipes-kernel')
53 files changed, 5549 insertions, 0 deletions
diff --git a/recipes-kernel/asf/asf_git.bb b/recipes-kernel/asf/asf_git.bb new file mode 100644 index 0000000..8070f5a --- /dev/null +++ b/recipes-kernel/asf/asf_git.bb | |||
@@ -0,0 +1,29 @@ | |||
1 | DESCRIPTION = "Non-DPAA software Application Specific Fast-path" | ||
2 | SECTION = "asf" | ||
3 | LICENSE = "GPLv2 & GPLv2+ & BSD" | ||
4 | LIC_FILES_CHKSUM = "file://COPYING;md5=b5881ecf398da8a03a3f4c501e29d287" | ||
5 | |||
6 | SRC_URI = "git://git.freescale.com/ppc/sdk/asf.git;nobranch=1" | ||
7 | SRCREV = "16eb472d6b2b34c8b605a86c469611bc8ddec1c9" | ||
8 | |||
9 | |||
10 | inherit module qoriq_build_64bit_kernel | ||
11 | |||
12 | S = "${WORKDIR}/git/asfmodule" | ||
13 | |||
14 | EXTRA_OEMAKE = "CROSS_COMPILE=${TARGET_PREFIX}" | ||
15 | export KERNEL_PATH = "${STAGING_KERNEL_DIR}" | ||
16 | |||
17 | INHIBIT_PACKAGE_STRIP = "1" | ||
18 | |||
19 | do_install(){ | ||
20 | install -d ${D}/${libexecdir} | ||
21 | install -d ${D}/lib/modules/${KERNEL_VERSION}/asf | ||
22 | cp -rf ${S}/bin/full ${D}/lib/modules/${KERNEL_VERSION}/asf | ||
23 | cp -rf ${S}/bin/min ${D}/lib/modules/${KERNEL_VERSION}/asf | ||
24 | cp -rf ${S}/../scripts ${D}/${libexecdir}/ | ||
25 | } | ||
26 | |||
27 | FILES_${PN} += "${libexecdir} /lib/modules/${KERNEL_VERSION}/asf" | ||
28 | RDEPENDS_${PN} += "ipsec-tools" | ||
29 | |||
diff --git a/recipes-kernel/auto-resp/ar_git.bb b/recipes-kernel/auto-resp/ar_git.bb new file mode 100644 index 0000000..81a94a0 --- /dev/null +++ b/recipes-kernel/auto-resp/ar_git.bb | |||
@@ -0,0 +1,25 @@ | |||
1 | SUMMARY = "Auto Response Control Module" | ||
2 | LICENSE = "GPLv2 & BSD" | ||
3 | LIC_FILES_CHKSUM = "file://COPYING;md5=b5881ecf398da8a03a3f4c501e29d287" | ||
4 | |||
5 | inherit module | ||
6 | |||
7 | SRC_URI = "git://git.freescale.com/ppc/sdk/auto-resp.git;branch=sdk-v1.7.x" | ||
8 | SRCREV = "dbede76fb4020a370baa393f7c53af4c0db8f175" | ||
9 | |||
10 | S = "${WORKDIR}/git" | ||
11 | |||
12 | EXTRA_OEMAKE = "CROSS_COMPILE=${TARGET_PREFIX} SYSROOT=${STAGING_DIR_TARGET}" | ||
13 | export KERNEL_PATH | ||
14 | |||
15 | INHIBIT_PACKAGE_STRIP = "1" | ||
16 | |||
17 | do_install(){ | ||
18 | install -d ${D}/lib/modules/${KERNEL_VERSION} | ||
19 | install -d ${D}${bindir} | ||
20 | install -m 644 ${B}/bin/ar.ko ${D}/lib/modules/${KERNEL_VERSION}/ | ||
21 | cp -f ${S}/bin/ar_* ${D}${bindir}/ | ||
22 | } | ||
23 | |||
24 | FILES_${PN} += "${bindir}/" | ||
25 | |||
diff --git a/recipes-kernel/ceetm/ceetm_git.bb b/recipes-kernel/ceetm/ceetm_git.bb new file mode 100644 index 0000000..266261e --- /dev/null +++ b/recipes-kernel/ceetm/ceetm_git.bb | |||
@@ -0,0 +1,25 @@ | |||
1 | DESCRIPTION = "CEETM TC QDISC" | ||
2 | LICENSE = "GPLv2 & BSD" | ||
3 | LIC_FILES_CHKSUM = "file://COPYING;md5=b5881ecf398da8a03a3f4c501e29d287" | ||
4 | |||
5 | DEPENDS="virtual/kernel" | ||
6 | |||
7 | inherit module qoriq_build_64bit_kernel | ||
8 | |||
9 | SRC_URI = "git://git.freescale.com/ppc/sdk/ceetm.git;nobranch=1" | ||
10 | SRCREV = "ecf55c9ca0cd42a212653e1f99c19cd611e3a008" | ||
11 | |||
12 | S = "${WORKDIR}/git" | ||
13 | |||
14 | EXTRA_OEMAKE = "CROSS_COMPILE=${TARGET_PREFIX} SYSROOT=${STAGING_DIR_TARGET}" | ||
15 | export KERNEL_PATH = "${STAGING_KERNEL_DIR}" | ||
16 | |||
17 | do_install(){ | ||
18 | mkdir -p ${D}/usr/driver/ceetm | ||
19 | mkdir -p ${D}/${libdir}/tc | ||
20 | cp ${S}/bin/ceetm.ko ${D}/usr/driver/ceetm | ||
21 | cp ${S}/bin/q_ceetm.so ${D}/${libdir}/tc/. | ||
22 | } | ||
23 | |||
24 | FILES_${PN} += "/usr/driver/ceetm ${libdir}/tc" | ||
25 | INHIBIT_PACKAGE_STRIP = "1" | ||
diff --git a/recipes-kernel/cryptodev/cryptodev-fsl.inc b/recipes-kernel/cryptodev/cryptodev-fsl.inc new file mode 100644 index 0000000..e32e350 --- /dev/null +++ b/recipes-kernel/cryptodev/cryptodev-fsl.inc | |||
@@ -0,0 +1,17 @@ | |||
1 | FILESEXTRAPATHS_prepend := "${THISDIR}/cryptodev-fsl:" | ||
2 | |||
3 | SRC_URI_qoriq-ppc = "git://github.com/cryptodev-linux/cryptodev-linux.git \ | ||
4 | file://0001-add-support-for-composite-TLS10-SHA1-AES-algorithm-o.patch \ | ||
5 | file://0002-add-support-for-COMPAT_CIOCAUTHCRYPT-ioctl.patch \ | ||
6 | file://0003-PKC-support-added-in-cryptodev-module.patch \ | ||
7 | file://0004-Compat-versions-of-PKC-IOCTLs.patch \ | ||
8 | file://0005-Asynchronous-interface-changes-in-cryptodev.patch \ | ||
9 | file://0006-ECC_KEYGEN-and-DLC_KEYGEN-supported-in-cryptodev-mod.patch \ | ||
10 | file://0007-RCU-stall-fixed-in-PKC-asynchronous-interface.patch \ | ||
11 | file://0008-Add-RSA-Key-generation-offloading.patch \ | ||
12 | file://0009-Fixed-compilation-error-of-openssl-with-fsl-cryptode.patch \ | ||
13 | " | ||
14 | SRCREV_qoriq-ppc = "6aa62a2c320b04f55fdfe0ed015c3d9b48997239" | ||
15 | |||
16 | S_qoriq-ppc = "${WORKDIR}/git" | ||
17 | |||
diff --git a/recipes-kernel/cryptodev/cryptodev-fsl/0001-add-support-for-composite-TLS10-SHA1-AES-algorithm-o.patch b/recipes-kernel/cryptodev/cryptodev-fsl/0001-add-support-for-composite-TLS10-SHA1-AES-algorithm-o.patch new file mode 100644 index 0000000..796e548 --- /dev/null +++ b/recipes-kernel/cryptodev/cryptodev-fsl/0001-add-support-for-composite-TLS10-SHA1-AES-algorithm-o.patch | |||
@@ -0,0 +1,52 @@ | |||
1 | From 715ade8236f40cf811c39f9538dfd60803967fcd Mon Sep 17 00:00:00 2001 | ||
2 | From: Cristian Stoica <cristian.stoica@freescale.com> | ||
3 | Date: Thu, 29 Aug 2013 16:52:30 +0300 | ||
4 | Subject: [PATCH 1/9] add support for composite TLS10(SHA1,AES) algorithm | ||
5 | offload | ||
6 | |||
7 | This adds support for composite algorithm offload as a primitive | ||
8 | crypto (cipher + hmac) operation. | ||
9 | |||
10 | It requires kernel support for tls10(hmac(sha1),cbc(aes)) algorithm | ||
11 | provided either in software or accelerated by hardware such as | ||
12 | Freescale B*, P* and T* platforms. | ||
13 | |||
14 | Change-Id: Ia1c605da3860e91e681295dfc8df7c09eb4006cf | ||
15 | Signed-off-by: Cristian Stoica <cristian.stoica@freescale.com> | ||
16 | Reviewed-on: http://git.am.freescale.net:8181/17218 | ||
17 | --- | ||
18 | crypto/cryptodev.h | 1 + | ||
19 | ioctl.c | 5 +++++ | ||
20 | 2 files changed, 6 insertions(+) | ||
21 | |||
22 | diff --git a/crypto/cryptodev.h b/crypto/cryptodev.h | ||
23 | index 7fb9c7d..c0e8cd4 100644 | ||
24 | --- a/crypto/cryptodev.h | ||
25 | +++ b/crypto/cryptodev.h | ||
26 | @@ -50,6 +50,7 @@ enum cryptodev_crypto_op_t { | ||
27 | CRYPTO_SHA2_384, | ||
28 | CRYPTO_SHA2_512, | ||
29 | CRYPTO_SHA2_224_HMAC, | ||
30 | + CRYPTO_TLS10_AES_CBC_HMAC_SHA1, | ||
31 | CRYPTO_ALGORITHM_ALL, /* Keep updated - see below */ | ||
32 | }; | ||
33 | |||
34 | diff --git a/ioctl.c b/ioctl.c | ||
35 | index 5a55a76..f9b9b2e 100644 | ||
36 | --- a/ioctl.c | ||
37 | +++ b/ioctl.c | ||
38 | @@ -159,6 +159,11 @@ crypto_create_session(struct fcrypt *fcr, struct session_op *sop) | ||
39 | stream = 1; | ||
40 | aead = 1; | ||
41 | break; | ||
42 | + case CRYPTO_TLS10_AES_CBC_HMAC_SHA1: | ||
43 | + alg_name = "tls10(hmac(sha1),cbc(aes))"; | ||
44 | + stream = 0; | ||
45 | + aead = 1; | ||
46 | + break; | ||
47 | case CRYPTO_NULL: | ||
48 | alg_name = "ecb(cipher_null)"; | ||
49 | stream = 1; | ||
50 | -- | ||
51 | 1.8.3.1 | ||
52 | |||
diff --git a/recipes-kernel/cryptodev/cryptodev-fsl/0001-don-t-advertise-RSA-keygen.patch b/recipes-kernel/cryptodev/cryptodev-fsl/0001-don-t-advertise-RSA-keygen.patch new file mode 100644 index 0000000..3d7c608 --- /dev/null +++ b/recipes-kernel/cryptodev/cryptodev-fsl/0001-don-t-advertise-RSA-keygen.patch | |||
@@ -0,0 +1,32 @@ | |||
1 | From b6e2a3747e3cffdf3cc515b0ce35d6bcdcb051c5 Mon Sep 17 00:00:00 2001 | ||
2 | From: Cristian Stoica <cristian.stoica@freescale.com> | ||
3 | Date: Tue, 9 Dec 2014 16:41:25 +0200 | ||
4 | Subject: [PATCH] don't advertise RSA keygen | ||
5 | |||
6 | This is supposed to avoid RSA keygen operations when they are not | ||
7 | available. Since no testing can be done, the patch should be applied | ||
8 | selectively (for example when offloading through pkc driver on C293) | ||
9 | |||
10 | Change-Id: I60765f46fd7a39053d42e075d2ec71b032b2ed8a | ||
11 | Signed-off-by: Cristian Stoica <cristian.stoica@freescale.com> | ||
12 | --- | ||
13 | ioctl.c | 3 +-- | ||
14 | 1 file changed, 1 insertion(+), 2 deletions(-) | ||
15 | |||
16 | diff --git a/ioctl.c b/ioctl.c | ||
17 | index e907167..3239093 100644 | ||
18 | --- a/ioctl.c | ||
19 | +++ b/ioctl.c | ||
20 | @@ -961,8 +961,7 @@ cryptodev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg_) | ||
21 | case CIOCASYMFEAT: | ||
22 | return put_user(CRF_MOD_EXP_CRT | CRF_MOD_EXP | CRF_DSA_SIGN | | ||
23 | CRF_DSA_VERIFY | CRF_DH_COMPUTE_KEY | | ||
24 | - CRF_DSA_GENERATE_KEY | CRF_DH_GENERATE_KEY | | ||
25 | - CRF_RSA_GENERATE_KEY, p); | ||
26 | + CRF_DSA_GENERATE_KEY | CRF_DH_GENERATE_KEY, p); | ||
27 | case CRIOGET: | ||
28 | fd = clonefd(filp); | ||
29 | ret = put_user(fd, p); | ||
30 | -- | ||
31 | 2.2.0 | ||
32 | |||
diff --git a/recipes-kernel/cryptodev/cryptodev-fsl/0002-add-support-for-COMPAT_CIOCAUTHCRYPT-ioctl.patch b/recipes-kernel/cryptodev/cryptodev-fsl/0002-add-support-for-COMPAT_CIOCAUTHCRYPT-ioctl.patch new file mode 100644 index 0000000..086a97f --- /dev/null +++ b/recipes-kernel/cryptodev/cryptodev-fsl/0002-add-support-for-COMPAT_CIOCAUTHCRYPT-ioctl.patch | |||
@@ -0,0 +1,207 @@ | |||
1 | From 4b766c93e4ee19248dd66bbebb61fb5cc9c8a012 Mon Sep 17 00:00:00 2001 | ||
2 | From: Horia Geanta <horia.geanta@freescale.com> | ||
3 | Date: Wed, 4 Dec 2013 15:43:41 +0200 | ||
4 | Subject: [PATCH 2/9] add support for COMPAT_CIOCAUTHCRYPT ioctl() | ||
5 | |||
6 | Upstream-status: Pending | ||
7 | |||
8 | Needed for 64b kernel with 32b user space. | ||
9 | |||
10 | Change-Id: I44a999a4164e7ae7122dee6ed0716b2f25cadbc1 | ||
11 | Signed-off-by: Horia Geanta <horia.geanta@freescale.com> | ||
12 | Tested-by: Cristian Stoica <cristian.stoica@freescale.com> | ||
13 | --- | ||
14 | authenc.c | 78 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ | ||
15 | cryptodev_int.h | 40 +++++++++++++++++++++++++++++ | ||
16 | ioctl.c | 16 ++++++++++++ | ||
17 | 3 files changed, 134 insertions(+) | ||
18 | |||
19 | diff --git a/authenc.c b/authenc.c | ||
20 | index 1bd7377..ef0d3db 100644 | ||
21 | --- a/authenc.c | ||
22 | +++ b/authenc.c | ||
23 | @@ -272,6 +272,84 @@ static int fill_caop_from_kcaop(struct kernel_crypt_auth_op *kcaop, struct fcryp | ||
24 | return 0; | ||
25 | } | ||
26 | |||
27 | +/* compatibility code for 32bit userlands */ | ||
28 | +#ifdef CONFIG_COMPAT | ||
29 | + | ||
30 | +static inline void | ||
31 | +compat_to_crypt_auth_op(struct compat_crypt_auth_op *compat, | ||
32 | + struct crypt_auth_op *caop) | ||
33 | +{ | ||
34 | + caop->ses = compat->ses; | ||
35 | + caop->op = compat->op; | ||
36 | + caop->flags = compat->flags; | ||
37 | + caop->len = compat->len; | ||
38 | + caop->auth_len = compat->auth_len; | ||
39 | + caop->tag_len = compat->tag_len; | ||
40 | + caop->iv_len = compat->iv_len; | ||
41 | + | ||
42 | + caop->auth_src = compat_ptr(compat->auth_src); | ||
43 | + caop->src = compat_ptr(compat->src); | ||
44 | + caop->dst = compat_ptr(compat->dst); | ||
45 | + caop->tag = compat_ptr(compat->tag); | ||
46 | + caop->iv = compat_ptr(compat->iv); | ||
47 | +} | ||
48 | + | ||
49 | +static inline void | ||
50 | +crypt_auth_op_to_compat(struct crypt_auth_op *caop, | ||
51 | + struct compat_crypt_auth_op *compat) | ||
52 | +{ | ||
53 | + compat->ses = caop->ses; | ||
54 | + compat->op = caop->op; | ||
55 | + compat->flags = caop->flags; | ||
56 | + compat->len = caop->len; | ||
57 | + compat->auth_len = caop->auth_len; | ||
58 | + compat->tag_len = caop->tag_len; | ||
59 | + compat->iv_len = caop->iv_len; | ||
60 | + | ||
61 | + compat->auth_src = ptr_to_compat(caop->auth_src); | ||
62 | + compat->src = ptr_to_compat(caop->src); | ||
63 | + compat->dst = ptr_to_compat(caop->dst); | ||
64 | + compat->tag = ptr_to_compat(caop->tag); | ||
65 | + compat->iv = ptr_to_compat(caop->iv); | ||
66 | +} | ||
67 | + | ||
68 | +int compat_kcaop_from_user(struct kernel_crypt_auth_op *kcaop, | ||
69 | + struct fcrypt *fcr, void __user *arg) | ||
70 | +{ | ||
71 | + struct compat_crypt_auth_op compat_caop; | ||
72 | + | ||
73 | + if (unlikely(copy_from_user(&compat_caop, arg, sizeof(compat_caop)))) { | ||
74 | + dprintk(1, KERN_ERR, "Error in copying from userspace\n"); | ||
75 | + return -EFAULT; | ||
76 | + } | ||
77 | + | ||
78 | + compat_to_crypt_auth_op(&compat_caop, &kcaop->caop); | ||
79 | + | ||
80 | + return fill_kcaop_from_caop(kcaop, fcr); | ||
81 | +} | ||
82 | + | ||
83 | +int compat_kcaop_to_user(struct kernel_crypt_auth_op *kcaop, | ||
84 | + struct fcrypt *fcr, void __user *arg) | ||
85 | +{ | ||
86 | + int ret; | ||
87 | + struct compat_crypt_auth_op compat_caop; | ||
88 | + | ||
89 | + ret = fill_caop_from_kcaop(kcaop, fcr); | ||
90 | + if (unlikely(ret)) { | ||
91 | + dprintk(1, KERN_ERR, "fill_caop_from_kcaop\n"); | ||
92 | + return ret; | ||
93 | + } | ||
94 | + | ||
95 | + crypt_auth_op_to_compat(&kcaop->caop, &compat_caop); | ||
96 | + | ||
97 | + if (unlikely(copy_to_user(arg, &compat_caop, sizeof(compat_caop)))) { | ||
98 | + dprintk(1, KERN_ERR, "Error in copying to userspace\n"); | ||
99 | + return -EFAULT; | ||
100 | + } | ||
101 | + return 0; | ||
102 | +} | ||
103 | + | ||
104 | +#endif /* CONFIG_COMPAT */ | ||
105 | |||
106 | int kcaop_from_user(struct kernel_crypt_auth_op *kcaop, | ||
107 | struct fcrypt *fcr, void __user *arg) | ||
108 | diff --git a/cryptodev_int.h b/cryptodev_int.h | ||
109 | index d7660fa..8e687e7 100644 | ||
110 | --- a/cryptodev_int.h | ||
111 | +++ b/cryptodev_int.h | ||
112 | @@ -73,11 +73,42 @@ struct compat_crypt_op { | ||
113 | compat_uptr_t iv;/* initialization vector for encryption operations */ | ||
114 | }; | ||
115 | |||
116 | + /* input of CIOCAUTHCRYPT */ | ||
117 | +struct compat_crypt_auth_op { | ||
118 | + uint32_t ses; /* session identifier */ | ||
119 | + uint16_t op; /* COP_ENCRYPT or COP_DECRYPT */ | ||
120 | + uint16_t flags; /* see COP_FLAG_AEAD_* */ | ||
121 | + uint32_t len; /* length of source data */ | ||
122 | + uint32_t auth_len; /* length of auth data */ | ||
123 | + compat_uptr_t auth_src; /* authenticated-only data */ | ||
124 | + | ||
125 | + /* The current implementation is more efficient if data are | ||
126 | + * encrypted in-place (src==dst). */ | ||
127 | + compat_uptr_t src; /* data to be encrypted and | ||
128 | + authenticated */ | ||
129 | + compat_uptr_t dst; /* pointer to output data. Must have | ||
130 | + * space for tag. For TLS this should be | ||
131 | + * at least len + tag_size + block_size | ||
132 | + * for padding */ | ||
133 | + | ||
134 | + compat_uptr_t tag; /* where the tag will be copied to. TLS | ||
135 | + * mode doesn't use that as tag is | ||
136 | + * copied to dst. | ||
137 | + * SRTP mode copies tag there. */ | ||
138 | + uint32_t tag_len; /* the length of the tag. Use zero for | ||
139 | + * digest size or max tag. */ | ||
140 | + | ||
141 | + /* initialization vector for encryption operations */ | ||
142 | + compat_uptr_t iv; | ||
143 | + uint32_t iv_len; | ||
144 | +}; | ||
145 | + | ||
146 | /* compat ioctls, defined for the above structs */ | ||
147 | #define COMPAT_CIOCGSESSION _IOWR('c', 102, struct compat_session_op) | ||
148 | #define COMPAT_CIOCCRYPT _IOWR('c', 104, struct compat_crypt_op) | ||
149 | #define COMPAT_CIOCASYNCCRYPT _IOW('c', 107, struct compat_crypt_op) | ||
150 | #define COMPAT_CIOCASYNCFETCH _IOR('c', 108, struct compat_crypt_op) | ||
151 | +#define COMPAT_CIOCAUTHCRYPT _IOWR('c', 109, struct compat_crypt_auth_op) | ||
152 | |||
153 | #endif /* CONFIG_COMPAT */ | ||
154 | |||
155 | @@ -108,6 +139,15 @@ struct kernel_crypt_auth_op { | ||
156 | |||
157 | /* auth */ | ||
158 | |||
159 | +#ifdef CONFIG_COMPAT | ||
160 | +int compat_kcaop_from_user(struct kernel_crypt_auth_op *kcaop, | ||
161 | + struct fcrypt *fcr, void __user *arg); | ||
162 | + | ||
163 | +int compat_kcaop_to_user(struct kernel_crypt_auth_op *kcaop, | ||
164 | + struct fcrypt *fcr, void __user *arg); | ||
165 | +#endif /* CONFIG_COMPAT */ | ||
166 | + | ||
167 | + | ||
168 | int kcaop_from_user(struct kernel_crypt_auth_op *kcop, | ||
169 | struct fcrypt *fcr, void __user *arg); | ||
170 | int kcaop_to_user(struct kernel_crypt_auth_op *kcaop, | ||
171 | diff --git a/ioctl.c b/ioctl.c | ||
172 | index f9b9b2e..1563c75 100644 | ||
173 | --- a/ioctl.c | ||
174 | +++ b/ioctl.c | ||
175 | @@ -998,6 +998,7 @@ cryptodev_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg_) | ||
176 | struct session_op sop; | ||
177 | struct compat_session_op compat_sop; | ||
178 | struct kernel_crypt_op kcop; | ||
179 | + struct kernel_crypt_auth_op kcaop; | ||
180 | int ret; | ||
181 | |||
182 | if (unlikely(!pcr)) | ||
183 | @@ -1040,6 +1041,21 @@ cryptodev_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg_) | ||
184 | return ret; | ||
185 | |||
186 | return compat_kcop_to_user(&kcop, fcr, arg); | ||
187 | + | ||
188 | + case COMPAT_CIOCAUTHCRYPT: | ||
189 | + if (unlikely(ret = compat_kcaop_from_user(&kcaop, fcr, arg))) { | ||
190 | + dprintk(1, KERN_WARNING, "Error copying from user\n"); | ||
191 | + return ret; | ||
192 | + } | ||
193 | + | ||
194 | + ret = crypto_auth_run(fcr, &kcaop); | ||
195 | + if (unlikely(ret)) { | ||
196 | + dprintk(1, KERN_WARNING, "Error in crypto_auth_run\n"); | ||
197 | + return ret; | ||
198 | + } | ||
199 | + | ||
200 | + return compat_kcaop_to_user(&kcaop, fcr, arg); | ||
201 | + | ||
202 | #ifdef ENABLE_ASYNC | ||
203 | case COMPAT_CIOCASYNCCRYPT: | ||
204 | if (unlikely(ret = compat_kcop_from_user(&kcop, fcr, arg))) | ||
205 | -- | ||
206 | 1.8.3.1 | ||
207 | |||
diff --git a/recipes-kernel/cryptodev/cryptodev-fsl/0003-PKC-support-added-in-cryptodev-module.patch b/recipes-kernel/cryptodev/cryptodev-fsl/0003-PKC-support-added-in-cryptodev-module.patch new file mode 100644 index 0000000..a4f7816 --- /dev/null +++ b/recipes-kernel/cryptodev/cryptodev-fsl/0003-PKC-support-added-in-cryptodev-module.patch | |||
@@ -0,0 +1,898 @@ | |||
1 | From 5b57fc2124cef0acc3c7e8de376ebd9aa4f1fdd3 Mon Sep 17 00:00:00 2001 | ||
2 | From: Yashpal Dutta <yashpal.dutta@freescale.com> | ||
3 | Date: Fri, 7 Mar 2014 06:16:09 +0545 | ||
4 | Subject: [PATCH 3/9] PKC support added in cryptodev module | ||
5 | |||
6 | Upstream-status: Pending | ||
7 | |||
8 | Signed-off-by: Yashpal Dutta <yashpal.dutta@freescale.com> | ||
9 | --- | ||
10 | cryptlib.c | 66 +++++++++- | ||
11 | cryptlib.h | 28 ++++ | ||
12 | crypto/cryptodev.h | 15 ++- | ||
13 | cryptodev_int.h | 20 ++- | ||
14 | ioctl.c | 196 +++++++++++++++++++++++++-- | ||
15 | main.c | 378 +++++++++++++++++++++++++++++++++++++++++++++++++++++ | ||
16 | 6 files changed, 685 insertions(+), 18 deletions(-) | ||
17 | |||
18 | diff --git a/cryptlib.c b/cryptlib.c | ||
19 | index 44ce763..6900028 100644 | ||
20 | --- a/cryptlib.c | ||
21 | +++ b/cryptlib.c | ||
22 | @@ -5,6 +5,8 @@ | ||
23 | * Portions Copyright (c) 2010 Michael Weiser | ||
24 | * Portions Copyright (c) 2010 Phil Sutter | ||
25 | * | ||
26 | + * Copyright 2012 Freescale Semiconductor, Inc. | ||
27 | + * | ||
28 | * This file is part of linux cryptodev. | ||
29 | * | ||
30 | * This program is free software; you can redistribute it and/or | ||
31 | @@ -39,11 +41,6 @@ | ||
32 | #include "cryptodev_int.h" | ||
33 | |||
34 | |||
35 | -struct cryptodev_result { | ||
36 | - struct completion completion; | ||
37 | - int err; | ||
38 | -}; | ||
39 | - | ||
40 | static void cryptodev_complete(struct crypto_async_request *req, int err) | ||
41 | { | ||
42 | struct cryptodev_result *res = req->data; | ||
43 | @@ -259,7 +256,6 @@ static inline int waitfor(struct cryptodev_result *cr, ssize_t ret) | ||
44 | case 0: | ||
45 | break; | ||
46 | case -EINPROGRESS: | ||
47 | - case -EBUSY: | ||
48 | wait_for_completion(&cr->completion); | ||
49 | /* At this point we known for sure the request has finished, | ||
50 | * because wait_for_completion above was not interruptible. | ||
51 | @@ -439,3 +435,61 @@ int cryptodev_hash_final(struct hash_data *hdata, void *output) | ||
52 | return waitfor(hdata->async.result, ret); | ||
53 | } | ||
54 | |||
55 | +int cryptodev_pkc_offload(struct cryptodev_pkc *pkc) | ||
56 | +{ | ||
57 | + int ret = 0; | ||
58 | + struct pkc_request *pkc_req = &pkc->req, *pkc_requested; | ||
59 | + | ||
60 | + switch (pkc_req->type) { | ||
61 | + case RSA_PUB: | ||
62 | + case RSA_PRIV_FORM1: | ||
63 | + case RSA_PRIV_FORM2: | ||
64 | + case RSA_PRIV_FORM3: | ||
65 | + pkc->s = crypto_alloc_pkc("pkc(rsa)", | ||
66 | + CRYPTO_ALG_TYPE_PKC_RSA, 0); | ||
67 | + break; | ||
68 | + case DSA_SIGN: | ||
69 | + case DSA_VERIFY: | ||
70 | + case ECDSA_SIGN: | ||
71 | + case ECDSA_VERIFY: | ||
72 | + pkc->s = crypto_alloc_pkc("pkc(dsa)", | ||
73 | + CRYPTO_ALG_TYPE_PKC_DSA, 0); | ||
74 | + break; | ||
75 | + case DH_COMPUTE_KEY: | ||
76 | + case ECDH_COMPUTE_KEY: | ||
77 | + pkc->s = crypto_alloc_pkc("pkc(dh)", | ||
78 | + CRYPTO_ALG_TYPE_PKC_DH, 0); | ||
79 | + break; | ||
80 | + default: | ||
81 | + return -EINVAL; | ||
82 | + } | ||
83 | + | ||
84 | + if (IS_ERR_OR_NULL(pkc->s)) | ||
85 | + return -EINVAL; | ||
86 | + | ||
87 | + init_completion(&pkc->result.completion); | ||
88 | + pkc_requested = pkc_request_alloc(pkc->s, GFP_KERNEL); | ||
89 | + | ||
90 | + if (unlikely(IS_ERR_OR_NULL(pkc_requested))) { | ||
91 | + ret = -ENOMEM; | ||
92 | + goto error; | ||
93 | + } | ||
94 | + pkc_requested->type = pkc_req->type; | ||
95 | + pkc_requested->curve_type = pkc_req->curve_type; | ||
96 | + memcpy(&pkc_requested->req_u, &pkc_req->req_u, sizeof(pkc_req->req_u)); | ||
97 | + pkc_request_set_callback(pkc_requested, CRYPTO_TFM_REQ_MAY_BACKLOG, | ||
98 | + cryptodev_complete_asym, pkc); | ||
99 | + ret = crypto_pkc_op(pkc_requested); | ||
100 | + if (ret != -EINPROGRESS && ret != 0) | ||
101 | + goto error2; | ||
102 | + | ||
103 | + if (pkc->type == SYNCHRONOUS) | ||
104 | + ret = waitfor(&pkc->result, ret); | ||
105 | + | ||
106 | + return ret; | ||
107 | +error2: | ||
108 | + kfree(pkc_requested); | ||
109 | +error: | ||
110 | + crypto_free_pkc(pkc->s); | ||
111 | + return ret; | ||
112 | +} | ||
113 | diff --git a/cryptlib.h b/cryptlib.h | ||
114 | index a0a8a63..56d325a 100644 | ||
115 | --- a/cryptlib.h | ||
116 | +++ b/cryptlib.h | ||
117 | @@ -1,3 +1,6 @@ | ||
118 | +/* | ||
119 | + * Copyright 2012 Freescale Semiconductor, Inc. | ||
120 | + */ | ||
121 | #ifndef CRYPTLIB_H | ||
122 | # define CRYPTLIB_H | ||
123 | |||
124 | @@ -89,5 +92,30 @@ void cryptodev_hash_deinit(struct hash_data *hdata); | ||
125 | int cryptodev_hash_init(struct hash_data *hdata, const char *alg_name, | ||
126 | int hmac_mode, void *mackey, size_t mackeylen); | ||
127 | |||
128 | +/* Operation Type */ | ||
129 | +enum offload_type { | ||
130 | + SYNCHRONOUS, | ||
131 | + ASYNCHRONOUS | ||
132 | +}; | ||
133 | + | ||
134 | +struct cryptodev_result { | ||
135 | + struct completion completion; | ||
136 | + int err; | ||
137 | +}; | ||
138 | + | ||
139 | +struct cryptodev_pkc { | ||
140 | + struct list_head list; /* To maintain the Jobs in completed | ||
141 | + cryptodev lists */ | ||
142 | + struct kernel_crypt_kop kop; | ||
143 | + struct crypto_pkc *s; /* Transform pointer from CryptoAPI */ | ||
144 | + struct cryptodev_result result; /* Result to be updated by | ||
145 | + completion handler */ | ||
146 | + struct pkc_request req; /* PKC request structure allocated | ||
147 | + from CryptoAPI */ | ||
148 | + enum offload_type type; /* Synchronous Vs Asynchronous request */ | ||
149 | + void *cookie; /*Additional opaque cookie to be used in future */ | ||
150 | + struct crypt_priv *priv; | ||
151 | +}; | ||
152 | |||
153 | +int cryptodev_pkc_offload(struct cryptodev_pkc *); | ||
154 | #endif | ||
155 | diff --git a/crypto/cryptodev.h b/crypto/cryptodev.h | ||
156 | index c0e8cd4..96675fe 100644 | ||
157 | --- a/crypto/cryptodev.h | ||
158 | +++ b/crypto/cryptodev.h | ||
159 | @@ -1,6 +1,10 @@ | ||
160 | -/* This is a source compatible implementation with the original API of | ||
161 | +/* | ||
162 | + * Copyright 2012 Freescale Semiconductor, Inc. | ||
163 | + * | ||
164 | + * This is a source compatible implementation with the original API of | ||
165 | * cryptodev by Angelos D. Keromytis, found at openbsd cryptodev.h. | ||
166 | - * Placed under public domain */ | ||
167 | + * Placed under public domain | ||
168 | + */ | ||
169 | |||
170 | #ifndef L_CRYPTODEV_H | ||
171 | #define L_CRYPTODEV_H | ||
172 | @@ -245,6 +249,9 @@ struct crypt_kop { | ||
173 | __u16 crk_oparams; | ||
174 | __u32 crk_pad1; | ||
175 | struct crparam crk_param[CRK_MAXPARAM]; | ||
176 | + enum curve_t curve_type; /* 0 == Discrete Log, | ||
177 | + 1 = EC_PRIME, 2 = EC_BINARY */ | ||
178 | + void *cookie; | ||
179 | }; | ||
180 | |||
181 | enum cryptodev_crk_op_t { | ||
182 | @@ -289,5 +296,7 @@ enum cryptodev_crk_op_t { | ||
183 | */ | ||
184 | #define CIOCASYNCCRYPT _IOW('c', 110, struct crypt_op) | ||
185 | #define CIOCASYNCFETCH _IOR('c', 111, struct crypt_op) | ||
186 | - | ||
187 | +/* additional ioctls for asynchronous operation for asymmetric ciphers*/ | ||
188 | +#define CIOCASYMASYNCRYPT _IOW('c', 112, struct crypt_kop) | ||
189 | +#define CIOCASYMASYNFETCH _IOR('c', 113, struct crypt_kop) | ||
190 | #endif /* L_CRYPTODEV_H */ | ||
191 | diff --git a/cryptodev_int.h b/cryptodev_int.h | ||
192 | index 8e687e7..fdbcc61 100644 | ||
193 | --- a/cryptodev_int.h | ||
194 | +++ b/cryptodev_int.h | ||
195 | @@ -1,4 +1,6 @@ | ||
196 | -/* cipher stuff */ | ||
197 | +/* cipher stuff | ||
198 | + * Copyright 2012 Freescale Semiconductor, Inc. | ||
199 | + */ | ||
200 | #ifndef CRYPTODEV_INT_H | ||
201 | # define CRYPTODEV_INT_H | ||
202 | |||
203 | @@ -112,6 +114,14 @@ struct compat_crypt_auth_op { | ||
204 | |||
205 | #endif /* CONFIG_COMPAT */ | ||
206 | |||
207 | +/* kernel-internal extension to struct crypt_kop */ | ||
208 | +struct kernel_crypt_kop { | ||
209 | + struct crypt_kop kop; | ||
210 | + | ||
211 | + struct task_struct *task; | ||
212 | + struct mm_struct *mm; | ||
213 | +}; | ||
214 | + | ||
215 | /* kernel-internal extension to struct crypt_op */ | ||
216 | struct kernel_crypt_op { | ||
217 | struct crypt_op cop; | ||
218 | @@ -157,6 +167,14 @@ int crypto_run(struct fcrypt *fcr, struct kernel_crypt_op *kcop); | ||
219 | |||
220 | #include <cryptlib.h> | ||
221 | |||
222 | +/* Cryptodev Key operation handler */ | ||
223 | +int crypto_bn_modexp(struct cryptodev_pkc *); | ||
224 | +int crypto_modexp_crt(struct cryptodev_pkc *); | ||
225 | +int crypto_kop_dsasign(struct cryptodev_pkc *); | ||
226 | +int crypto_kop_dsaverify(struct cryptodev_pkc *); | ||
227 | +int crypto_run_asym(struct cryptodev_pkc *); | ||
228 | +void cryptodev_complete_asym(struct crypto_async_request *, int); | ||
229 | + | ||
230 | /* other internal structs */ | ||
231 | struct csession { | ||
232 | struct list_head entry; | ||
233 | diff --git a/ioctl.c b/ioctl.c | ||
234 | index 1563c75..782d7fe 100644 | ||
235 | --- a/ioctl.c | ||
236 | +++ b/ioctl.c | ||
237 | @@ -4,6 +4,7 @@ | ||
238 | * Copyright (c) 2004 Michal Ludvig <mludvig@logix.net.nz>, SuSE Labs | ||
239 | * Copyright (c) 2009,2010,2011 Nikos Mavrogiannopoulos <nmav@gnutls.org> | ||
240 | * Copyright (c) 2010 Phil Sutter | ||
241 | + * Copyright 2012 Freescale Semiconductor, Inc. | ||
242 | * | ||
243 | * This file is part of linux cryptodev. | ||
244 | * | ||
245 | @@ -89,8 +90,37 @@ struct crypt_priv { | ||
246 | int itemcount; | ||
247 | struct work_struct cryptask; | ||
248 | wait_queue_head_t user_waiter; | ||
249 | + /* List of pending cryptodev_pkc asym requests */ | ||
250 | + struct list_head asym_completed_list; | ||
251 | + /* For addition/removal of entry in pending list of asymmetric request*/ | ||
252 | + spinlock_t completion_lock; | ||
253 | }; | ||
254 | |||
255 | +/* Asymmetric request Completion handler */ | ||
256 | +void cryptodev_complete_asym(struct crypto_async_request *req, int err) | ||
257 | +{ | ||
258 | + struct cryptodev_pkc *pkc = req->data; | ||
259 | + struct cryptodev_result *res = &pkc->result; | ||
260 | + | ||
261 | + crypto_free_pkc(pkc->s); | ||
262 | + res->err = err; | ||
263 | + if (pkc->type == SYNCHRONOUS) { | ||
264 | + if (err == -EINPROGRESS) | ||
265 | + return; | ||
266 | + complete(&res->completion); | ||
267 | + } else { | ||
268 | + struct crypt_priv *pcr = pkc->priv; | ||
269 | + unsigned long flags; | ||
270 | + spin_lock_irqsave(&pcr->completion_lock, flags); | ||
271 | + list_add_tail(&pkc->list, &pcr->asym_completed_list); | ||
272 | + spin_unlock_irqrestore(&pcr->completion_lock, flags); | ||
273 | + /* wake for POLLIN */ | ||
274 | + wake_up_interruptible(&pcr->user_waiter); | ||
275 | + } | ||
276 | + | ||
277 | + kfree(req); | ||
278 | +} | ||
279 | + | ||
280 | #define FILL_SG(sg, ptr, len) \ | ||
281 | do { \ | ||
282 | (sg)->page = virt_to_page(ptr); \ | ||
283 | @@ -472,7 +502,8 @@ cryptodev_open(struct inode *inode, struct file *filp) | ||
284 | INIT_LIST_HEAD(&pcr->free.list); | ||
285 | INIT_LIST_HEAD(&pcr->todo.list); | ||
286 | INIT_LIST_HEAD(&pcr->done.list); | ||
287 | - | ||
288 | + INIT_LIST_HEAD(&pcr->asym_completed_list); | ||
289 | + spin_lock_init(&pcr->completion_lock); | ||
290 | INIT_WORK(&pcr->cryptask, cryptask_routine); | ||
291 | |||
292 | init_waitqueue_head(&pcr->user_waiter); | ||
293 | @@ -639,6 +670,79 @@ static int crypto_async_fetch(struct crypt_priv *pcr, | ||
294 | } | ||
295 | #endif | ||
296 | |||
297 | +/* get the first asym cipher completed job from the "done" queue | ||
298 | + * | ||
299 | + * returns: | ||
300 | + * -EBUSY if no completed jobs are ready (yet) | ||
301 | + * the return value otherwise */ | ||
302 | +static int crypto_async_fetch_asym(struct cryptodev_pkc *pkc) | ||
303 | +{ | ||
304 | + int ret = 0; | ||
305 | + struct kernel_crypt_kop *kop = &pkc->kop; | ||
306 | + struct crypt_kop *ckop = &kop->kop; | ||
307 | + struct pkc_request *pkc_req = &pkc->req; | ||
308 | + | ||
309 | + switch (ckop->crk_op) { | ||
310 | + case CRK_MOD_EXP: | ||
311 | + { | ||
312 | + struct rsa_pub_req_s *rsa_req = &pkc_req->req_u.rsa_pub_req; | ||
313 | + copy_to_user(ckop->crk_param[3].crp_p, rsa_req->g, | ||
314 | + rsa_req->g_len); | ||
315 | + } | ||
316 | + break; | ||
317 | + case CRK_MOD_EXP_CRT: | ||
318 | + { | ||
319 | + struct rsa_priv_frm3_req_s *rsa_req = | ||
320 | + &pkc_req->req_u.rsa_priv_f3; | ||
321 | + copy_to_user(ckop->crk_param[6].crp_p, | ||
322 | + rsa_req->f, rsa_req->f_len); | ||
323 | + } | ||
324 | + break; | ||
325 | + case CRK_DSA_SIGN: | ||
326 | + { | ||
327 | + struct dsa_sign_req_s *dsa_req = &pkc_req->req_u.dsa_sign; | ||
328 | + | ||
329 | + if (pkc_req->type == ECDSA_SIGN) { | ||
330 | + copy_to_user(ckop->crk_param[6].crp_p, | ||
331 | + dsa_req->c, dsa_req->d_len); | ||
332 | + copy_to_user(ckop->crk_param[7].crp_p, | ||
333 | + dsa_req->d, dsa_req->d_len); | ||
334 | + } else { | ||
335 | + copy_to_user(ckop->crk_param[5].crp_p, | ||
336 | + dsa_req->c, dsa_req->d_len); | ||
337 | + copy_to_user(ckop->crk_param[6].crp_p, | ||
338 | + dsa_req->d, dsa_req->d_len); | ||
339 | + } | ||
340 | + } | ||
341 | + break; | ||
342 | + case CRK_DSA_VERIFY: | ||
343 | + break; | ||
344 | + case CRK_DH_COMPUTE_KEY: | ||
345 | + { | ||
346 | + struct dh_key_req_s *dh_req = &pkc_req->req_u.dh_req; | ||
347 | + if (pkc_req->type == ECDH_COMPUTE_KEY) | ||
348 | + copy_to_user(ckop->crk_param[4].crp_p, | ||
349 | + dh_req->z, dh_req->z_len); | ||
350 | + else | ||
351 | + copy_to_user(ckop->crk_param[3].crp_p, | ||
352 | + dh_req->z, dh_req->z_len); | ||
353 | + } | ||
354 | + break; | ||
355 | + default: | ||
356 | + ret = -EINVAL; | ||
357 | + } | ||
358 | + kfree(pkc->cookie); | ||
359 | + return ret; | ||
360 | +} | ||
361 | + | ||
362 | +/* this function has to be called from process context */ | ||
363 | +static int fill_kop_from_cop(struct kernel_crypt_kop *kop) | ||
364 | +{ | ||
365 | + kop->task = current; | ||
366 | + kop->mm = current->mm; | ||
367 | + return 0; | ||
368 | +} | ||
369 | + | ||
370 | /* this function has to be called from process context */ | ||
371 | static int fill_kcop_from_cop(struct kernel_crypt_op *kcop, struct fcrypt *fcr) | ||
372 | { | ||
373 | @@ -662,11 +766,8 @@ static int fill_kcop_from_cop(struct kernel_crypt_op *kcop, struct fcrypt *fcr) | ||
374 | |||
375 | if (cop->iv) { | ||
376 | rc = copy_from_user(kcop->iv, cop->iv, kcop->ivlen); | ||
377 | - if (unlikely(rc)) { | ||
378 | - derr(1, "error copying IV (%d bytes), copy_from_user returned %d for address %p", | ||
379 | - kcop->ivlen, rc, cop->iv); | ||
380 | + if (unlikely(rc)) | ||
381 | return -EFAULT; | ||
382 | - } | ||
383 | } | ||
384 | |||
385 | return 0; | ||
386 | @@ -692,6 +793,25 @@ static int fill_cop_from_kcop(struct kernel_crypt_op *kcop, struct fcrypt *fcr) | ||
387 | return 0; | ||
388 | } | ||
389 | |||
390 | +static int kop_from_user(struct kernel_crypt_kop *kop, | ||
391 | + void __user *arg) | ||
392 | +{ | ||
393 | + if (unlikely(copy_from_user(&kop->kop, arg, sizeof(kop->kop)))) | ||
394 | + return -EFAULT; | ||
395 | + | ||
396 | + return fill_kop_from_cop(kop); | ||
397 | +} | ||
398 | + | ||
399 | +static int kop_to_user(struct kernel_crypt_kop *kop, | ||
400 | + void __user *arg) | ||
401 | +{ | ||
402 | + if (unlikely(copy_to_user(arg, &kop->kop, sizeof(kop->kop)))) { | ||
403 | + dprintk(1, KERN_ERR, "Cannot copy to userspace\n"); | ||
404 | + return -EFAULT; | ||
405 | + } | ||
406 | + return 0; | ||
407 | +} | ||
408 | + | ||
409 | static int kcop_from_user(struct kernel_crypt_op *kcop, | ||
410 | struct fcrypt *fcr, void __user *arg) | ||
411 | { | ||
412 | @@ -821,7 +941,8 @@ cryptodev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg_) | ||
413 | |||
414 | switch (cmd) { | ||
415 | case CIOCASYMFEAT: | ||
416 | - return put_user(0, p); | ||
417 | + return put_user(CRF_MOD_EXP_CRT | CRF_MOD_EXP | | ||
418 | + CRF_DSA_SIGN | CRF_DSA_VERIFY | CRF_DH_COMPUTE_KEY, p); | ||
419 | case CRIOGET: | ||
420 | fd = clonefd(filp); | ||
421 | ret = put_user(fd, p); | ||
422 | @@ -857,6 +978,24 @@ cryptodev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg_) | ||
423 | if (unlikely(ret)) | ||
424 | return ret; | ||
425 | return copy_to_user(arg, &siop, sizeof(siop)); | ||
426 | + case CIOCKEY: | ||
427 | + { | ||
428 | + struct cryptodev_pkc *pkc = | ||
429 | + kzalloc(sizeof(struct cryptodev_pkc), GFP_KERNEL); | ||
430 | + | ||
431 | + if (!pkc) | ||
432 | + return -ENOMEM; | ||
433 | + | ||
434 | + ret = kop_from_user(&pkc->kop, arg); | ||
435 | + if (unlikely(ret)) { | ||
436 | + kfree(pkc); | ||
437 | + return ret; | ||
438 | + } | ||
439 | + pkc->type = SYNCHRONOUS; | ||
440 | + ret = crypto_run_asym(pkc); | ||
441 | + kfree(pkc); | ||
442 | + } | ||
443 | + return ret; | ||
444 | case CIOCCRYPT: | ||
445 | if (unlikely(ret = kcop_from_user(&kcop, fcr, arg))) { | ||
446 | dwarning(1, "Error copying from user"); | ||
447 | @@ -895,6 +1034,45 @@ cryptodev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg_) | ||
448 | |||
449 | return kcop_to_user(&kcop, fcr, arg); | ||
450 | #endif | ||
451 | + case CIOCASYMASYNCRYPT: | ||
452 | + { | ||
453 | + struct cryptodev_pkc *pkc = | ||
454 | + kzalloc(sizeof(struct cryptodev_pkc), GFP_KERNEL); | ||
455 | + ret = kop_from_user(&pkc->kop, arg); | ||
456 | + | ||
457 | + if (unlikely(ret)) | ||
458 | + return -EINVAL; | ||
459 | + | ||
460 | + /* Store associated FD priv data with asymmetric request */ | ||
461 | + pkc->priv = pcr; | ||
462 | + pkc->type = ASYNCHRONOUS; | ||
463 | + ret = crypto_run_asym(pkc); | ||
464 | + if (ret == -EINPROGRESS) | ||
465 | + ret = 0; | ||
466 | + } | ||
467 | + return ret; | ||
468 | + case CIOCASYMASYNFETCH: | ||
469 | + { | ||
470 | + struct cryptodev_pkc *pkc; | ||
471 | + unsigned long flags; | ||
472 | + | ||
473 | + spin_lock_irqsave(&pcr->completion_lock, flags); | ||
474 | + if (list_empty(&pcr->asym_completed_list)) { | ||
475 | + spin_unlock_irqrestore(&pcr->completion_lock, flags); | ||
476 | + return -ENOMEM; | ||
477 | + } | ||
478 | + pkc = list_first_entry(&pcr->asym_completed_list, | ||
479 | + struct cryptodev_pkc, list); | ||
480 | + list_del(&pkc->list); | ||
481 | + spin_unlock_irqrestore(&pcr->completion_lock, flags); | ||
482 | + ret = crypto_async_fetch_asym(pkc); | ||
483 | + | ||
484 | + /* Reflect the updated request to user-space */ | ||
485 | + if (!ret) | ||
486 | + kop_to_user(&pkc->kop, arg); | ||
487 | + kfree(pkc); | ||
488 | + } | ||
489 | + return ret; | ||
490 | default: | ||
491 | return -EINVAL; | ||
492 | } | ||
493 | @@ -1083,9 +1261,11 @@ static unsigned int cryptodev_poll(struct file *file, poll_table *wait) | ||
494 | |||
495 | poll_wait(file, &pcr->user_waiter, wait); | ||
496 | |||
497 | - if (!list_empty_careful(&pcr->done.list)) | ||
498 | + if (!list_empty_careful(&pcr->done.list) || | ||
499 | + !list_empty_careful(&pcr->asym_completed_list)) | ||
500 | ret |= POLLIN | POLLRDNORM; | ||
501 | - if (!list_empty_careful(&pcr->free.list) || pcr->itemcount < MAX_COP_RINGSIZE) | ||
502 | + if (!list_empty_careful(&pcr->free.list) || | ||
503 | + pcr->itemcount < MAX_COP_RINGSIZE) | ||
504 | ret |= POLLOUT | POLLWRNORM; | ||
505 | |||
506 | return ret; | ||
507 | diff --git a/main.c b/main.c | ||
508 | index 57e5c38..0b7951e 100644 | ||
509 | --- a/main.c | ||
510 | +++ b/main.c | ||
511 | @@ -181,6 +181,384 @@ __crypto_run_zc(struct csession *ses_ptr, struct kernel_crypt_op *kcop) | ||
512 | return ret; | ||
513 | } | ||
514 | |||
515 | +int crypto_kop_dsasign(struct cryptodev_pkc *pkc) | ||
516 | +{ | ||
517 | + struct kernel_crypt_kop *kop = &pkc->kop; | ||
518 | + struct crypt_kop *cop = &kop->kop; | ||
519 | + struct pkc_request *pkc_req = &pkc->req; | ||
520 | + struct dsa_sign_req_s *dsa_req = &pkc_req->req_u.dsa_sign; | ||
521 | + int rc, buf_size; | ||
522 | + uint8_t *buf; | ||
523 | + | ||
524 | + if (!cop->crk_param[0].crp_nbits || !cop->crk_param[1].crp_nbits || | ||
525 | + !cop->crk_param[2].crp_nbits || !cop->crk_param[3].crp_nbits || | ||
526 | + !cop->crk_param[4].crp_nbits || !cop->crk_param[5].crp_nbits || | ||
527 | + !cop->crk_param[6].crp_nbits || (cop->crk_iparams == 6 && | ||
528 | + !cop->crk_param[7].crp_nbits)) | ||
529 | + return -EINVAL; | ||
530 | + | ||
531 | + dsa_req->m_len = (cop->crk_param[0].crp_nbits + 7)/8; | ||
532 | + dsa_req->q_len = (cop->crk_param[1].crp_nbits + 7)/8; | ||
533 | + dsa_req->r_len = (cop->crk_param[2].crp_nbits + 7)/8; | ||
534 | + dsa_req->g_len = (cop->crk_param[3].crp_nbits + 7)/8; | ||
535 | + dsa_req->priv_key_len = (cop->crk_param[4].crp_nbits + 7)/8; | ||
536 | + dsa_req->d_len = (cop->crk_param[6].crp_nbits + 7)/8; | ||
537 | + buf_size = dsa_req->m_len + dsa_req->q_len + dsa_req->r_len + | ||
538 | + dsa_req->g_len + dsa_req->priv_key_len + dsa_req->d_len + | ||
539 | + dsa_req->d_len; | ||
540 | + if (cop->crk_iparams == 6) { | ||
541 | + dsa_req->ab_len = (cop->crk_param[5].crp_nbits + 7)/8; | ||
542 | + buf_size += dsa_req->ab_len; | ||
543 | + pkc_req->type = ECDSA_SIGN; | ||
544 | + pkc_req->curve_type = cop->curve_type; | ||
545 | + } else { | ||
546 | + pkc_req->type = DSA_SIGN; | ||
547 | + } | ||
548 | + | ||
549 | + buf = kzalloc(buf_size, GFP_DMA); | ||
550 | + | ||
551 | + dsa_req->q = buf; | ||
552 | + dsa_req->r = dsa_req->q + dsa_req->q_len; | ||
553 | + dsa_req->g = dsa_req->r + dsa_req->r_len; | ||
554 | + dsa_req->priv_key = dsa_req->g + dsa_req->g_len; | ||
555 | + dsa_req->m = dsa_req->priv_key + dsa_req->priv_key_len; | ||
556 | + dsa_req->c = dsa_req->m + dsa_req->m_len; | ||
557 | + dsa_req->d = dsa_req->c + dsa_req->d_len; | ||
558 | + copy_from_user(dsa_req->m, cop->crk_param[0].crp_p, dsa_req->m_len); | ||
559 | + copy_from_user(dsa_req->q, cop->crk_param[1].crp_p, dsa_req->q_len); | ||
560 | + copy_from_user(dsa_req->r, cop->crk_param[2].crp_p, dsa_req->r_len); | ||
561 | + copy_from_user(dsa_req->g, cop->crk_param[3].crp_p, dsa_req->g_len); | ||
562 | + copy_from_user(dsa_req->priv_key, cop->crk_param[4].crp_p, | ||
563 | + dsa_req->priv_key_len); | ||
564 | + if (cop->crk_iparams == 6) { | ||
565 | + dsa_req->ab = dsa_req->d + dsa_req->d_len; | ||
566 | + copy_from_user(dsa_req->ab, cop->crk_param[5].crp_p, | ||
567 | + dsa_req->ab_len); | ||
568 | + } | ||
569 | + rc = cryptodev_pkc_offload(pkc); | ||
570 | + if (pkc->type == SYNCHRONOUS) { | ||
571 | + if (rc) | ||
572 | + goto err; | ||
573 | + if (cop->crk_iparams == 6) { | ||
574 | + copy_to_user(cop->crk_param[6].crp_p, dsa_req->c, | ||
575 | + dsa_req->d_len); | ||
576 | + copy_to_user(cop->crk_param[7].crp_p, dsa_req->d, | ||
577 | + dsa_req->d_len); | ||
578 | + } else { | ||
579 | + copy_to_user(cop->crk_param[5].crp_p, dsa_req->c, | ||
580 | + dsa_req->d_len); | ||
581 | + copy_to_user(cop->crk_param[6].crp_p, dsa_req->d, | ||
582 | + dsa_req->d_len); | ||
583 | + } | ||
584 | + } else { | ||
585 | + if (rc != -EINPROGRESS && rc != 0) | ||
586 | + goto err; | ||
587 | + | ||
588 | + pkc->cookie = buf; | ||
589 | + return rc; | ||
590 | + } | ||
591 | +err: | ||
592 | + kfree(buf); | ||
593 | + return rc; | ||
594 | +} | ||
595 | + | ||
596 | +int crypto_kop_dsaverify(struct cryptodev_pkc *pkc) | ||
597 | +{ | ||
598 | + struct kernel_crypt_kop *kop = &pkc->kop; | ||
599 | + struct crypt_kop *cop = &kop->kop; | ||
600 | + struct pkc_request *pkc_req; | ||
601 | + struct dsa_verify_req_s *dsa_req; | ||
602 | + int rc, buf_size; | ||
603 | + uint8_t *buf; | ||
604 | + | ||
605 | + if (!cop->crk_param[0].crp_nbits || !cop->crk_param[1].crp_nbits || | ||
606 | + !cop->crk_param[2].crp_nbits || !cop->crk_param[3].crp_nbits || | ||
607 | + !cop->crk_param[4].crp_nbits || !cop->crk_param[5].crp_nbits || | ||
608 | + !cop->crk_param[6].crp_nbits || (cop->crk_iparams == 8 && | ||
609 | + !cop->crk_param[7].crp_nbits)) | ||
610 | + return -EINVAL; | ||
611 | + | ||
612 | + pkc_req = &pkc->req; | ||
613 | + dsa_req = &pkc_req->req_u.dsa_verify; | ||
614 | + dsa_req->m_len = (cop->crk_param[0].crp_nbits + 7)/8; | ||
615 | + dsa_req->q_len = (cop->crk_param[1].crp_nbits + 7)/8; | ||
616 | + dsa_req->r_len = (cop->crk_param[2].crp_nbits + 7)/8; | ||
617 | + dsa_req->g_len = (cop->crk_param[3].crp_nbits + 7)/8; | ||
618 | + dsa_req->pub_key_len = (cop->crk_param[4].crp_nbits + 7)/8; | ||
619 | + dsa_req->d_len = (cop->crk_param[6].crp_nbits + 7)/8; | ||
620 | + buf_size = dsa_req->m_len + dsa_req->q_len + dsa_req->r_len + | ||
621 | + dsa_req->g_len + dsa_req->pub_key_len + dsa_req->d_len + | ||
622 | + dsa_req->d_len; | ||
623 | + if (cop->crk_iparams == 8) { | ||
624 | + dsa_req->ab_len = (cop->crk_param[5].crp_nbits + 7)/8; | ||
625 | + buf_size += dsa_req->ab_len; | ||
626 | + pkc_req->type = ECDSA_VERIFY; | ||
627 | + pkc_req->curve_type = cop->curve_type; | ||
628 | + } else { | ||
629 | + pkc_req->type = DSA_VERIFY; | ||
630 | + } | ||
631 | + | ||
632 | + buf = kzalloc(buf_size, GFP_DMA); | ||
633 | + | ||
634 | + dsa_req->q = buf; | ||
635 | + dsa_req->r = dsa_req->q + dsa_req->q_len; | ||
636 | + dsa_req->g = dsa_req->r + dsa_req->r_len; | ||
637 | + dsa_req->pub_key = dsa_req->g + dsa_req->g_len; | ||
638 | + dsa_req->m = dsa_req->pub_key + dsa_req->pub_key_len; | ||
639 | + dsa_req->c = dsa_req->m + dsa_req->m_len; | ||
640 | + dsa_req->d = dsa_req->c + dsa_req->d_len; | ||
641 | + copy_from_user(dsa_req->m, cop->crk_param[0].crp_p, dsa_req->m_len); | ||
642 | + copy_from_user(dsa_req->q, cop->crk_param[1].crp_p, dsa_req->q_len); | ||
643 | + copy_from_user(dsa_req->r, cop->crk_param[2].crp_p, dsa_req->r_len); | ||
644 | + copy_from_user(dsa_req->g, cop->crk_param[3].crp_p, dsa_req->g_len); | ||
645 | + copy_from_user(dsa_req->pub_key, cop->crk_param[4].crp_p, | ||
646 | + dsa_req->pub_key_len); | ||
647 | + if (cop->crk_iparams == 8) { | ||
648 | + dsa_req->ab = dsa_req->d + dsa_req->d_len; | ||
649 | + copy_from_user(dsa_req->ab, cop->crk_param[5].crp_p, | ||
650 | + dsa_req->ab_len); | ||
651 | + copy_from_user(dsa_req->c, cop->crk_param[6].crp_p, | ||
652 | + dsa_req->d_len); | ||
653 | + copy_from_user(dsa_req->d, cop->crk_param[7].crp_p, | ||
654 | + dsa_req->d_len); | ||
655 | + } else { | ||
656 | + copy_from_user(dsa_req->c, cop->crk_param[5].crp_p, | ||
657 | + dsa_req->d_len); | ||
658 | + copy_from_user(dsa_req->d, cop->crk_param[6].crp_p, | ||
659 | + dsa_req->d_len); | ||
660 | + } | ||
661 | + rc = cryptodev_pkc_offload(pkc); | ||
662 | + if (pkc->type == SYNCHRONOUS) { | ||
663 | + if (rc) | ||
664 | + goto err; | ||
665 | + } else { | ||
666 | + if (rc != -EINPROGRESS && !rc) | ||
667 | + goto err; | ||
668 | + pkc->cookie = buf; | ||
669 | + return rc; | ||
670 | + } | ||
671 | +err: | ||
672 | + kfree(buf); | ||
673 | + return rc; | ||
674 | +} | ||
675 | + | ||
676 | +int crypto_kop_dh_key(struct cryptodev_pkc *pkc) | ||
677 | +{ | ||
678 | + struct kernel_crypt_kop *kop = &pkc->kop; | ||
679 | + struct crypt_kop *cop = &kop->kop; | ||
680 | + struct pkc_request *pkc_req; | ||
681 | + struct dh_key_req_s *dh_req; | ||
682 | + int buf_size; | ||
683 | + uint8_t *buf; | ||
684 | + int rc = -EINVAL; | ||
685 | + | ||
686 | + pkc_req = &pkc->req; | ||
687 | + dh_req = &pkc_req->req_u.dh_req; | ||
688 | + dh_req->s_len = (cop->crk_param[0].crp_nbits + 7)/8; | ||
689 | + dh_req->pub_key_len = (cop->crk_param[1].crp_nbits + 7)/8; | ||
690 | + dh_req->q_len = (cop->crk_param[2].crp_nbits + 7)/8; | ||
691 | + buf_size = dh_req->q_len + dh_req->pub_key_len + dh_req->s_len; | ||
692 | + if (cop->crk_iparams == 4) { | ||
693 | + pkc_req->type = ECDH_COMPUTE_KEY; | ||
694 | + dh_req->ab_len = (cop->crk_param[3].crp_nbits + 7)/8; | ||
695 | + dh_req->z_len = (cop->crk_param[4].crp_nbits + 7)/8; | ||
696 | + buf_size += dh_req->ab_len; | ||
697 | + } else { | ||
698 | + dh_req->z_len = (cop->crk_param[3].crp_nbits + 7)/8; | ||
699 | + pkc_req->type = DH_COMPUTE_KEY; | ||
700 | + } | ||
701 | + buf_size += dh_req->z_len; | ||
702 | + buf = kzalloc(buf_size, GFP_DMA); | ||
703 | + dh_req->q = buf; | ||
704 | + dh_req->s = dh_req->q + dh_req->q_len; | ||
705 | + dh_req->pub_key = dh_req->s + dh_req->s_len; | ||
706 | + dh_req->z = dh_req->pub_key + dh_req->pub_key_len; | ||
707 | + if (cop->crk_iparams == 4) { | ||
708 | + dh_req->ab = dh_req->z + dh_req->z_len; | ||
709 | + pkc_req->curve_type = cop->curve_type; | ||
710 | + copy_from_user(dh_req->ab, cop->crk_param[3].crp_p, | ||
711 | + dh_req->ab_len); | ||
712 | + } | ||
713 | + copy_from_user(dh_req->s, cop->crk_param[0].crp_p, dh_req->s_len); | ||
714 | + copy_from_user(dh_req->pub_key, cop->crk_param[1].crp_p, | ||
715 | + dh_req->pub_key_len); | ||
716 | + copy_from_user(dh_req->q, cop->crk_param[2].crp_p, dh_req->q_len); | ||
717 | + rc = cryptodev_pkc_offload(pkc); | ||
718 | + if (pkc->type == SYNCHRONOUS) { | ||
719 | + if (rc) | ||
720 | + goto err; | ||
721 | + if (cop->crk_iparams == 4) | ||
722 | + copy_to_user(cop->crk_param[4].crp_p, dh_req->z, | ||
723 | + dh_req->z_len); | ||
724 | + else | ||
725 | + copy_to_user(cop->crk_param[3].crp_p, dh_req->z, | ||
726 | + dh_req->z_len); | ||
727 | + } else { | ||
728 | + if (rc != -EINPROGRESS && rc != 0) | ||
729 | + goto err; | ||
730 | + | ||
731 | + pkc->cookie = buf; | ||
732 | + return rc; | ||
733 | + } | ||
734 | +err: | ||
735 | + kfree(buf); | ||
736 | + return rc; | ||
737 | +} | ||
738 | + | ||
739 | +int crypto_modexp_crt(struct cryptodev_pkc *pkc) | ||
740 | +{ | ||
741 | + struct kernel_crypt_kop *kop = &pkc->kop; | ||
742 | + struct crypt_kop *cop = &kop->kop; | ||
743 | + struct pkc_request *pkc_req; | ||
744 | + struct rsa_priv_frm3_req_s *rsa_req; | ||
745 | + int rc; | ||
746 | + uint8_t *buf; | ||
747 | + | ||
748 | + if (!cop->crk_param[0].crp_nbits || !cop->crk_param[1].crp_nbits || | ||
749 | + !cop->crk_param[2].crp_nbits || !cop->crk_param[3].crp_nbits || | ||
750 | + !cop->crk_param[4].crp_nbits || !cop->crk_param[5].crp_nbits) | ||
751 | + return -EINVAL; | ||
752 | + | ||
753 | + pkc_req = &pkc->req; | ||
754 | + pkc_req->type = RSA_PRIV_FORM3; | ||
755 | + rsa_req = &pkc_req->req_u.rsa_priv_f3; | ||
756 | + rsa_req->p_len = (cop->crk_param[0].crp_nbits + 7)/8; | ||
757 | + rsa_req->q_len = (cop->crk_param[1].crp_nbits + 7)/8; | ||
758 | + rsa_req->g_len = (cop->crk_param[2].crp_nbits + 7)/8; | ||
759 | + rsa_req->dp_len = (cop->crk_param[3].crp_nbits + 7)/8; | ||
760 | + rsa_req->dq_len = (cop->crk_param[4].crp_nbits + 7)/8; | ||
761 | + rsa_req->c_len = (cop->crk_param[5].crp_nbits + 7)/8; | ||
762 | + rsa_req->f_len = (cop->crk_param[6].crp_nbits + 7)/8; | ||
763 | + buf = kzalloc(rsa_req->p_len + rsa_req->q_len + rsa_req->f_len + | ||
764 | + rsa_req->dp_len + rsa_req->dp_len + rsa_req->c_len + | ||
765 | + rsa_req->g_len, GFP_DMA); | ||
766 | + rsa_req->p = buf; | ||
767 | + rsa_req->q = rsa_req->p + rsa_req->p_len; | ||
768 | + rsa_req->g = rsa_req->q + rsa_req->q_len; | ||
769 | + rsa_req->dp = rsa_req->g + rsa_req->g_len; | ||
770 | + rsa_req->dq = rsa_req->dp + rsa_req->dp_len; | ||
771 | + rsa_req->c = rsa_req->dq + rsa_req->dq_len; | ||
772 | + rsa_req->f = rsa_req->c + rsa_req->c_len; | ||
773 | + copy_from_user(rsa_req->p, cop->crk_param[0].crp_p, rsa_req->p_len); | ||
774 | + copy_from_user(rsa_req->q, cop->crk_param[1].crp_p, rsa_req->q_len); | ||
775 | + copy_from_user(rsa_req->g, cop->crk_param[2].crp_p, rsa_req->g_len); | ||
776 | + copy_from_user(rsa_req->dp, cop->crk_param[3].crp_p, rsa_req->dp_len); | ||
777 | + copy_from_user(rsa_req->dq, cop->crk_param[4].crp_p, rsa_req->dq_len); | ||
778 | + copy_from_user(rsa_req->c, cop->crk_param[5].crp_p, rsa_req->c_len); | ||
779 | + rc = cryptodev_pkc_offload(pkc); | ||
780 | + | ||
781 | + if (pkc->type == SYNCHRONOUS) { | ||
782 | + if (rc) | ||
783 | + goto err; | ||
784 | + copy_to_user(cop->crk_param[6].crp_p, rsa_req->f, | ||
785 | + rsa_req->f_len); | ||
786 | + } else { | ||
787 | + if (rc != -EINPROGRESS && rc != 0) | ||
788 | + goto err; | ||
789 | + | ||
790 | + pkc->cookie = buf; | ||
791 | + return rc; | ||
792 | + } | ||
793 | +err: | ||
794 | + kfree(buf); | ||
795 | + return rc; | ||
796 | +} | ||
797 | + | ||
798 | +int crypto_bn_modexp(struct cryptodev_pkc *pkc) | ||
799 | +{ | ||
800 | + struct pkc_request *pkc_req; | ||
801 | + struct rsa_pub_req_s *rsa_req; | ||
802 | + int rc; | ||
803 | + struct kernel_crypt_kop *kop = &pkc->kop; | ||
804 | + struct crypt_kop *cop = &kop->kop; | ||
805 | + uint8_t *buf; | ||
806 | + | ||
807 | + if (!cop->crk_param[0].crp_nbits || !cop->crk_param[1].crp_nbits || | ||
808 | + !cop->crk_param[2].crp_nbits || !cop->crk_param[3].crp_nbits) | ||
809 | + return -EINVAL; | ||
810 | + | ||
811 | + pkc_req = &pkc->req; | ||
812 | + pkc_req->type = RSA_PUB; | ||
813 | + rsa_req = &pkc_req->req_u.rsa_pub_req; | ||
814 | + rsa_req->f_len = (cop->crk_param[0].crp_nbits + 7)/8; | ||
815 | + rsa_req->e_len = (cop->crk_param[1].crp_nbits + 7)/8; | ||
816 | + rsa_req->n_len = (cop->crk_param[2].crp_nbits + 7)/8; | ||
817 | + rsa_req->g_len = (cop->crk_param[3].crp_nbits + 7)/8; | ||
818 | + buf = kzalloc(rsa_req->f_len + rsa_req->e_len + rsa_req->n_len | ||
819 | + + rsa_req->g_len, GFP_DMA); | ||
820 | + if (!buf) | ||
821 | + return -ENOMEM; | ||
822 | + | ||
823 | + rsa_req->e = buf; | ||
824 | + rsa_req->f = rsa_req->e + rsa_req->e_len; | ||
825 | + rsa_req->g = rsa_req->f + rsa_req->f_len; | ||
826 | + rsa_req->n = rsa_req->g + rsa_req->g_len; | ||
827 | + copy_from_user(rsa_req->f, cop->crk_param[0].crp_p, rsa_req->f_len); | ||
828 | + copy_from_user(rsa_req->e, cop->crk_param[1].crp_p, rsa_req->e_len); | ||
829 | + copy_from_user(rsa_req->n, cop->crk_param[2].crp_p, rsa_req->n_len); | ||
830 | + rc = cryptodev_pkc_offload(pkc); | ||
831 | + if (pkc->type == SYNCHRONOUS) { | ||
832 | + if (rc) | ||
833 | + goto err; | ||
834 | + | ||
835 | + copy_to_user(cop->crk_param[3].crp_p, rsa_req->g, | ||
836 | + rsa_req->g_len); | ||
837 | + } else { | ||
838 | + if (rc != -EINPROGRESS && rc != 0) | ||
839 | + goto err; | ||
840 | + | ||
841 | + /* This one will be freed later in fetch handler */ | ||
842 | + pkc->cookie = buf; | ||
843 | + return rc; | ||
844 | + } | ||
845 | +err: | ||
846 | + kfree(buf); | ||
847 | + return rc; | ||
848 | +} | ||
849 | + | ||
850 | +int crypto_run_asym(struct cryptodev_pkc *pkc) | ||
851 | +{ | ||
852 | + int ret = -EINVAL; | ||
853 | + struct kernel_crypt_kop *kop = &pkc->kop; | ||
854 | + | ||
855 | + switch (kop->kop.crk_op) { | ||
856 | + case CRK_MOD_EXP: | ||
857 | + if (kop->kop.crk_iparams != 3 && kop->kop.crk_oparams != 1) | ||
858 | + goto err; | ||
859 | + | ||
860 | + ret = crypto_bn_modexp(pkc); | ||
861 | + break; | ||
862 | + case CRK_MOD_EXP_CRT: | ||
863 | + if (kop->kop.crk_iparams != 6 && kop->kop.crk_oparams != 1) | ||
864 | + goto err; | ||
865 | + | ||
866 | + ret = crypto_modexp_crt(pkc); | ||
867 | + break; | ||
868 | + case CRK_DSA_SIGN: | ||
869 | + if ((kop->kop.crk_iparams != 5 && kop->kop.crk_iparams != 6) || | ||
870 | + kop->kop.crk_oparams != 2) | ||
871 | + goto err; | ||
872 | + | ||
873 | + ret = crypto_kop_dsasign(pkc); | ||
874 | + break; | ||
875 | + case CRK_DSA_VERIFY: | ||
876 | + if ((kop->kop.crk_iparams != 7 && kop->kop.crk_iparams != 8) || | ||
877 | + kop->kop.crk_oparams != 0) | ||
878 | + goto err; | ||
879 | + | ||
880 | + ret = crypto_kop_dsaverify(pkc); | ||
881 | + break; | ||
882 | + case CRK_DH_COMPUTE_KEY: | ||
883 | + if ((kop->kop.crk_iparams != 3 && kop->kop.crk_iparams != 4) || | ||
884 | + kop->kop.crk_oparams != 1) | ||
885 | + goto err; | ||
886 | + ret = crypto_kop_dh_key(pkc); | ||
887 | + break; | ||
888 | + } | ||
889 | +err: | ||
890 | + return ret; | ||
891 | +} | ||
892 | + | ||
893 | int crypto_run(struct fcrypt *fcr, struct kernel_crypt_op *kcop) | ||
894 | { | ||
895 | struct csession *ses_ptr; | ||
896 | -- | ||
897 | 1.8.3.1 | ||
898 | |||
diff --git a/recipes-kernel/cryptodev/cryptodev-fsl/0004-Compat-versions-of-PKC-IOCTLs.patch b/recipes-kernel/cryptodev/cryptodev-fsl/0004-Compat-versions-of-PKC-IOCTLs.patch new file mode 100644 index 0000000..2eedcc7 --- /dev/null +++ b/recipes-kernel/cryptodev/cryptodev-fsl/0004-Compat-versions-of-PKC-IOCTLs.patch | |||
@@ -0,0 +1,200 @@ | |||
1 | From 5435dfd329cd90837ce36c6dadc26166c7906cab Mon Sep 17 00:00:00 2001 | ||
2 | From: Yashpal Dutta <yashpal.dutta@freescale.com> | ||
3 | Date: Fri, 7 Mar 2014 06:52:13 +0545 | ||
4 | Subject: [PATCH 4/9] Compat versions of PKC IOCTLs | ||
5 | |||
6 | Upstream-status: Pending | ||
7 | |||
8 | Signed-off-by: Yashpal Dutta <yashpal.dutta@freescale.com> | ||
9 | --- | ||
10 | cryptodev_int.h | 20 ++++++++++ | ||
11 | ioctl.c | 120 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ | ||
12 | 2 files changed, 140 insertions(+) | ||
13 | |||
14 | diff --git a/cryptodev_int.h b/cryptodev_int.h | ||
15 | index fdbcc61..cf54dac 100644 | ||
16 | --- a/cryptodev_int.h | ||
17 | +++ b/cryptodev_int.h | ||
18 | @@ -75,6 +75,24 @@ struct compat_crypt_op { | ||
19 | compat_uptr_t iv;/* initialization vector for encryption operations */ | ||
20 | }; | ||
21 | |||
22 | +/* input of CIOCKEY */ | ||
23 | +struct compat_crparam { | ||
24 | + compat_uptr_t crp_p; | ||
25 | + uint32_t crp_nbits; | ||
26 | +}; | ||
27 | + | ||
28 | +struct compat_crypt_kop { | ||
29 | + uint32_t crk_op; /* cryptodev_crk_ot_t */ | ||
30 | + uint32_t crk_status; | ||
31 | + uint16_t crk_iparams; | ||
32 | + uint16_t crk_oparams; | ||
33 | + uint32_t crk_pad1; | ||
34 | + struct compat_crparam crk_param[CRK_MAXPARAM]; | ||
35 | + enum curve_t curve_type; /* 0 == Discrete Log, 1 = EC_PRIME, | ||
36 | + 2 = EC_BINARY */ | ||
37 | + compat_uptr_t cookie; | ||
38 | +}; | ||
39 | + | ||
40 | /* input of CIOCAUTHCRYPT */ | ||
41 | struct compat_crypt_auth_op { | ||
42 | uint32_t ses; /* session identifier */ | ||
43 | @@ -111,6 +129,8 @@ struct compat_crypt_auth_op { | ||
44 | #define COMPAT_CIOCASYNCCRYPT _IOW('c', 107, struct compat_crypt_op) | ||
45 | #define COMPAT_CIOCASYNCFETCH _IOR('c', 108, struct compat_crypt_op) | ||
46 | #define COMPAT_CIOCAUTHCRYPT _IOWR('c', 109, struct compat_crypt_auth_op) | ||
47 | +#define COMPAT_CIOCASYMASYNCRYPT _IOW('c', 110, struct compat_crypt_kop) | ||
48 | +#define COMPAT_CIOCASYMASYNFETCH _IOR('c', 111, struct compat_crypt_kop) | ||
49 | |||
50 | #endif /* CONFIG_COMPAT */ | ||
51 | |||
52 | diff --git a/ioctl.c b/ioctl.c | ||
53 | index 782d7fe..3baf3e6 100644 | ||
54 | --- a/ioctl.c | ||
55 | +++ b/ioctl.c | ||
56 | @@ -1081,6 +1081,68 @@ cryptodev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg_) | ||
57 | /* compatibility code for 32bit userlands */ | ||
58 | #ifdef CONFIG_COMPAT | ||
59 | |||
60 | +static inline void compat_to_crypt_kop(struct compat_crypt_kop *compat, | ||
61 | + struct crypt_kop *kop) | ||
62 | +{ | ||
63 | + int i; | ||
64 | + kop->crk_op = compat->crk_op; | ||
65 | + kop->crk_status = compat->crk_status; | ||
66 | + kop->crk_iparams = compat->crk_iparams; | ||
67 | + kop->crk_oparams = compat->crk_oparams; | ||
68 | + | ||
69 | + for (i = 0; i < CRK_MAXPARAM; i++) { | ||
70 | + kop->crk_param[i].crp_p = | ||
71 | + compat_ptr(compat->crk_param[i].crp_p); | ||
72 | + kop->crk_param[i].crp_nbits = compat->crk_param[i].crp_nbits; | ||
73 | + } | ||
74 | + | ||
75 | + kop->curve_type = compat->curve_type; | ||
76 | + kop->cookie = compat->cookie; | ||
77 | +} | ||
78 | + | ||
79 | +static int compat_kop_from_user(struct kernel_crypt_kop *kop, | ||
80 | + void __user *arg) | ||
81 | +{ | ||
82 | + struct compat_crypt_kop compat_kop; | ||
83 | + | ||
84 | + if (unlikely(copy_from_user(&compat_kop, arg, sizeof(compat_kop)))) | ||
85 | + return -EFAULT; | ||
86 | + | ||
87 | + compat_to_crypt_kop(&compat_kop, &kop->kop); | ||
88 | + return fill_kop_from_cop(kop); | ||
89 | +} | ||
90 | + | ||
91 | +static inline void crypt_kop_to_compat(struct crypt_kop *kop, | ||
92 | + struct compat_crypt_kop *compat) | ||
93 | +{ | ||
94 | + int i; | ||
95 | + | ||
96 | + compat->crk_op = kop->crk_op; | ||
97 | + compat->crk_status = kop->crk_status; | ||
98 | + compat->crk_iparams = kop->crk_iparams; | ||
99 | + compat->crk_oparams = kop->crk_oparams; | ||
100 | + | ||
101 | + for (i = 0; i < CRK_MAXPARAM; i++) { | ||
102 | + compat->crk_param[i].crp_p = | ||
103 | + ptr_to_compat(kop->crk_param[i].crp_p); | ||
104 | + compat->crk_param[i].crp_nbits = kop->crk_param[i].crp_nbits; | ||
105 | + } | ||
106 | + compat->cookie = kop->cookie; | ||
107 | + compat->curve_type = kop->curve_type; | ||
108 | +} | ||
109 | + | ||
110 | +static int compat_kop_to_user(struct kernel_crypt_kop *kop, void __user *arg) | ||
111 | +{ | ||
112 | + struct compat_crypt_kop compat_kop; | ||
113 | + | ||
114 | + crypt_kop_to_compat(&kop->kop, &compat_kop); | ||
115 | + if (unlikely(copy_to_user(arg, &compat_kop, sizeof(compat_kop)))) { | ||
116 | + dprintk(1, KERN_ERR, "Cannot copy to userspace\n"); | ||
117 | + return -EFAULT; | ||
118 | + } | ||
119 | + return 0; | ||
120 | +} | ||
121 | + | ||
122 | static inline void | ||
123 | compat_to_session_op(struct compat_session_op *compat, struct session_op *sop) | ||
124 | { | ||
125 | @@ -1208,7 +1270,26 @@ cryptodev_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg_) | ||
126 | return -EFAULT; | ||
127 | } | ||
128 | return ret; | ||
129 | + case COMPAT_CIOCKEY: | ||
130 | + { | ||
131 | + struct cryptodev_pkc *pkc = | ||
132 | + kzalloc(sizeof(struct cryptodev_pkc), GFP_KERNEL); | ||
133 | + | ||
134 | + if (!pkc) | ||
135 | + return -ENOMEM; | ||
136 | + | ||
137 | + ret = compat_kop_from_user(&pkc->kop, arg); | ||
138 | + | ||
139 | + if (unlikely(ret)) { | ||
140 | + kfree(pkc); | ||
141 | + return ret; | ||
142 | + } | ||
143 | |||
144 | + pkc->type = SYNCHRONOUS; | ||
145 | + ret = crypto_run_asym(pkc); | ||
146 | + kfree(pkc); | ||
147 | + } | ||
148 | + return ret; | ||
149 | case COMPAT_CIOCCRYPT: | ||
150 | ret = compat_kcop_from_user(&kcop, fcr, arg); | ||
151 | if (unlikely(ret)) | ||
152 | @@ -1247,6 +1328,45 @@ cryptodev_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg_) | ||
153 | |||
154 | return compat_kcop_to_user(&kcop, fcr, arg); | ||
155 | #endif | ||
156 | + case COMPAT_CIOCASYMASYNCRYPT: | ||
157 | + { | ||
158 | + struct cryptodev_pkc *pkc = | ||
159 | + kzalloc(sizeof(struct cryptodev_pkc), GFP_KERNEL); | ||
160 | + | ||
161 | + ret = compat_kop_from_user(&pkc->kop, arg); | ||
162 | + if (unlikely(ret)) | ||
163 | + return -EINVAL; | ||
164 | + | ||
165 | + /* Store associated FD priv data with asymmetric request */ | ||
166 | + pkc->priv = pcr; | ||
167 | + pkc->type = ASYNCHRONOUS; | ||
168 | + ret = crypto_run_asym(pkc); | ||
169 | + if (ret == -EINPROGRESS) | ||
170 | + ret = 0; | ||
171 | + } | ||
172 | + return ret; | ||
173 | + case COMPAT_CIOCASYMASYNFETCH: | ||
174 | + { | ||
175 | + struct cryptodev_pkc *pkc; | ||
176 | + unsigned long flags; | ||
177 | + | ||
178 | + spin_lock_irqsave(&pcr->completion_lock, flags); | ||
179 | + if (list_empty(&pcr->asym_completed_list)) { | ||
180 | + spin_unlock_irqrestore(&pcr->completion_lock, flags); | ||
181 | + return -ENOMEM; | ||
182 | + } | ||
183 | + pkc = list_first_entry(&pcr->asym_completed_list, | ||
184 | + struct cryptodev_pkc, list); | ||
185 | + list_del(&pkc->list); | ||
186 | + spin_unlock_irqrestore(&pcr->completion_lock, flags); | ||
187 | + ret = crypto_async_fetch_asym(pkc); | ||
188 | + | ||
189 | + /* Reflect the updated request to user-space */ | ||
190 | + if (!ret) | ||
191 | + compat_kop_to_user(&pkc->kop, arg); | ||
192 | + kfree(pkc); | ||
193 | + } | ||
194 | + return ret; | ||
195 | default: | ||
196 | return -EINVAL; | ||
197 | } | ||
198 | -- | ||
199 | 1.8.3.1 | ||
200 | |||
diff --git a/recipes-kernel/cryptodev/cryptodev-fsl/0005-Asynchronous-interface-changes-in-cryptodev.patch b/recipes-kernel/cryptodev/cryptodev-fsl/0005-Asynchronous-interface-changes-in-cryptodev.patch new file mode 100644 index 0000000..2f88eda --- /dev/null +++ b/recipes-kernel/cryptodev/cryptodev-fsl/0005-Asynchronous-interface-changes-in-cryptodev.patch | |||
@@ -0,0 +1,213 @@ | |||
1 | From ddc4179a454cea79c8385fd6756d20cbf3c6dcb5 Mon Sep 17 00:00:00 2001 | ||
2 | From: Yashpal Dutta <yashpal.dutta@freescale.com> | ||
3 | Date: Fri, 7 Mar 2014 07:24:00 +0545 | ||
4 | Subject: [PATCH 5/9] Asynchronous interface changes in cryptodev | ||
5 | |||
6 | Upstream-status: Pending | ||
7 | |||
8 | Signed-off-by: Yashpal Dutta <yashpal.dutta@freescale.com> | ||
9 | --- | ||
10 | cryptlib.h | 7 ++++- | ||
11 | crypto/cryptodev.h | 10 ++++++- | ||
12 | cryptodev_int.h | 10 ++++++- | ||
13 | ioctl.c | 76 +++++++++++++++++++++++++++++++++++++----------------- | ||
14 | 4 files changed, 76 insertions(+), 27 deletions(-) | ||
15 | |||
16 | diff --git a/cryptlib.h b/cryptlib.h | ||
17 | index 56d325a..7ffa54c 100644 | ||
18 | --- a/cryptlib.h | ||
19 | +++ b/cryptlib.h | ||
20 | @@ -113,7 +113,12 @@ struct cryptodev_pkc { | ||
21 | struct pkc_request req; /* PKC request structure allocated | ||
22 | from CryptoAPI */ | ||
23 | enum offload_type type; /* Synchronous Vs Asynchronous request */ | ||
24 | - void *cookie; /*Additional opaque cookie to be used in future */ | ||
25 | + /* | ||
26 | + * cookie used for transfering tranparent information from async | ||
27 | + * submission to async fetch. Currently some dynamic allocated | ||
28 | + * buffers are maintained which will be freed later during fetch | ||
29 | + */ | ||
30 | + void *cookie; | ||
31 | struct crypt_priv *priv; | ||
32 | }; | ||
33 | |||
34 | diff --git a/crypto/cryptodev.h b/crypto/cryptodev.h | ||
35 | index 96675fe..4436fbf 100644 | ||
36 | --- a/crypto/cryptodev.h | ||
37 | +++ b/crypto/cryptodev.h | ||
38 | @@ -254,6 +254,14 @@ struct crypt_kop { | ||
39 | void *cookie; | ||
40 | }; | ||
41 | |||
42 | +#define MAX_COOKIES 4 | ||
43 | + | ||
44 | +struct pkc_cookie_list_s { | ||
45 | + int cookie_available; | ||
46 | + void *cookie[MAX_COOKIES]; | ||
47 | + int status[MAX_COOKIES]; | ||
48 | +}; | ||
49 | + | ||
50 | enum cryptodev_crk_op_t { | ||
51 | CRK_MOD_EXP = 0, | ||
52 | CRK_MOD_EXP_CRT = 1, | ||
53 | @@ -298,5 +306,5 @@ enum cryptodev_crk_op_t { | ||
54 | #define CIOCASYNCFETCH _IOR('c', 111, struct crypt_op) | ||
55 | /* additional ioctls for asynchronous operation for asymmetric ciphers*/ | ||
56 | #define CIOCASYMASYNCRYPT _IOW('c', 112, struct crypt_kop) | ||
57 | -#define CIOCASYMASYNFETCH _IOR('c', 113, struct crypt_kop) | ||
58 | +#define CIOCASYMFETCHCOOKIE _IOR('c', 113, struct pkc_cookie_list_s) | ||
59 | #endif /* L_CRYPTODEV_H */ | ||
60 | diff --git a/cryptodev_int.h b/cryptodev_int.h | ||
61 | index cf54dac..5347cae 100644 | ||
62 | --- a/cryptodev_int.h | ||
63 | +++ b/cryptodev_int.h | ||
64 | @@ -93,6 +93,12 @@ struct compat_crypt_kop { | ||
65 | compat_uptr_t cookie; | ||
66 | }; | ||
67 | |||
68 | +struct compat_pkc_cookie_list_s { | ||
69 | + int cookie_available; | ||
70 | + compat_uptr_t cookie[MAX_COOKIES]; | ||
71 | + int status[MAX_COOKIES]; | ||
72 | +}; | ||
73 | + | ||
74 | /* input of CIOCAUTHCRYPT */ | ||
75 | struct compat_crypt_auth_op { | ||
76 | uint32_t ses; /* session identifier */ | ||
77 | @@ -126,11 +132,13 @@ struct compat_crypt_auth_op { | ||
78 | /* compat ioctls, defined for the above structs */ | ||
79 | #define COMPAT_CIOCGSESSION _IOWR('c', 102, struct compat_session_op) | ||
80 | #define COMPAT_CIOCCRYPT _IOWR('c', 104, struct compat_crypt_op) | ||
81 | +#define COMPAT_CIOCKEY _IOW('c', 105, struct compat_crypt_kop) | ||
82 | #define COMPAT_CIOCASYNCCRYPT _IOW('c', 107, struct compat_crypt_op) | ||
83 | #define COMPAT_CIOCASYNCFETCH _IOR('c', 108, struct compat_crypt_op) | ||
84 | #define COMPAT_CIOCAUTHCRYPT _IOWR('c', 109, struct compat_crypt_auth_op) | ||
85 | #define COMPAT_CIOCASYMASYNCRYPT _IOW('c', 110, struct compat_crypt_kop) | ||
86 | -#define COMPAT_CIOCASYMASYNFETCH _IOR('c', 111, struct compat_crypt_kop) | ||
87 | +#define COMPAT_CIOCASYMFETCHCOOKIE _IOR('c', 111, \ | ||
88 | + struct compat_pkc_cookie_list_s) | ||
89 | |||
90 | #endif /* CONFIG_COMPAT */ | ||
91 | |||
92 | diff --git a/ioctl.c b/ioctl.c | ||
93 | index 3baf3e6..2eb7f03 100644 | ||
94 | --- a/ioctl.c | ||
95 | +++ b/ioctl.c | ||
96 | @@ -105,8 +105,6 @@ void cryptodev_complete_asym(struct crypto_async_request *req, int err) | ||
97 | crypto_free_pkc(pkc->s); | ||
98 | res->err = err; | ||
99 | if (pkc->type == SYNCHRONOUS) { | ||
100 | - if (err == -EINPROGRESS) | ||
101 | - return; | ||
102 | complete(&res->completion); | ||
103 | } else { | ||
104 | struct crypt_priv *pcr = pkc->priv; | ||
105 | @@ -1051,26 +1049,41 @@ cryptodev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg_) | ||
106 | ret = 0; | ||
107 | } | ||
108 | return ret; | ||
109 | - case CIOCASYMASYNFETCH: | ||
110 | + case CIOCASYMFETCHCOOKIE: | ||
111 | { | ||
112 | struct cryptodev_pkc *pkc; | ||
113 | unsigned long flags; | ||
114 | + int i; | ||
115 | + struct pkc_cookie_list_s cookie_list; | ||
116 | |||
117 | spin_lock_irqsave(&pcr->completion_lock, flags); | ||
118 | - if (list_empty(&pcr->asym_completed_list)) { | ||
119 | - spin_unlock_irqrestore(&pcr->completion_lock, flags); | ||
120 | - return -ENOMEM; | ||
121 | + cookie_list.cookie_available = 0; | ||
122 | + for (i = 0; i < MAX_COOKIES; i++) { | ||
123 | + if (!list_empty(&pcr->asym_completed_list)) { | ||
124 | + /* Run a loop in the list for upto elements | ||
125 | + and copy their response back */ | ||
126 | + pkc = | ||
127 | + list_first_entry(&pcr->asym_completed_list, | ||
128 | + struct cryptodev_pkc, list); | ||
129 | + list_del(&pkc->list); | ||
130 | + ret = crypto_async_fetch_asym(pkc); | ||
131 | + if (!ret) { | ||
132 | + cookie_list.cookie_available++; | ||
133 | + cookie_list.cookie[i] = | ||
134 | + pkc->kop.kop.cookie; | ||
135 | + cookie_list.status[i] = pkc->result.err; | ||
136 | + } | ||
137 | + kfree(pkc); | ||
138 | + } else { | ||
139 | + break; | ||
140 | + } | ||
141 | } | ||
142 | - pkc = list_first_entry(&pcr->asym_completed_list, | ||
143 | - struct cryptodev_pkc, list); | ||
144 | - list_del(&pkc->list); | ||
145 | spin_unlock_irqrestore(&pcr->completion_lock, flags); | ||
146 | - ret = crypto_async_fetch_asym(pkc); | ||
147 | |||
148 | /* Reflect the updated request to user-space */ | ||
149 | - if (!ret) | ||
150 | - kop_to_user(&pkc->kop, arg); | ||
151 | - kfree(pkc); | ||
152 | + if (cookie_list.cookie_available) | ||
153 | + copy_to_user(arg, &cookie_list, | ||
154 | + sizeof(struct pkc_cookie_list_s)); | ||
155 | } | ||
156 | return ret; | ||
157 | default: | ||
158 | @@ -1345,26 +1358,41 @@ cryptodev_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg_) | ||
159 | ret = 0; | ||
160 | } | ||
161 | return ret; | ||
162 | - case COMPAT_CIOCASYMASYNFETCH: | ||
163 | + case COMPAT_CIOCASYMFETCHCOOKIE: | ||
164 | { | ||
165 | struct cryptodev_pkc *pkc; | ||
166 | unsigned long flags; | ||
167 | + int i = 0; | ||
168 | + struct compat_pkc_cookie_list_s cookie_list; | ||
169 | |||
170 | spin_lock_irqsave(&pcr->completion_lock, flags); | ||
171 | - if (list_empty(&pcr->asym_completed_list)) { | ||
172 | - spin_unlock_irqrestore(&pcr->completion_lock, flags); | ||
173 | - return -ENOMEM; | ||
174 | + cookie_list.cookie_available = 0; | ||
175 | + | ||
176 | + for (i = 0; i < MAX_COOKIES; i++) { | ||
177 | + if (!list_empty(&pcr->asym_completed_list)) { | ||
178 | + /* Run a loop in the list for upto elements | ||
179 | + and copy their response back */ | ||
180 | + pkc = | ||
181 | + list_first_entry(&pcr->asym_completed_list, | ||
182 | + struct cryptodev_pkc, list); | ||
183 | + list_del(&pkc->list); | ||
184 | + ret = crypto_async_fetch_asym(pkc); | ||
185 | + if (!ret) { | ||
186 | + cookie_list.cookie_available++; | ||
187 | + cookie_list.cookie[i] = | ||
188 | + pkc->kop.kop.cookie; | ||
189 | + } | ||
190 | + kfree(pkc); | ||
191 | + } else { | ||
192 | + break; | ||
193 | + } | ||
194 | } | ||
195 | - pkc = list_first_entry(&pcr->asym_completed_list, | ||
196 | - struct cryptodev_pkc, list); | ||
197 | - list_del(&pkc->list); | ||
198 | spin_unlock_irqrestore(&pcr->completion_lock, flags); | ||
199 | - ret = crypto_async_fetch_asym(pkc); | ||
200 | |||
201 | /* Reflect the updated request to user-space */ | ||
202 | - if (!ret) | ||
203 | - compat_kop_to_user(&pkc->kop, arg); | ||
204 | - kfree(pkc); | ||
205 | + if (cookie_list.cookie_available) | ||
206 | + copy_to_user(arg, &cookie_list, | ||
207 | + sizeof(struct compat_pkc_cookie_list_s)); | ||
208 | } | ||
209 | return ret; | ||
210 | default: | ||
211 | -- | ||
212 | 1.8.3.1 | ||
213 | |||
diff --git a/recipes-kernel/cryptodev/cryptodev-fsl/0006-ECC_KEYGEN-and-DLC_KEYGEN-supported-in-cryptodev-mod.patch b/recipes-kernel/cryptodev/cryptodev-fsl/0006-ECC_KEYGEN-and-DLC_KEYGEN-supported-in-cryptodev-mod.patch new file mode 100644 index 0000000..e70a057 --- /dev/null +++ b/recipes-kernel/cryptodev/cryptodev-fsl/0006-ECC_KEYGEN-and-DLC_KEYGEN-supported-in-cryptodev-mod.patch | |||
@@ -0,0 +1,212 @@ | |||
1 | From 30fc86a09109f169815befc2cd8bbfcae79fe7e0 Mon Sep 17 00:00:00 2001 | ||
2 | From: Yashpal Dutta <yashpal.dutta@freescale.com> | ||
3 | Date: Fri, 7 Mar 2014 07:53:53 +0545 | ||
4 | Subject: [PATCH 6/9] ECC_KEYGEN and DLC_KEYGEN supported in cryptodev module | ||
5 | |||
6 | Upstream-status: Pending | ||
7 | |||
8 | Signed-off-by: Yashpal Dutta <yashpal.dutta@freescale.com> | ||
9 | --- | ||
10 | cryptlib.c | 2 ++ | ||
11 | crypto/cryptodev.h | 5 +++- | ||
12 | ioctl.c | 29 +++++++++++++++++-- | ||
13 | main.c | 85 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ | ||
14 | 4 files changed, 118 insertions(+), 3 deletions(-) | ||
15 | |||
16 | diff --git a/cryptlib.c b/cryptlib.c | ||
17 | index 6900028..47cd568 100644 | ||
18 | --- a/cryptlib.c | ||
19 | +++ b/cryptlib.c | ||
20 | @@ -452,6 +452,8 @@ int cryptodev_pkc_offload(struct cryptodev_pkc *pkc) | ||
21 | case DSA_VERIFY: | ||
22 | case ECDSA_SIGN: | ||
23 | case ECDSA_VERIFY: | ||
24 | + case DLC_KEYGEN: | ||
25 | + case ECC_KEYGEN: | ||
26 | pkc->s = crypto_alloc_pkc("pkc(dsa)", | ||
27 | CRYPTO_ALG_TYPE_PKC_DSA, 0); | ||
28 | break; | ||
29 | diff --git a/crypto/cryptodev.h b/crypto/cryptodev.h | ||
30 | index 4436fbf..275a55c 100644 | ||
31 | --- a/crypto/cryptodev.h | ||
32 | +++ b/crypto/cryptodev.h | ||
33 | @@ -268,6 +268,8 @@ enum cryptodev_crk_op_t { | ||
34 | CRK_DSA_SIGN = 2, | ||
35 | CRK_DSA_VERIFY = 3, | ||
36 | CRK_DH_COMPUTE_KEY = 4, | ||
37 | + CRK_DSA_GENERATE_KEY = 5, | ||
38 | + CRK_DH_GENERATE_KEY = 6, | ||
39 | CRK_ALGORITHM_ALL | ||
40 | }; | ||
41 | |||
42 | @@ -280,7 +282,8 @@ enum cryptodev_crk_op_t { | ||
43 | #define CRF_DSA_SIGN (1 << CRK_DSA_SIGN) | ||
44 | #define CRF_DSA_VERIFY (1 << CRK_DSA_VERIFY) | ||
45 | #define CRF_DH_COMPUTE_KEY (1 << CRK_DH_COMPUTE_KEY) | ||
46 | - | ||
47 | +#define CRF_DSA_GENERATE_KEY (1 << CRK_DSA_GENERATE_KEY) | ||
48 | +#define CRF_DH_GENERATE_KEY (1 << CRK_DH_GENERATE_KEY) | ||
49 | |||
50 | /* ioctl's. Compatible with old linux cryptodev.h | ||
51 | */ | ||
52 | diff --git a/ioctl.c b/ioctl.c | ||
53 | index 2eb7f03..c813c8c 100644 | ||
54 | --- a/ioctl.c | ||
55 | +++ b/ioctl.c | ||
56 | @@ -726,6 +726,23 @@ static int crypto_async_fetch_asym(struct cryptodev_pkc *pkc) | ||
57 | dh_req->z, dh_req->z_len); | ||
58 | } | ||
59 | break; | ||
60 | + case CRK_DSA_GENERATE_KEY: | ||
61 | + case CRK_DH_GENERATE_KEY: | ||
62 | + { | ||
63 | + struct keygen_req_s *key_req = &pkc_req->req_u.keygen; | ||
64 | + | ||
65 | + if (pkc_req->type == ECC_KEYGEN) { | ||
66 | + copy_to_user(ckop->crk_param[4].crp_p, key_req->pub_key, | ||
67 | + key_req->pub_key_len); | ||
68 | + copy_to_user(ckop->crk_param[5].crp_p, | ||
69 | + key_req->priv_key, key_req->priv_key_len); | ||
70 | + } else { | ||
71 | + copy_to_user(ckop->crk_param[3].crp_p, | ||
72 | + key_req->pub_key, key_req->pub_key_len); | ||
73 | + copy_to_user(ckop->crk_param[4].crp_p, | ||
74 | + key_req->priv_key, key_req->priv_key_len); | ||
75 | + } | ||
76 | + } | ||
77 | default: | ||
78 | ret = -EINVAL; | ||
79 | } | ||
80 | @@ -939,8 +956,9 @@ cryptodev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg_) | ||
81 | |||
82 | switch (cmd) { | ||
83 | case CIOCASYMFEAT: | ||
84 | - return put_user(CRF_MOD_EXP_CRT | CRF_MOD_EXP | | ||
85 | - CRF_DSA_SIGN | CRF_DSA_VERIFY | CRF_DH_COMPUTE_KEY, p); | ||
86 | + return put_user(CRF_MOD_EXP_CRT | CRF_MOD_EXP | CRF_DSA_SIGN | | ||
87 | + CRF_DSA_VERIFY | CRF_DH_COMPUTE_KEY | | ||
88 | + CRF_DSA_GENERATE_KEY, p); | ||
89 | case CRIOGET: | ||
90 | fd = clonefd(filp); | ||
91 | ret = put_user(fd, p); | ||
92 | @@ -1084,7 +1102,14 @@ cryptodev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg_) | ||
93 | if (cookie_list.cookie_available) | ||
94 | copy_to_user(arg, &cookie_list, | ||
95 | sizeof(struct pkc_cookie_list_s)); | ||
96 | + else { | ||
97 | + struct pkc_cookie_list_s *user_ck_list = (void *)arg; | ||
98 | + | ||
99 | + put_user(0, &(user_ck_list->cookie_available)); | ||
100 | + } | ||
101 | + ret = cookie_list.cookie_available; | ||
102 | } | ||
103 | + | ||
104 | return ret; | ||
105 | default: | ||
106 | return -EINVAL; | ||
107 | diff --git a/main.c b/main.c | ||
108 | index 0b7951e..c901bc7 100644 | ||
109 | --- a/main.c | ||
110 | +++ b/main.c | ||
111 | @@ -342,6 +342,85 @@ err: | ||
112 | return rc; | ||
113 | } | ||
114 | |||
115 | +int crypto_kop_keygen(struct cryptodev_pkc *pkc) | ||
116 | +{ | ||
117 | + struct kernel_crypt_kop *kop = &pkc->kop; | ||
118 | + struct crypt_kop *cop = &kop->kop; | ||
119 | + struct pkc_request *pkc_req; | ||
120 | + struct keygen_req_s *key_req; | ||
121 | + int rc, buf_size; | ||
122 | + uint8_t *buf; | ||
123 | + | ||
124 | + if (!cop->crk_param[0].crp_nbits || !cop->crk_param[1].crp_nbits || | ||
125 | + !cop->crk_param[2].crp_nbits || !cop->crk_param[3].crp_nbits || | ||
126 | + !cop->crk_param[4].crp_nbits) | ||
127 | + return -EINVAL; | ||
128 | + | ||
129 | + pkc_req = &pkc->req; | ||
130 | + key_req = &pkc_req->req_u.keygen; | ||
131 | + key_req->q_len = (cop->crk_param[0].crp_nbits + 7)/8; | ||
132 | + key_req->r_len = (cop->crk_param[1].crp_nbits + 7)/8; | ||
133 | + key_req->g_len = (cop->crk_param[2].crp_nbits + 7)/8; | ||
134 | + if (cop->crk_iparams == 3) { | ||
135 | + key_req->pub_key_len = (cop->crk_param[3].crp_nbits + 7)/8; | ||
136 | + key_req->priv_key_len = (cop->crk_param[4].crp_nbits + 7)/8; | ||
137 | + buf_size = key_req->q_len + key_req->r_len + key_req->g_len + | ||
138 | + key_req->pub_key_len + key_req->priv_key_len; | ||
139 | + pkc_req->type = DLC_KEYGEN; | ||
140 | + } else { | ||
141 | + key_req->ab_len = (cop->crk_param[3].crp_nbits + 7)/8; | ||
142 | + key_req->pub_key_len = (cop->crk_param[4].crp_nbits + 7)/8; | ||
143 | + key_req->priv_key_len = (cop->crk_param[5].crp_nbits + 7)/8; | ||
144 | + buf_size = key_req->q_len + key_req->r_len + key_req->g_len + | ||
145 | + key_req->pub_key_len + key_req->priv_key_len + | ||
146 | + key_req->ab_len; | ||
147 | + pkc_req->type = ECC_KEYGEN; | ||
148 | + pkc_req->curve_type = cop->curve_type; | ||
149 | + } | ||
150 | + | ||
151 | + buf = kzalloc(buf_size, GFP_DMA); | ||
152 | + if (!buf) | ||
153 | + return -ENOMEM; | ||
154 | + | ||
155 | + key_req->q = buf; | ||
156 | + key_req->r = key_req->q + key_req->q_len; | ||
157 | + key_req->g = key_req->r + key_req->r_len; | ||
158 | + key_req->pub_key = key_req->g + key_req->g_len; | ||
159 | + key_req->priv_key = key_req->pub_key + key_req->pub_key_len; | ||
160 | + copy_from_user(key_req->q, cop->crk_param[0].crp_p, key_req->q_len); | ||
161 | + copy_from_user(key_req->r, cop->crk_param[1].crp_p, key_req->r_len); | ||
162 | + copy_from_user(key_req->g, cop->crk_param[2].crp_p, key_req->g_len); | ||
163 | + if (cop->crk_iparams == 3) { | ||
164 | + copy_from_user(key_req->pub_key, cop->crk_param[3].crp_p, | ||
165 | + key_req->pub_key_len); | ||
166 | + copy_from_user(key_req->priv_key, cop->crk_param[4].crp_p, | ||
167 | + key_req->priv_key_len); | ||
168 | + } else { | ||
169 | + key_req->ab = key_req->priv_key + key_req->priv_key_len; | ||
170 | + copy_from_user(key_req->ab, cop->crk_param[3].crp_p, | ||
171 | + key_req->ab_len); | ||
172 | + copy_from_user(key_req->pub_key, cop->crk_param[4].crp_p, | ||
173 | + key_req->pub_key_len); | ||
174 | + copy_from_user(key_req->priv_key, cop->crk_param[5].crp_p, | ||
175 | + key_req->priv_key_len); | ||
176 | + } | ||
177 | + | ||
178 | + rc = cryptodev_pkc_offload(pkc); | ||
179 | + if (pkc->type == SYNCHRONOUS) { | ||
180 | + if (rc) | ||
181 | + goto err; | ||
182 | + } else { | ||
183 | + if (rc != -EINPROGRESS && !rc) | ||
184 | + goto err; | ||
185 | + | ||
186 | + pkc->cookie = buf; | ||
187 | + return rc; | ||
188 | + } | ||
189 | +err: | ||
190 | + kfree(buf); | ||
191 | + return rc; | ||
192 | +} | ||
193 | + | ||
194 | int crypto_kop_dh_key(struct cryptodev_pkc *pkc) | ||
195 | { | ||
196 | struct kernel_crypt_kop *kop = &pkc->kop; | ||
197 | @@ -554,6 +633,12 @@ int crypto_run_asym(struct cryptodev_pkc *pkc) | ||
198 | goto err; | ||
199 | ret = crypto_kop_dh_key(pkc); | ||
200 | break; | ||
201 | + case CRK_DH_GENERATE_KEY: | ||
202 | + case CRK_DSA_GENERATE_KEY: | ||
203 | + if ((kop->kop.crk_iparams != 3 && kop->kop.crk_iparams != 4)) | ||
204 | + goto err; | ||
205 | + ret = crypto_kop_keygen(pkc); | ||
206 | + break; | ||
207 | } | ||
208 | err: | ||
209 | return ret; | ||
210 | -- | ||
211 | 1.8.3.1 | ||
212 | |||
diff --git a/recipes-kernel/cryptodev/cryptodev-fsl/0007-RCU-stall-fixed-in-PKC-asynchronous-interface.patch b/recipes-kernel/cryptodev/cryptodev-fsl/0007-RCU-stall-fixed-in-PKC-asynchronous-interface.patch new file mode 100644 index 0000000..93a2248 --- /dev/null +++ b/recipes-kernel/cryptodev/cryptodev-fsl/0007-RCU-stall-fixed-in-PKC-asynchronous-interface.patch | |||
@@ -0,0 +1,238 @@ | |||
1 | From d60b9dbf53d63092fd292c00bb03c250c26703cf Mon Sep 17 00:00:00 2001 | ||
2 | From: Yashpal Dutta <yashpal.dutta@freescale.com> | ||
3 | Date: Fri, 7 Mar 2014 08:49:15 +0545 | ||
4 | Subject: [PATCH 7/9] RCU stall fixed in PKC asynchronous interface | ||
5 | |||
6 | Upstream-status: Pending | ||
7 | |||
8 | Signed-off-by: Yashpal Dutta <yashpal.dutta@freescale.com> | ||
9 | --- | ||
10 | ioctl.c | 23 +++++++++++------------ | ||
11 | main.c | 43 +++++++++++++++++++++++++++---------------- | ||
12 | 2 files changed, 38 insertions(+), 28 deletions(-) | ||
13 | |||
14 | diff --git a/ioctl.c b/ioctl.c | ||
15 | index c813c8c..7e4c671 100644 | ||
16 | --- a/ioctl.c | ||
17 | +++ b/ioctl.c | ||
18 | @@ -108,10 +108,9 @@ void cryptodev_complete_asym(struct crypto_async_request *req, int err) | ||
19 | complete(&res->completion); | ||
20 | } else { | ||
21 | struct crypt_priv *pcr = pkc->priv; | ||
22 | - unsigned long flags; | ||
23 | - spin_lock_irqsave(&pcr->completion_lock, flags); | ||
24 | + spin_lock_bh(&pcr->completion_lock); | ||
25 | list_add_tail(&pkc->list, &pcr->asym_completed_list); | ||
26 | - spin_unlock_irqrestore(&pcr->completion_lock, flags); | ||
27 | + spin_unlock_bh(&pcr->completion_lock); | ||
28 | /* wake for POLLIN */ | ||
29 | wake_up_interruptible(&pcr->user_waiter); | ||
30 | } | ||
31 | @@ -958,7 +957,7 @@ cryptodev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg_) | ||
32 | case CIOCASYMFEAT: | ||
33 | return put_user(CRF_MOD_EXP_CRT | CRF_MOD_EXP | CRF_DSA_SIGN | | ||
34 | CRF_DSA_VERIFY | CRF_DH_COMPUTE_KEY | | ||
35 | - CRF_DSA_GENERATE_KEY, p); | ||
36 | + CRF_DSA_GENERATE_KEY | CRF_DH_GENERATE_KEY, p); | ||
37 | case CRIOGET: | ||
38 | fd = clonefd(filp); | ||
39 | ret = put_user(fd, p); | ||
40 | @@ -997,7 +996,7 @@ cryptodev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg_) | ||
41 | case CIOCKEY: | ||
42 | { | ||
43 | struct cryptodev_pkc *pkc = | ||
44 | - kzalloc(sizeof(struct cryptodev_pkc), GFP_KERNEL); | ||
45 | + kmalloc(sizeof(struct cryptodev_pkc), GFP_KERNEL); | ||
46 | |||
47 | if (!pkc) | ||
48 | return -ENOMEM; | ||
49 | @@ -1053,7 +1052,7 @@ cryptodev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg_) | ||
50 | case CIOCASYMASYNCRYPT: | ||
51 | { | ||
52 | struct cryptodev_pkc *pkc = | ||
53 | - kzalloc(sizeof(struct cryptodev_pkc), GFP_KERNEL); | ||
54 | + kmalloc(sizeof(struct cryptodev_pkc), GFP_KERNEL); | ||
55 | ret = kop_from_user(&pkc->kop, arg); | ||
56 | |||
57 | if (unlikely(ret)) | ||
58 | @@ -1070,13 +1069,12 @@ cryptodev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg_) | ||
59 | case CIOCASYMFETCHCOOKIE: | ||
60 | { | ||
61 | struct cryptodev_pkc *pkc; | ||
62 | - unsigned long flags; | ||
63 | int i; | ||
64 | struct pkc_cookie_list_s cookie_list; | ||
65 | |||
66 | - spin_lock_irqsave(&pcr->completion_lock, flags); | ||
67 | cookie_list.cookie_available = 0; | ||
68 | for (i = 0; i < MAX_COOKIES; i++) { | ||
69 | + spin_lock_bh(&pcr->completion_lock); | ||
70 | if (!list_empty(&pcr->asym_completed_list)) { | ||
71 | /* Run a loop in the list for upto elements | ||
72 | and copy their response back */ | ||
73 | @@ -1084,6 +1082,7 @@ cryptodev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg_) | ||
74 | list_first_entry(&pcr->asym_completed_list, | ||
75 | struct cryptodev_pkc, list); | ||
76 | list_del(&pkc->list); | ||
77 | + spin_unlock_bh(&pcr->completion_lock); | ||
78 | ret = crypto_async_fetch_asym(pkc); | ||
79 | if (!ret) { | ||
80 | cookie_list.cookie_available++; | ||
81 | @@ -1093,10 +1092,10 @@ cryptodev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg_) | ||
82 | } | ||
83 | kfree(pkc); | ||
84 | } else { | ||
85 | + spin_unlock_bh(&pcr->completion_lock); | ||
86 | break; | ||
87 | } | ||
88 | } | ||
89 | - spin_unlock_irqrestore(&pcr->completion_lock, flags); | ||
90 | |||
91 | /* Reflect the updated request to user-space */ | ||
92 | if (cookie_list.cookie_available) | ||
93 | @@ -1386,14 +1385,13 @@ cryptodev_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg_) | ||
94 | case COMPAT_CIOCASYMFETCHCOOKIE: | ||
95 | { | ||
96 | struct cryptodev_pkc *pkc; | ||
97 | - unsigned long flags; | ||
98 | int i = 0; | ||
99 | struct compat_pkc_cookie_list_s cookie_list; | ||
100 | |||
101 | - spin_lock_irqsave(&pcr->completion_lock, flags); | ||
102 | cookie_list.cookie_available = 0; | ||
103 | |||
104 | for (i = 0; i < MAX_COOKIES; i++) { | ||
105 | + spin_lock_bh(&pcr->completion_lock); | ||
106 | if (!list_empty(&pcr->asym_completed_list)) { | ||
107 | /* Run a loop in the list for upto elements | ||
108 | and copy their response back */ | ||
109 | @@ -1401,6 +1399,7 @@ cryptodev_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg_) | ||
110 | list_first_entry(&pcr->asym_completed_list, | ||
111 | struct cryptodev_pkc, list); | ||
112 | list_del(&pkc->list); | ||
113 | + spin_unlock_bh(&pcr->completion_lock); | ||
114 | ret = crypto_async_fetch_asym(pkc); | ||
115 | if (!ret) { | ||
116 | cookie_list.cookie_available++; | ||
117 | @@ -1409,10 +1408,10 @@ cryptodev_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg_) | ||
118 | } | ||
119 | kfree(pkc); | ||
120 | } else { | ||
121 | + spin_unlock_bh(&pcr->completion_lock); | ||
122 | break; | ||
123 | } | ||
124 | } | ||
125 | - spin_unlock_irqrestore(&pcr->completion_lock, flags); | ||
126 | |||
127 | /* Reflect the updated request to user-space */ | ||
128 | if (cookie_list.cookie_available) | ||
129 | diff --git a/main.c b/main.c | ||
130 | index c901bc7..2747706 100644 | ||
131 | --- a/main.c | ||
132 | +++ b/main.c | ||
133 | @@ -215,7 +215,9 @@ int crypto_kop_dsasign(struct cryptodev_pkc *pkc) | ||
134 | pkc_req->type = DSA_SIGN; | ||
135 | } | ||
136 | |||
137 | - buf = kzalloc(buf_size, GFP_DMA); | ||
138 | + buf = kmalloc(buf_size, GFP_DMA); | ||
139 | + if (!buf) | ||
140 | + return -ENOMEM; | ||
141 | |||
142 | dsa_req->q = buf; | ||
143 | dsa_req->r = dsa_req->q + dsa_req->q_len; | ||
144 | @@ -298,7 +300,9 @@ int crypto_kop_dsaverify(struct cryptodev_pkc *pkc) | ||
145 | pkc_req->type = DSA_VERIFY; | ||
146 | } | ||
147 | |||
148 | - buf = kzalloc(buf_size, GFP_DMA); | ||
149 | + buf = kmalloc(buf_size, GFP_DMA); | ||
150 | + if (!buf) | ||
151 | + return -ENOMEM; | ||
152 | |||
153 | dsa_req->q = buf; | ||
154 | dsa_req->r = dsa_req->q + dsa_req->q_len; | ||
155 | @@ -378,7 +382,7 @@ int crypto_kop_keygen(struct cryptodev_pkc *pkc) | ||
156 | pkc_req->curve_type = cop->curve_type; | ||
157 | } | ||
158 | |||
159 | - buf = kzalloc(buf_size, GFP_DMA); | ||
160 | + buf = kmalloc(buf_size, GFP_DMA); | ||
161 | if (!buf) | ||
162 | return -ENOMEM; | ||
163 | |||
164 | @@ -390,25 +394,28 @@ int crypto_kop_keygen(struct cryptodev_pkc *pkc) | ||
165 | copy_from_user(key_req->q, cop->crk_param[0].crp_p, key_req->q_len); | ||
166 | copy_from_user(key_req->r, cop->crk_param[1].crp_p, key_req->r_len); | ||
167 | copy_from_user(key_req->g, cop->crk_param[2].crp_p, key_req->g_len); | ||
168 | - if (cop->crk_iparams == 3) { | ||
169 | - copy_from_user(key_req->pub_key, cop->crk_param[3].crp_p, | ||
170 | - key_req->pub_key_len); | ||
171 | - copy_from_user(key_req->priv_key, cop->crk_param[4].crp_p, | ||
172 | - key_req->priv_key_len); | ||
173 | - } else { | ||
174 | + if (cop->crk_iparams == 4) { | ||
175 | key_req->ab = key_req->priv_key + key_req->priv_key_len; | ||
176 | copy_from_user(key_req->ab, cop->crk_param[3].crp_p, | ||
177 | key_req->ab_len); | ||
178 | - copy_from_user(key_req->pub_key, cop->crk_param[4].crp_p, | ||
179 | - key_req->pub_key_len); | ||
180 | - copy_from_user(key_req->priv_key, cop->crk_param[5].crp_p, | ||
181 | - key_req->priv_key_len); | ||
182 | } | ||
183 | |||
184 | rc = cryptodev_pkc_offload(pkc); | ||
185 | if (pkc->type == SYNCHRONOUS) { | ||
186 | if (rc) | ||
187 | goto err; | ||
188 | + | ||
189 | + if (cop->crk_iparams == 4) { | ||
190 | + copy_to_user(cop->crk_param[4].crp_p, key_req->pub_key, | ||
191 | + key_req->pub_key_len); | ||
192 | + copy_to_user(cop->crk_param[5].crp_p, key_req->priv_key, | ||
193 | + key_req->priv_key_len); | ||
194 | + } else { | ||
195 | + copy_to_user(cop->crk_param[3].crp_p, key_req->pub_key, | ||
196 | + key_req->pub_key_len); | ||
197 | + copy_to_user(cop->crk_param[4].crp_p, | ||
198 | + key_req->priv_key, key_req->priv_key_len); | ||
199 | + } | ||
200 | } else { | ||
201 | if (rc != -EINPROGRESS && !rc) | ||
202 | goto err; | ||
203 | @@ -447,7 +454,9 @@ int crypto_kop_dh_key(struct cryptodev_pkc *pkc) | ||
204 | pkc_req->type = DH_COMPUTE_KEY; | ||
205 | } | ||
206 | buf_size += dh_req->z_len; | ||
207 | - buf = kzalloc(buf_size, GFP_DMA); | ||
208 | + buf = kmalloc(buf_size, GFP_DMA); | ||
209 | + if (!buf) | ||
210 | + return -ENOMEM; | ||
211 | dh_req->q = buf; | ||
212 | dh_req->s = dh_req->q + dh_req->q_len; | ||
213 | dh_req->pub_key = dh_req->s + dh_req->s_len; | ||
214 | @@ -508,9 +517,11 @@ int crypto_modexp_crt(struct cryptodev_pkc *pkc) | ||
215 | rsa_req->dq_len = (cop->crk_param[4].crp_nbits + 7)/8; | ||
216 | rsa_req->c_len = (cop->crk_param[5].crp_nbits + 7)/8; | ||
217 | rsa_req->f_len = (cop->crk_param[6].crp_nbits + 7)/8; | ||
218 | - buf = kzalloc(rsa_req->p_len + rsa_req->q_len + rsa_req->f_len + | ||
219 | + buf = kmalloc(rsa_req->p_len + rsa_req->q_len + rsa_req->f_len + | ||
220 | rsa_req->dp_len + rsa_req->dp_len + rsa_req->c_len + | ||
221 | rsa_req->g_len, GFP_DMA); | ||
222 | + if (!buf) | ||
223 | + return -ENOMEM; | ||
224 | rsa_req->p = buf; | ||
225 | rsa_req->q = rsa_req->p + rsa_req->p_len; | ||
226 | rsa_req->g = rsa_req->q + rsa_req->q_len; | ||
227 | @@ -563,7 +574,7 @@ int crypto_bn_modexp(struct cryptodev_pkc *pkc) | ||
228 | rsa_req->e_len = (cop->crk_param[1].crp_nbits + 7)/8; | ||
229 | rsa_req->n_len = (cop->crk_param[2].crp_nbits + 7)/8; | ||
230 | rsa_req->g_len = (cop->crk_param[3].crp_nbits + 7)/8; | ||
231 | - buf = kzalloc(rsa_req->f_len + rsa_req->e_len + rsa_req->n_len | ||
232 | + buf = kmalloc(rsa_req->f_len + rsa_req->e_len + rsa_req->n_len | ||
233 | + rsa_req->g_len, GFP_DMA); | ||
234 | if (!buf) | ||
235 | return -ENOMEM; | ||
236 | -- | ||
237 | 1.8.3.1 | ||
238 | |||
diff --git a/recipes-kernel/cryptodev/cryptodev-fsl/0008-Add-RSA-Key-generation-offloading.patch b/recipes-kernel/cryptodev/cryptodev-fsl/0008-Add-RSA-Key-generation-offloading.patch new file mode 100644 index 0000000..affb2e7 --- /dev/null +++ b/recipes-kernel/cryptodev/cryptodev-fsl/0008-Add-RSA-Key-generation-offloading.patch | |||
@@ -0,0 +1,170 @@ | |||
1 | From af5e4289f60c38ab17adab14c82d6204d155f25f Mon Sep 17 00:00:00 2001 | ||
2 | From: Hou Zhiqiang <B48286@freescale.com> | ||
3 | Date: Wed, 19 Mar 2014 14:02:46 +0800 | ||
4 | Subject: [PATCH 8/9] Add RSA Key generation offloading | ||
5 | |||
6 | Upstream-status: Pending | ||
7 | |||
8 | Signed-off-by: Hou Zhiqiang <B48286@freescale.com> | ||
9 | Tested-by: Cristian Stoica <cristian.stoica@freescale.com> | ||
10 | --- | ||
11 | cryptlib.c | 1 + | ||
12 | crypto/cryptodev.h | 2 ++ | ||
13 | ioctl.c | 3 +- | ||
14 | main.c | 80 +++++++++++++++++++++++++++++++++++++++++++++++++++++- | ||
15 | 4 files changed, 84 insertions(+), 2 deletions(-) | ||
16 | |||
17 | diff --git a/cryptlib.c b/cryptlib.c | ||
18 | index 47cd568..4dd1847 100644 | ||
19 | --- a/cryptlib.c | ||
20 | +++ b/cryptlib.c | ||
21 | @@ -441,6 +441,7 @@ int cryptodev_pkc_offload(struct cryptodev_pkc *pkc) | ||
22 | struct pkc_request *pkc_req = &pkc->req, *pkc_requested; | ||
23 | |||
24 | switch (pkc_req->type) { | ||
25 | + case RSA_KEYGEN: | ||
26 | case RSA_PUB: | ||
27 | case RSA_PRIV_FORM1: | ||
28 | case RSA_PRIV_FORM2: | ||
29 | diff --git a/crypto/cryptodev.h b/crypto/cryptodev.h | ||
30 | index 275a55c..d0cc542 100644 | ||
31 | --- a/crypto/cryptodev.h | ||
32 | +++ b/crypto/cryptodev.h | ||
33 | @@ -270,6 +270,7 @@ enum cryptodev_crk_op_t { | ||
34 | CRK_DH_COMPUTE_KEY = 4, | ||
35 | CRK_DSA_GENERATE_KEY = 5, | ||
36 | CRK_DH_GENERATE_KEY = 6, | ||
37 | + CRK_RSA_GENERATE_KEY = 7, | ||
38 | CRK_ALGORITHM_ALL | ||
39 | }; | ||
40 | |||
41 | @@ -279,6 +280,7 @@ enum cryptodev_crk_op_t { | ||
42 | */ | ||
43 | #define CRF_MOD_EXP (1 << CRK_MOD_EXP) | ||
44 | #define CRF_MOD_EXP_CRT (1 << CRK_MOD_EXP_CRT) | ||
45 | +#define CRF_RSA_GENERATE_KEY (1 << CRK_RSA_GENERATE_KEY) | ||
46 | #define CRF_DSA_SIGN (1 << CRK_DSA_SIGN) | ||
47 | #define CRF_DSA_VERIFY (1 << CRK_DSA_VERIFY) | ||
48 | #define CRF_DH_COMPUTE_KEY (1 << CRK_DH_COMPUTE_KEY) | ||
49 | diff --git a/ioctl.c b/ioctl.c | ||
50 | index 7e4c671..14888d6 100644 | ||
51 | --- a/ioctl.c | ||
52 | +++ b/ioctl.c | ||
53 | @@ -957,7 +957,8 @@ cryptodev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg_) | ||
54 | case CIOCASYMFEAT: | ||
55 | return put_user(CRF_MOD_EXP_CRT | CRF_MOD_EXP | CRF_DSA_SIGN | | ||
56 | CRF_DSA_VERIFY | CRF_DH_COMPUTE_KEY | | ||
57 | - CRF_DSA_GENERATE_KEY | CRF_DH_GENERATE_KEY, p); | ||
58 | + CRF_DSA_GENERATE_KEY | CRF_DH_GENERATE_KEY | | ||
59 | + CRF_RSA_GENERATE_KEY, p); | ||
60 | case CRIOGET: | ||
61 | fd = clonefd(filp); | ||
62 | ret = put_user(fd, p); | ||
63 | diff --git a/main.c b/main.c | ||
64 | index 2747706..14dcf40 100644 | ||
65 | --- a/main.c | ||
66 | +++ b/main.c | ||
67 | @@ -346,6 +346,82 @@ err: | ||
68 | return rc; | ||
69 | } | ||
70 | |||
71 | +int crypto_kop_rsa_keygen(struct cryptodev_pkc *pkc) | ||
72 | +{ | ||
73 | + struct kernel_crypt_kop *kop = &pkc->kop; | ||
74 | + struct crypt_kop *cop = &kop->kop; | ||
75 | + struct pkc_request *pkc_req; | ||
76 | + struct rsa_keygen_req_s *key_req; | ||
77 | + int rc, buf_size; | ||
78 | + uint8_t *buf; | ||
79 | + | ||
80 | + if (!cop->crk_param[0].crp_nbits || !cop->crk_param[1].crp_nbits || | ||
81 | + !cop->crk_param[2].crp_nbits || !cop->crk_param[3].crp_nbits || | ||
82 | + !cop->crk_param[4].crp_nbits || !cop->crk_param[5].crp_nbits || | ||
83 | + !cop->crk_param[6].crp_nbits) | ||
84 | + return -EINVAL; | ||
85 | + | ||
86 | + pkc_req = &pkc->req; | ||
87 | + pkc_req->type = RSA_KEYGEN; | ||
88 | + key_req = &pkc_req->req_u.rsa_keygen; | ||
89 | + key_req->n_len = (cop->crk_param[2].crp_nbits + 7)/8; | ||
90 | + key_req->p_len = (cop->crk_param[0].crp_nbits + 7) / 8; | ||
91 | + key_req->q_len = (cop->crk_param[1].crp_nbits + 7) / 8; | ||
92 | + key_req->n_len = (cop->crk_param[2].crp_nbits + 7) / 8; | ||
93 | + key_req->d_len = (cop->crk_param[3].crp_nbits + 7) / 8; | ||
94 | + key_req->dp_len = (cop->crk_param[4].crp_nbits + 7) / 8; | ||
95 | + key_req->dq_len = (cop->crk_param[5].crp_nbits + 7) / 8; | ||
96 | + key_req->c_len = (cop->crk_param[6].crp_nbits + 7) / 8; | ||
97 | + | ||
98 | + buf_size = key_req->p_len + key_req->q_len + key_req->n_len + | ||
99 | + key_req->d_len + key_req->dp_len + | ||
100 | + key_req->dq_len + key_req->c_len; | ||
101 | + | ||
102 | + buf = kmalloc(buf_size, GFP_DMA); | ||
103 | + if (!buf) | ||
104 | + return -ENOMEM; | ||
105 | + key_req->p = buf; | ||
106 | + key_req->q = key_req->p + key_req->p_len; | ||
107 | + key_req->n = key_req->q + key_req->q_len; | ||
108 | + key_req->d = key_req->n + key_req->n_len; | ||
109 | + key_req->dp = key_req->d + key_req->d_len; | ||
110 | + key_req->dq = key_req->dp + key_req->dp_len; | ||
111 | + key_req->c = key_req->dq + key_req->dq_len; | ||
112 | + | ||
113 | + rc = cryptodev_pkc_offload(pkc); | ||
114 | + | ||
115 | + if (pkc->type == SYNCHRONOUS) { | ||
116 | + if (rc) | ||
117 | + goto err; | ||
118 | + | ||
119 | + copy_to_user(cop->crk_param[0].crp_p, | ||
120 | + key_req->p, key_req->p_len); | ||
121 | + copy_to_user(cop->crk_param[1].crp_p, | ||
122 | + key_req->q, key_req->q_len); | ||
123 | + copy_to_user(cop->crk_param[2].crp_p, | ||
124 | + key_req->n, key_req->n_len); | ||
125 | + copy_to_user(cop->crk_param[3].crp_p, | ||
126 | + key_req->d, key_req->d_len); | ||
127 | + copy_to_user(cop->crk_param[4].crp_p, | ||
128 | + key_req->dp, key_req->dp_len); | ||
129 | + copy_to_user(cop->crk_param[5].crp_p, | ||
130 | + key_req->dq, key_req->dq_len); | ||
131 | + copy_to_user(cop->crk_param[6].crp_p, | ||
132 | + key_req->c, key_req->c_len); | ||
133 | + } else { | ||
134 | + if (rc != -EINPROGRESS && !rc) { | ||
135 | + printk("%s: Failed\n", __func__); | ||
136 | + goto err; | ||
137 | + } | ||
138 | + pkc->cookie = buf; | ||
139 | + return rc; | ||
140 | + } | ||
141 | +err: | ||
142 | + kfree(buf); | ||
143 | + return rc; | ||
144 | + | ||
145 | +} | ||
146 | + | ||
147 | int crypto_kop_keygen(struct cryptodev_pkc *pkc) | ||
148 | { | ||
149 | struct kernel_crypt_kop *kop = &pkc->kop; | ||
150 | @@ -385,7 +461,6 @@ int crypto_kop_keygen(struct cryptodev_pkc *pkc) | ||
151 | buf = kmalloc(buf_size, GFP_DMA); | ||
152 | if (!buf) | ||
153 | return -ENOMEM; | ||
154 | - | ||
155 | key_req->q = buf; | ||
156 | key_req->r = key_req->q + key_req->q_len; | ||
157 | key_req->g = key_req->r + key_req->r_len; | ||
158 | @@ -650,6 +725,9 @@ int crypto_run_asym(struct cryptodev_pkc *pkc) | ||
159 | goto err; | ||
160 | ret = crypto_kop_keygen(pkc); | ||
161 | break; | ||
162 | + case CRK_RSA_GENERATE_KEY: | ||
163 | + ret = crypto_kop_rsa_keygen(pkc); | ||
164 | + break; | ||
165 | } | ||
166 | err: | ||
167 | return ret; | ||
168 | -- | ||
169 | 1.8.3.1 | ||
170 | |||
diff --git a/recipes-kernel/cryptodev/cryptodev-fsl/0009-Fixed-compilation-error-of-openssl-with-fsl-cryptode.patch b/recipes-kernel/cryptodev/cryptodev-fsl/0009-Fixed-compilation-error-of-openssl-with-fsl-cryptode.patch new file mode 100644 index 0000000..32757ca --- /dev/null +++ b/recipes-kernel/cryptodev/cryptodev-fsl/0009-Fixed-compilation-error-of-openssl-with-fsl-cryptode.patch | |||
@@ -0,0 +1,160 @@ | |||
1 | From e791b55b03d295ee11476382a7bd93ab131e2e52 Mon Sep 17 00:00:00 2001 | ||
2 | From: Yashpal Dutta <yashpal.dutta@freescale.com> | ||
3 | Date: Thu, 17 Apr 2014 07:08:47 +0545 | ||
4 | Subject: [PATCH 9/9] Fixed compilation error of openssl with fsl cryptodev | ||
5 | |||
6 | Upstream-status: Pending | ||
7 | |||
8 | Signed-off-by: Yashpal Dutta <yashpal.dutta@freescale.com> | ||
9 | Tested-by: Cristian Stoica <cristian.stoica@freescale.com> | ||
10 | --- | ||
11 | authenc.c | 1 + | ||
12 | cryptlib.c | 9 ++++----- | ||
13 | crypto/cryptodev.h | 9 ++++++++- | ||
14 | cryptodev_int.h | 2 +- | ||
15 | ioctl.c | 8 ++++++-- | ||
16 | main.c | 1 + | ||
17 | 6 files changed, 21 insertions(+), 9 deletions(-) | ||
18 | |||
19 | diff --git a/authenc.c b/authenc.c | ||
20 | index ef0d3db..2aa4d38 100644 | ||
21 | --- a/authenc.c | ||
22 | +++ b/authenc.c | ||
23 | @@ -2,6 +2,7 @@ | ||
24 | * Driver for /dev/crypto device (aka CryptoDev) | ||
25 | * | ||
26 | * Copyright (c) 2011, 2012 OpenSSL Software Foundation, Inc. | ||
27 | + * Copyright (c) 2014 Freescale Semiconductor, Inc. | ||
28 | * | ||
29 | * Author: Nikos Mavrogiannopoulos | ||
30 | * | ||
31 | diff --git a/cryptlib.c b/cryptlib.c | ||
32 | index 4dd1847..ec6693e 100644 | ||
33 | --- a/cryptlib.c | ||
34 | +++ b/cryptlib.c | ||
35 | @@ -4,8 +4,7 @@ | ||
36 | * Copyright (c) 2010,2011 Nikos Mavrogiannopoulos <nmav@gnutls.org> | ||
37 | * Portions Copyright (c) 2010 Michael Weiser | ||
38 | * Portions Copyright (c) 2010 Phil Sutter | ||
39 | - * | ||
40 | - * Copyright 2012 Freescale Semiconductor, Inc. | ||
41 | + * Copyright 2012-2014 Freescale Semiconductor, Inc. | ||
42 | * | ||
43 | * This file is part of linux cryptodev. | ||
44 | * | ||
45 | @@ -144,7 +143,7 @@ int cryptodev_cipher_init(struct cipher_data *out, const char *alg_name, | ||
46 | if (alg->max_keysize > 0 && | ||
47 | unlikely((keylen < alg->min_keysize) || | ||
48 | (keylen > alg->max_keysize))) { | ||
49 | - ddebug(1, "Wrong keylen '%zu' for algorithm '%s'. Use %u to %u.", | ||
50 | + ddebug(1, "Wrong keylen '%u' for algorithm '%s'. Use %u to %u.", | ||
51 | keylen, alg_name, alg->min_keysize, alg->max_keysize); | ||
52 | ret = -EINVAL; | ||
53 | goto error; | ||
54 | @@ -171,7 +170,7 @@ int cryptodev_cipher_init(struct cipher_data *out, const char *alg_name, | ||
55 | } | ||
56 | |||
57 | if (unlikely(ret)) { | ||
58 | - ddebug(1, "Setting key failed for %s-%zu.", alg_name, keylen*8); | ||
59 | + ddebug(1, "Setting key failed for %s-%u.", alg_name, keylen*8); | ||
60 | ret = -EINVAL; | ||
61 | goto error; | ||
62 | } | ||
63 | @@ -338,7 +337,7 @@ int cryptodev_hash_init(struct hash_data *hdata, const char *alg_name, | ||
64 | if (hmac_mode != 0) { | ||
65 | ret = crypto_ahash_setkey(hdata->async.s, mackey, mackeylen); | ||
66 | if (unlikely(ret)) { | ||
67 | - ddebug(1, "Setting hmac key failed for %s-%zu.", | ||
68 | + ddebug(1, "Setting hmac key failed for %s-%u.", | ||
69 | alg_name, mackeylen*8); | ||
70 | ret = -EINVAL; | ||
71 | goto error; | ||
72 | diff --git a/crypto/cryptodev.h b/crypto/cryptodev.h | ||
73 | index d0cc542..e7edd97 100644 | ||
74 | --- a/crypto/cryptodev.h | ||
75 | +++ b/crypto/cryptodev.h | ||
76 | @@ -234,6 +234,13 @@ struct crypt_auth_op { | ||
77 | #define CRYPTO_ALG_FLAG_RNG_ENABLE 2 | ||
78 | #define CRYPTO_ALG_FLAG_DSA_SHA 4 | ||
79 | |||
80 | +enum ec_curve_t { | ||
81 | + EC_DISCRETE_LOG, | ||
82 | + EC_PRIME, | ||
83 | + EC_BINARY, | ||
84 | + MAX_EC_TYPE | ||
85 | +}; | ||
86 | + | ||
87 | struct crparam { | ||
88 | __u8 *crp_p; | ||
89 | __u32 crp_nbits; | ||
90 | @@ -249,7 +256,7 @@ struct crypt_kop { | ||
91 | __u16 crk_oparams; | ||
92 | __u32 crk_pad1; | ||
93 | struct crparam crk_param[CRK_MAXPARAM]; | ||
94 | - enum curve_t curve_type; /* 0 == Discrete Log, | ||
95 | + enum ec_curve_t curve_type; /* 0 == Discrete Log, | ||
96 | 1 = EC_PRIME, 2 = EC_BINARY */ | ||
97 | void *cookie; | ||
98 | }; | ||
99 | diff --git a/cryptodev_int.h b/cryptodev_int.h | ||
100 | index 5347cae..c83c885 100644 | ||
101 | --- a/cryptodev_int.h | ||
102 | +++ b/cryptodev_int.h | ||
103 | @@ -88,7 +88,7 @@ struct compat_crypt_kop { | ||
104 | uint16_t crk_oparams; | ||
105 | uint32_t crk_pad1; | ||
106 | struct compat_crparam crk_param[CRK_MAXPARAM]; | ||
107 | - enum curve_t curve_type; /* 0 == Discrete Log, 1 = EC_PRIME, | ||
108 | + enum ec_curve_t curve_type; /* 0 == Discrete Log, 1 = EC_PRIME, | ||
109 | 2 = EC_BINARY */ | ||
110 | compat_uptr_t cookie; | ||
111 | }; | ||
112 | diff --git a/ioctl.c b/ioctl.c | ||
113 | index 14888d6..20ab4ca 100644 | ||
114 | --- a/ioctl.c | ||
115 | +++ b/ioctl.c | ||
116 | @@ -4,7 +4,7 @@ | ||
117 | * Copyright (c) 2004 Michal Ludvig <mludvig@logix.net.nz>, SuSE Labs | ||
118 | * Copyright (c) 2009,2010,2011 Nikos Mavrogiannopoulos <nmav@gnutls.org> | ||
119 | * Copyright (c) 2010 Phil Sutter | ||
120 | - * Copyright 2012 Freescale Semiconductor, Inc. | ||
121 | + * Copyright 2012-2014 Freescale Semiconductor, Inc. | ||
122 | * | ||
123 | * This file is part of linux cryptodev. | ||
124 | * | ||
125 | @@ -501,6 +501,7 @@ cryptodev_open(struct inode *inode, struct file *filp) | ||
126 | INIT_LIST_HEAD(&pcr->done.list); | ||
127 | INIT_LIST_HEAD(&pcr->asym_completed_list); | ||
128 | spin_lock_init(&pcr->completion_lock); | ||
129 | + | ||
130 | INIT_WORK(&pcr->cryptask, cryptask_routine); | ||
131 | |||
132 | init_waitqueue_head(&pcr->user_waiter); | ||
133 | @@ -780,8 +781,11 @@ static int fill_kcop_from_cop(struct kernel_crypt_op *kcop, struct fcrypt *fcr) | ||
134 | |||
135 | if (cop->iv) { | ||
136 | rc = copy_from_user(kcop->iv, cop->iv, kcop->ivlen); | ||
137 | - if (unlikely(rc)) | ||
138 | + if (unlikely(rc)) { | ||
139 | + derr(1, "error copying IV (%d bytes), copy_from_user returned %d for address %p", | ||
140 | + kcop->ivlen, rc, cop->iv); | ||
141 | return -EFAULT; | ||
142 | + } | ||
143 | } | ||
144 | |||
145 | return 0; | ||
146 | diff --git a/main.c b/main.c | ||
147 | index 14dcf40..6365911 100644 | ||
148 | --- a/main.c | ||
149 | +++ b/main.c | ||
150 | @@ -3,6 +3,7 @@ | ||
151 | * | ||
152 | * Copyright (c) 2004 Michal Ludvig <mludvig@logix.net.nz>, SuSE Labs | ||
153 | * Copyright (c) 2009-2013 Nikos Mavrogiannopoulos <nmav@gnutls.org> | ||
154 | + * Copyright (c) 2014 Freescale Semiconductor, Inc. | ||
155 | * | ||
156 | * This file is part of linux cryptodev. | ||
157 | * | ||
158 | -- | ||
159 | 2.2.0 | ||
160 | |||
diff --git a/recipes-kernel/cryptodev/cryptodev-linux_1.6.bbappend b/recipes-kernel/cryptodev/cryptodev-linux_1.6.bbappend new file mode 100644 index 0000000..3cbbb3d --- /dev/null +++ b/recipes-kernel/cryptodev/cryptodev-linux_1.6.bbappend | |||
@@ -0,0 +1,2 @@ | |||
1 | require recipes-kernel/cryptodev/cryptodev-fsl.inc | ||
2 | |||
diff --git a/recipes-kernel/cryptodev/cryptodev-module_1.6.bbappend b/recipes-kernel/cryptodev/cryptodev-module_1.6.bbappend new file mode 100644 index 0000000..2bf012c --- /dev/null +++ b/recipes-kernel/cryptodev/cryptodev-module_1.6.bbappend | |||
@@ -0,0 +1,12 @@ | |||
1 | require recipes-kernel/cryptodev/cryptodev-fsl.inc | ||
2 | |||
3 | inherit qoriq_build_64bit_kernel | ||
4 | |||
5 | do_install_append_qoriq-ppc () { | ||
6 | rm -fr ${D}/usr | ||
7 | } | ||
8 | |||
9 | # Currently pkc-host does not support RSA_KEYGEN, remove this | ||
10 | # if it is fixed. | ||
11 | SRC_URI_append_qoriq-ppc = "${@base_contains('DISTRO_FEATURES', 'c29x_pkc', ' file://0001-don-t-advertise-RSA-keygen.patch', '', d)}" | ||
12 | |||
diff --git a/recipes-kernel/ipc/ipc-modules-multi_git.bb b/recipes-kernel/ipc/ipc-modules-multi_git.bb new file mode 100644 index 0000000..e5dc115 --- /dev/null +++ b/recipes-kernel/ipc/ipc-modules-multi_git.bb | |||
@@ -0,0 +1,11 @@ | |||
1 | require ipc-modules.inc | ||
2 | |||
3 | EXTRA_OEMAKE ="KERNEL_DIR=${STAGING_KERNEL_DIR} ${SOC}=1 CONFIG_MULTI_RAT=1" | ||
4 | |||
5 | do_install(){ | ||
6 | install -d ${D}/usr/driver/IPC/multi_rat | ||
7 | install -m 755 ${S}/kernel/*.ko ${D}/usr/driver/IPC/multi_rat | ||
8 | } | ||
9 | |||
10 | FILES_${PN} += "/usr/driver/IPC/multi_rat/*.ko" | ||
11 | FILES_${PN}-dbg += "/usr/driver/IPC/multi_rat/.debug" | ||
diff --git a/recipes-kernel/ipc/ipc-modules-single_git.bb b/recipes-kernel/ipc/ipc-modules-single_git.bb new file mode 100644 index 0000000..03817e0 --- /dev/null +++ b/recipes-kernel/ipc/ipc-modules-single_git.bb | |||
@@ -0,0 +1,11 @@ | |||
1 | require ipc-modules.inc | ||
2 | |||
3 | EXTRA_OEMAKE ="KERNEL_DIR=${STAGING_KERNEL_DIR} ${SOC}=1" | ||
4 | |||
5 | do_install(){ | ||
6 | install -d ${D}/usr/driver/IPC/single_rat | ||
7 | install -m 755 ${S}/kernel/*.ko ${D}/usr/driver/IPC/single_rat | ||
8 | } | ||
9 | |||
10 | FILES_${PN} += "/usr/driver/IPC/single_rat/*.ko" | ||
11 | FILES_${PN}-dbg += "/usr/driver/IPC/single_rat/.debug" | ||
diff --git a/recipes-kernel/ipc/ipc-modules.inc b/recipes-kernel/ipc/ipc-modules.inc new file mode 100644 index 0000000..e403e6b --- /dev/null +++ b/recipes-kernel/ipc/ipc-modules.inc | |||
@@ -0,0 +1,21 @@ | |||
1 | SUMMARY = "Linux IPC KERNEL MODULE " | ||
2 | DESCRIPTION = "DSP boot application and ipc test application" | ||
3 | LICENSE = "BSD" | ||
4 | LIC_FILES_CHKSUM = "file://COPYING;md5=fa38cd73d71527dc6efb546474f64d10" | ||
5 | |||
6 | require recipes-bsp/ipc/ipc.inc | ||
7 | |||
8 | inherit module qoriq_build_64bit_kernel | ||
9 | |||
10 | S = "${WORKDIR}/git" | ||
11 | |||
12 | do_compile_prepend () { | ||
13 | cd ${S}/kernel | ||
14 | case ${MACHINE} in | ||
15 | bsc9132qds|bsc9131rdb) SOC=B913x;; | ||
16 | b4860qds|b4420qds) SOC=B4860;; | ||
17 | esac | ||
18 | } | ||
19 | |||
20 | INHIBIT_PACKAGE_STRIP = "1" | ||
21 | |||
diff --git a/recipes-kernel/linux/files/0001-ALSA-CVE-2014-4652.patch b/recipes-kernel/linux/files/0001-ALSA-CVE-2014-4652.patch new file mode 100644 index 0000000..0130768 --- /dev/null +++ b/recipes-kernel/linux/files/0001-ALSA-CVE-2014-4652.patch | |||
@@ -0,0 +1,140 @@ | |||
1 | From ed81e6b21790b717cda5f5bab2bdb07d2ce17ab1 Mon Sep 17 00:00:00 2001 | ||
2 | From: Lars-Peter Clausen <lars@metafoo.de> | ||
3 | Date: Wed, 18 Jun 2014 13:32:31 +0200 | ||
4 | Subject: [PATCH] ALSA: control: Protect user controls against concurrent | ||
5 | access | ||
6 | |||
7 | commit 07f4d9d74a04aa7c72c5dae0ef97565f28f17b92 upstream. | ||
8 | |||
9 | The user-control put and get handlers as well as the tlv do not protect against | ||
10 | concurrent access from multiple threads. Since the state of the control is not | ||
11 | updated atomically it is possible that either two write operations or a write | ||
12 | and a read operation race against each other. Both can lead to arbitrary memory | ||
13 | disclosure. This patch introduces a new lock that protects user-controls from | ||
14 | concurrent access. Since applications typically access controls sequentially | ||
15 | than in parallel a single lock per card should be fine. | ||
16 | |||
17 | This fixes CVE-2014-4652 | ||
18 | Upstream-Status: Backport | ||
19 | |||
20 | Signed-off-by: Lars-Peter Clausen <lars@metafoo.de> | ||
21 | Acked-by: Jaroslav Kysela <perex@perex.cz> | ||
22 | Signed-off-by: Takashi Iwai <tiwai@suse.de> | ||
23 | Signed-off-by: Jiri Slaby <jslaby@suse.cz> | ||
24 | Signed-off-by: Sona Sarmadi <sona.sarmadi@enea.com> | ||
25 | --- | ||
26 | include/sound/core.h | 2 ++ | ||
27 | sound/core/control.c | 31 +++++++++++++++++++++++++------ | ||
28 | sound/core/init.c | 1 + | ||
29 | 3 files changed, 28 insertions(+), 6 deletions(-) | ||
30 | |||
31 | diff --git a/include/sound/core.h b/include/sound/core.h | ||
32 | index 2a14f1f..d6bc961 100644 | ||
33 | --- a/include/sound/core.h | ||
34 | +++ b/include/sound/core.h | ||
35 | @@ -121,6 +121,8 @@ struct snd_card { | ||
36 | int user_ctl_count; /* count of all user controls */ | ||
37 | struct list_head controls; /* all controls for this card */ | ||
38 | struct list_head ctl_files; /* active control files */ | ||
39 | + struct mutex user_ctl_lock; /* protects user controls against | ||
40 | + concurrent access */ | ||
41 | |||
42 | struct snd_info_entry *proc_root; /* root for soundcard specific files */ | ||
43 | struct snd_info_entry *proc_id; /* the card id */ | ||
44 | diff --git a/sound/core/control.c b/sound/core/control.c | ||
45 | index d8aa206..183fab2 100644 | ||
46 | --- a/sound/core/control.c | ||
47 | +++ b/sound/core/control.c | ||
48 | @@ -992,6 +992,7 @@ static int snd_ctl_elem_unlock(struct snd_ctl_file *file, | ||
49 | |||
50 | struct user_element { | ||
51 | struct snd_ctl_elem_info info; | ||
52 | + struct snd_card *card; | ||
53 | void *elem_data; /* element data */ | ||
54 | unsigned long elem_data_size; /* size of element data in bytes */ | ||
55 | void *tlv_data; /* TLV data */ | ||
56 | @@ -1035,7 +1036,9 @@ static int snd_ctl_elem_user_get(struct snd_kcontrol *kcontrol, | ||
57 | { | ||
58 | struct user_element *ue = kcontrol->private_data; | ||
59 | |||
60 | + mutex_lock(&ue->card->user_ctl_lock); | ||
61 | memcpy(&ucontrol->value, ue->elem_data, ue->elem_data_size); | ||
62 | + mutex_unlock(&ue->card->user_ctl_lock); | ||
63 | return 0; | ||
64 | } | ||
65 | |||
66 | @@ -1044,10 +1047,12 @@ static int snd_ctl_elem_user_put(struct snd_kcontrol *kcontrol, | ||
67 | { | ||
68 | int change; | ||
69 | struct user_element *ue = kcontrol->private_data; | ||
70 | - | ||
71 | + | ||
72 | + mutex_lock(&ue->card->user_ctl_lock); | ||
73 | change = memcmp(&ucontrol->value, ue->elem_data, ue->elem_data_size) != 0; | ||
74 | if (change) | ||
75 | memcpy(ue->elem_data, &ucontrol->value, ue->elem_data_size); | ||
76 | + mutex_unlock(&ue->card->user_ctl_lock); | ||
77 | return change; | ||
78 | } | ||
79 | |||
80 | @@ -1067,19 +1072,32 @@ static int snd_ctl_elem_user_tlv(struct snd_kcontrol *kcontrol, | ||
81 | new_data = memdup_user(tlv, size); | ||
82 | if (IS_ERR(new_data)) | ||
83 | return PTR_ERR(new_data); | ||
84 | + mutex_lock(&ue->card->user_ctl_lock); | ||
85 | change = ue->tlv_data_size != size; | ||
86 | if (!change) | ||
87 | change = memcmp(ue->tlv_data, new_data, size); | ||
88 | kfree(ue->tlv_data); | ||
89 | ue->tlv_data = new_data; | ||
90 | ue->tlv_data_size = size; | ||
91 | + mutex_unlock(&ue->card->user_ctl_lock); | ||
92 | } else { | ||
93 | - if (! ue->tlv_data_size || ! ue->tlv_data) | ||
94 | - return -ENXIO; | ||
95 | - if (size < ue->tlv_data_size) | ||
96 | - return -ENOSPC; | ||
97 | + int ret = 0; | ||
98 | + | ||
99 | + mutex_lock(&ue->card->user_ctl_lock); | ||
100 | + if (!ue->tlv_data_size || !ue->tlv_data) { | ||
101 | + ret = -ENXIO; | ||
102 | + goto err_unlock; | ||
103 | + } | ||
104 | + if (size < ue->tlv_data_size) { | ||
105 | + ret = -ENOSPC; | ||
106 | + goto err_unlock; | ||
107 | + } | ||
108 | if (copy_to_user(tlv, ue->tlv_data, ue->tlv_data_size)) | ||
109 | - return -EFAULT; | ||
110 | + ret = -EFAULT; | ||
111 | +err_unlock: | ||
112 | + mutex_unlock(&ue->card->user_ctl_lock); | ||
113 | + if (ret) | ||
114 | + return ret; | ||
115 | } | ||
116 | return change; | ||
117 | } | ||
118 | @@ -1211,6 +1229,7 @@ static int snd_ctl_elem_add(struct snd_ctl_file *file, | ||
119 | ue = kzalloc(sizeof(struct user_element) + private_size, GFP_KERNEL); | ||
120 | if (ue == NULL) | ||
121 | return -ENOMEM; | ||
122 | + ue->card = card; | ||
123 | ue->info = *info; | ||
124 | ue->info.access = 0; | ||
125 | ue->elem_data = (char *)ue + sizeof(*ue); | ||
126 | diff --git a/sound/core/init.c b/sound/core/init.c | ||
127 | index d047851..b9268a5 100644 | ||
128 | --- a/sound/core/init.c | ||
129 | +++ b/sound/core/init.c | ||
130 | @@ -215,6 +215,7 @@ int snd_card_create(int idx, const char *xid, | ||
131 | INIT_LIST_HEAD(&card->devices); | ||
132 | init_rwsem(&card->controls_rwsem); | ||
133 | rwlock_init(&card->ctl_files_rwlock); | ||
134 | + mutex_init(&card->user_ctl_lock); | ||
135 | INIT_LIST_HEAD(&card->controls); | ||
136 | INIT_LIST_HEAD(&card->ctl_files); | ||
137 | spin_lock_init(&card->files_lock); | ||
138 | -- | ||
139 | 1.9.1 | ||
140 | |||
diff --git a/recipes-kernel/linux/files/0001-HID-CVE-2014-3181.patch b/recipes-kernel/linux/files/0001-HID-CVE-2014-3181.patch new file mode 100644 index 0000000..4355c68 --- /dev/null +++ b/recipes-kernel/linux/files/0001-HID-CVE-2014-3181.patch | |||
@@ -0,0 +1,52 @@ | |||
1 | From c54def7bd64d7c0b6993336abcffb8444795bf38 Mon Sep 17 00:00:00 2001 | ||
2 | From: Jiri Kosina <jkosina@suse.cz> | ||
3 | Date: Wed, 27 Aug 2014 09:12:24 +0200 | ||
4 | Subject: [PATCH] HID: magicmouse: sanity check report size in raw_event() | ||
5 | callback | ||
6 | |||
7 | The report passed to us from transport driver could potentially be | ||
8 | arbitrarily large, therefore we better sanity-check it so that | ||
9 | magicmouse_emit_touch() gets only valid values of raw_id. | ||
10 | |||
11 | This fixes CVE-2014-3181 | ||
12 | Upstream-Status: Backport | ||
13 | |||
14 | Cc: stable@vger.kernel.org | ||
15 | Reported-by: Steven Vittitoe <scvitti@google.com> | ||
16 | Signed-off-by: Jiri Kosina <jkosina@suse.cz> | ||
17 | Signed-off-by: Sona Sarmadi <sona.sarmadi@enea.com> | ||
18 | --- | ||
19 | drivers/hid/hid-magicmouse.c | 10 ++++++++++ | ||
20 | 1 file changed, 10 insertions(+) | ||
21 | |||
22 | diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c | ||
23 | index ecc2cbf..29a74c1 100644 | ||
24 | --- a/drivers/hid/hid-magicmouse.c | ||
25 | +++ b/drivers/hid/hid-magicmouse.c | ||
26 | @@ -290,6 +290,11 @@ static int magicmouse_raw_event(struct hid_device *hdev, | ||
27 | if (size < 4 || ((size - 4) % 9) != 0) | ||
28 | return 0; | ||
29 | npoints = (size - 4) / 9; | ||
30 | + if (npoints > 15) { | ||
31 | + hid_warn(hdev, "invalid size value (%d) for TRACKPAD_REPORT_ID\n", | ||
32 | + size); | ||
33 | + return 0; | ||
34 | + } | ||
35 | msc->ntouches = 0; | ||
36 | for (ii = 0; ii < npoints; ii++) | ||
37 | magicmouse_emit_touch(msc, ii, data + ii * 9 + 4); | ||
38 | @@ -307,6 +312,11 @@ static int magicmouse_raw_event(struct hid_device *hdev, | ||
39 | if (size < 6 || ((size - 6) % 8) != 0) | ||
40 | return 0; | ||
41 | npoints = (size - 6) / 8; | ||
42 | + if (npoints > 15) { | ||
43 | + hid_warn(hdev, "invalid size value (%d) for MOUSE_REPORT_ID\n", | ||
44 | + size); | ||
45 | + return 0; | ||
46 | + } | ||
47 | msc->ntouches = 0; | ||
48 | for (ii = 0; ii < npoints; ii++) | ||
49 | magicmouse_emit_touch(msc, ii, data + ii * 8 + 6); | ||
50 | -- | ||
51 | 1.9.1 | ||
52 | |||
diff --git a/recipes-kernel/linux/files/0001-kvm-iommu-CVE-2014-3601.patch b/recipes-kernel/linux/files/0001-kvm-iommu-CVE-2014-3601.patch new file mode 100644 index 0000000..e19a3c1 --- /dev/null +++ b/recipes-kernel/linux/files/0001-kvm-iommu-CVE-2014-3601.patch | |||
@@ -0,0 +1,94 @@ | |||
1 | From e35b1e9f17e0567f96502f3a2a31dace727ed3da Mon Sep 17 00:00:00 2001 | ||
2 | From: "Michael S. Tsirkin" <mst@redhat.com> | ||
3 | Date: Tue, 19 Aug 2014 19:14:50 +0800 | ||
4 | Subject: [PATCH] kvm: iommu: fix the third parameter of kvm_iommu_put_pages | ||
5 | (CVE-2014-3601) | ||
6 | |||
7 | commit 350b8bdd689cd2ab2c67c8a86a0be86cfa0751a7 upstream. | ||
8 | |||
9 | The third parameter of kvm_iommu_put_pages is wrong, | ||
10 | It should be 'gfn - slot->base_gfn'. | ||
11 | |||
12 | By making gfn very large, malicious guest or userspace can cause kvm to | ||
13 | go to this error path, and subsequently to pass a huge value as size. | ||
14 | Alternatively if gfn is small, then pages would be pinned but never | ||
15 | unpinned, causing host memory leak and local DOS. | ||
16 | |||
17 | Passing a reasonable but large value could be the most dangerous case, | ||
18 | because it would unpin a page that should have stayed pinned, and thus | ||
19 | allow the device to DMA into arbitrary memory. However, this cannot | ||
20 | happen because of the condition that can trigger the error: | ||
21 | |||
22 | - out of memory (where you can't allocate even a single page) | ||
23 | should not be possible for the attacker to trigger | ||
24 | |||
25 | - when exceeding the iommu's address space, guest pages after gfn | ||
26 | will also exceed the iommu's address space, and inside | ||
27 | kvm_iommu_put_pages() the iommu_iova_to_phys() will fail. The | ||
28 | page thus would not be unpinned at all. | ||
29 | |||
30 | Upstream-Status: Backport | ||
31 | |||
32 | Reported-by: Jack Morgenstein <jackm@mellanox.com> | ||
33 | Signed-off-by: Michael S. Tsirkin <mst@redhat.com> | ||
34 | Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> | ||
35 | Signed-off-by: Jiri Slaby <jslaby@suse.cz> | ||
36 | Signed-off-by: Sona Sarmadi <sona.sarmadi@enea.com> | ||
37 | --- | ||
38 | virt/kvm/iommu.c | 19 ++++++++++--------- | ||
39 | 1 file changed, 10 insertions(+), 9 deletions(-) | ||
40 | |||
41 | diff --git a/virt/kvm/iommu.c b/virt/kvm/iommu.c | ||
42 | index c329c8f..dec9971 100644 | ||
43 | --- a/virt/kvm/iommu.c | ||
44 | +++ b/virt/kvm/iommu.c | ||
45 | @@ -61,6 +61,14 @@ static pfn_t kvm_pin_pages(struct kvm_memory_slot *slot, gfn_t gfn, | ||
46 | return pfn; | ||
47 | } | ||
48 | |||
49 | +static void kvm_unpin_pages(struct kvm *kvm, pfn_t pfn, unsigned long npages) | ||
50 | +{ | ||
51 | + unsigned long i; | ||
52 | + | ||
53 | + for (i = 0; i < npages; ++i) | ||
54 | + kvm_release_pfn_clean(pfn + i); | ||
55 | +} | ||
56 | + | ||
57 | int kvm_iommu_map_pages(struct kvm *kvm, struct kvm_memory_slot *slot) | ||
58 | { | ||
59 | gfn_t gfn, end_gfn; | ||
60 | @@ -123,6 +131,7 @@ int kvm_iommu_map_pages(struct kvm *kvm, struct kvm_memory_slot *slot) | ||
61 | if (r) { | ||
62 | printk(KERN_ERR "kvm_iommu_map_address:" | ||
63 | "iommu failed to map pfn=%llx\n", pfn); | ||
64 | + kvm_unpin_pages(kvm, pfn, page_size); | ||
65 | goto unmap_pages; | ||
66 | } | ||
67 | |||
68 | @@ -134,7 +143,7 @@ int kvm_iommu_map_pages(struct kvm *kvm, struct kvm_memory_slot *slot) | ||
69 | return 0; | ||
70 | |||
71 | unmap_pages: | ||
72 | - kvm_iommu_put_pages(kvm, slot->base_gfn, gfn); | ||
73 | + kvm_iommu_put_pages(kvm, slot->base_gfn, gfn - slot->base_gfn); | ||
74 | return r; | ||
75 | } | ||
76 | |||
77 | @@ -272,14 +281,6 @@ out_unlock: | ||
78 | return r; | ||
79 | } | ||
80 | |||
81 | -static void kvm_unpin_pages(struct kvm *kvm, pfn_t pfn, unsigned long npages) | ||
82 | -{ | ||
83 | - unsigned long i; | ||
84 | - | ||
85 | - for (i = 0; i < npages; ++i) | ||
86 | - kvm_release_pfn_clean(pfn + i); | ||
87 | -} | ||
88 | - | ||
89 | static void kvm_iommu_put_pages(struct kvm *kvm, | ||
90 | gfn_t base_gfn, unsigned long npages) | ||
91 | { | ||
92 | -- | ||
93 | 1.9.1 | ||
94 | |||
diff --git a/recipes-kernel/linux/files/0001-mnt-CVE-2014-5206_CVE-2014-5207.patch b/recipes-kernel/linux/files/0001-mnt-CVE-2014-5206_CVE-2014-5207.patch new file mode 100644 index 0000000..aec8930 --- /dev/null +++ b/recipes-kernel/linux/files/0001-mnt-CVE-2014-5206_CVE-2014-5207.patch | |||
@@ -0,0 +1,62 @@ | |||
1 | From 25c1def33a2f74079f3062b7afdf98fcf9f34e6d Mon Sep 17 00:00:00 2001 | ||
2 | From: "Eric W. Biederman" <ebiederm@xmission.com> | ||
3 | Date: Mon, 28 Jul 2014 16:26:53 -0700 | ||
4 | Subject: [PATCH] mnt: Only change user settable mount flags in remount | ||
5 | |||
6 | commit a6138db815df5ee542d848318e5dae681590fccd upstream. | ||
7 | |||
8 | Kenton Varda <kenton@sandstorm.io> discovered that by remounting a | ||
9 | read-only bind mount read-only in a user namespace the | ||
10 | MNT_LOCK_READONLY bit would be cleared, allowing an unprivileged user | ||
11 | to the remount a read-only mount read-write. | ||
12 | |||
13 | Correct this by replacing the mask of mount flags to preserve | ||
14 | with a mask of mount flags that may be changed, and preserve | ||
15 | all others. This ensures that any future bugs with this mask and | ||
16 | remount will fail in an easy to detect way where new mount flags | ||
17 | simply won't change. | ||
18 | |||
19 | Fix for CVE-2014-5206 and CVE-2014-5207 | ||
20 | Upstream-Status: backport | ||
21 | |||
22 | Cc: stable@vger.kernel.org | ||
23 | Acked-by: Serge E. Hallyn <serge.hallyn@ubuntu.com> | ||
24 | Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com> | ||
25 | Signed-off-by: Jiri Slaby <jslaby@suse.cz> | ||
26 | Signed-off-by: Sona Sarmadi <sona.sarmadi@enea.com> | ||
27 | --- | ||
28 | fs/namespace.c | 2 +- | ||
29 | include/linux/mount.h | 4 +++- | ||
30 | 2 files changed, 4 insertions(+), 2 deletions(-) | ||
31 | |||
32 | diff --git a/fs/namespace.c b/fs/namespace.c | ||
33 | index 84447db..34fa7a5 100644 | ||
34 | --- a/fs/namespace.c | ||
35 | +++ b/fs/namespace.c | ||
36 | @@ -1847,7 +1847,7 @@ static int do_remount(struct path *path, int flags, int mnt_flags, | ||
37 | err = do_remount_sb(sb, flags, data, 0); | ||
38 | if (!err) { | ||
39 | br_write_lock(&vfsmount_lock); | ||
40 | - mnt_flags |= mnt->mnt.mnt_flags & MNT_PROPAGATION_MASK; | ||
41 | + mnt_flags |= mnt->mnt.mnt_flags & ~MNT_USER_SETTABLE_MASK; | ||
42 | mnt->mnt.mnt_flags = mnt_flags; | ||
43 | br_write_unlock(&vfsmount_lock); | ||
44 | } | ||
45 | diff --git a/include/linux/mount.h b/include/linux/mount.h | ||
46 | index 38cd98f..8707c9e 100644 | ||
47 | --- a/include/linux/mount.h | ||
48 | +++ b/include/linux/mount.h | ||
49 | @@ -42,7 +42,9 @@ struct mnt_namespace; | ||
50 | * flag, consider how it interacts with shared mounts. | ||
51 | */ | ||
52 | #define MNT_SHARED_MASK (MNT_UNBINDABLE) | ||
53 | -#define MNT_PROPAGATION_MASK (MNT_SHARED | MNT_UNBINDABLE) | ||
54 | +#define MNT_USER_SETTABLE_MASK (MNT_NOSUID | MNT_NODEV | MNT_NOEXEC \ | ||
55 | + | MNT_NOATIME | MNT_NODIRATIME | MNT_RELATIME \ | ||
56 | + | MNT_READONLY) | ||
57 | |||
58 | |||
59 | #define MNT_INTERNAL 0x4000 | ||
60 | -- | ||
61 | 1.9.1 | ||
62 | |||
diff --git a/recipes-kernel/linux/files/0001-net-sctp-CVE-2014-3673.patch b/recipes-kernel/linux/files/0001-net-sctp-CVE-2014-3673.patch new file mode 100644 index 0000000..68289f2 --- /dev/null +++ b/recipes-kernel/linux/files/0001-net-sctp-CVE-2014-3673.patch | |||
@@ -0,0 +1,348 @@ | |||
1 | From bbd951a21e0fd555cd9ede44c7196af09d04d171 Mon Sep 17 00:00:00 2001 | ||
2 | From: Daniel Borkmann <dborkman@redhat.com> | ||
3 | Date: Thu, 9 Oct 2014 22:55:31 +0200 | ||
4 | Subject: [PATCH] net: sctp: fix skb_over_panic when receiving malformed ASCONF | ||
5 | chunks | ||
6 | |||
7 | commit 9de7922bc709eee2f609cd01d98aaedc4cf5ea74 upstream. | ||
8 | |||
9 | Commit 6f4c618ddb0 ("SCTP : Add paramters validity check for | ||
10 | ASCONF chunk") added basic verification of ASCONF chunks, however, | ||
11 | it is still possible to remotely crash a server by sending a | ||
12 | special crafted ASCONF chunk, even up to pre 2.6.12 kernels: | ||
13 | |||
14 | skb_over_panic: text:ffffffffa01ea1c3 len:31056 put:30768 | ||
15 | head:ffff88011bd81800 data:ffff88011bd81800 tail:0x7950 | ||
16 | end:0x440 dev:<NULL> | ||
17 | ------------[ cut here ]------------ | ||
18 | kernel BUG at net/core/skbuff.c:129! | ||
19 | [...] | ||
20 | Call Trace: | ||
21 | <IRQ> | ||
22 | [<ffffffff8144fb1c>] skb_put+0x5c/0x70 | ||
23 | [<ffffffffa01ea1c3>] sctp_addto_chunk+0x63/0xd0 [sctp] | ||
24 | [<ffffffffa01eadaf>] sctp_process_asconf+0x1af/0x540 [sctp] | ||
25 | [<ffffffff8152d025>] ? _read_unlock_bh+0x15/0x20 | ||
26 | [<ffffffffa01e0038>] sctp_sf_do_asconf+0x168/0x240 [sctp] | ||
27 | [<ffffffffa01e3751>] sctp_do_sm+0x71/0x1210 [sctp] | ||
28 | [<ffffffff8147645d>] ? fib_rules_lookup+0xad/0xf0 | ||
29 | [<ffffffffa01e6b22>] ? sctp_cmp_addr_exact+0x32/0x40 [sctp] | ||
30 | [<ffffffffa01e8393>] sctp_assoc_bh_rcv+0xd3/0x180 [sctp] | ||
31 | [<ffffffffa01ee986>] sctp_inq_push+0x56/0x80 [sctp] | ||
32 | [<ffffffffa01fcc42>] sctp_rcv+0x982/0xa10 [sctp] | ||
33 | [<ffffffffa01d5123>] ? ipt_local_in_hook+0x23/0x28 [iptable_filter] | ||
34 | [<ffffffff8148bdc9>] ? nf_iterate+0x69/0xb0 | ||
35 | [<ffffffff81496d10>] ? ip_local_deliver_finish+0x0/0x2d0 | ||
36 | [<ffffffff8148bf86>] ? nf_hook_slow+0x76/0x120 | ||
37 | [<ffffffff81496d10>] ? ip_local_deliver_finish+0x0/0x2d0 | ||
38 | [<ffffffff81496ded>] ip_local_deliver_finish+0xdd/0x2d0 | ||
39 | [<ffffffff81497078>] ip_local_deliver+0x98/0xa0 | ||
40 | [<ffffffff8149653d>] ip_rcv_finish+0x12d/0x440 | ||
41 | [<ffffffff81496ac5>] ip_rcv+0x275/0x350 | ||
42 | [<ffffffff8145c88b>] __netif_receive_skb+0x4ab/0x750 | ||
43 | [<ffffffff81460588>] netif_receive_skb+0x58/0x60 | ||
44 | |||
45 | This can be triggered e.g., through a simple scripted nmap | ||
46 | connection scan injecting the chunk after the handshake, for | ||
47 | example, ... | ||
48 | |||
49 | -------------- INIT[ASCONF; ASCONF_ACK] -------------> | ||
50 | <----------- INIT-ACK[ASCONF; ASCONF_ACK] ------------ | ||
51 | -------------------- COOKIE-ECHO --------------------> | ||
52 | <-------------------- COOKIE-ACK --------------------- | ||
53 | ------------------ ASCONF; UNKNOWN ------------------> | ||
54 | |||
55 | ... where ASCONF chunk of length 280 contains 2 parameters ... | ||
56 | |||
57 | 1) Add IP address parameter (param length: 16) | ||
58 | 2) Add/del IP address parameter (param length: 255) | ||
59 | |||
60 | ... followed by an UNKNOWN chunk of e.g. 4 bytes. Here, the | ||
61 | Address Parameter in the ASCONF chunk is even missing, too. | ||
62 | This is just an example and similarly-crafted ASCONF chunks | ||
63 | could be used just as well. | ||
64 | |||
65 | The ASCONF chunk passes through sctp_verify_asconf() as all | ||
66 | parameters passed sanity checks, and after walking, we ended | ||
67 | up successfully at the chunk end boundary, and thus may invoke | ||
68 | sctp_process_asconf(). Parameter walking is done with | ||
69 | WORD_ROUND() to take padding into account. | ||
70 | |||
71 | In sctp_process_asconf()'s TLV processing, we may fail in | ||
72 | sctp_process_asconf_param() e.g., due to removal of the IP | ||
73 | address that is also the source address of the packet containing | ||
74 | the ASCONF chunk, and thus we need to add all TLVs after the | ||
75 | failure to our ASCONF response to remote via helper function | ||
76 | sctp_add_asconf_response(), which basically invokes a | ||
77 | sctp_addto_chunk() adding the error parameters to the given | ||
78 | skb. | ||
79 | |||
80 | When walking to the next parameter this time, we proceed | ||
81 | with ... | ||
82 | |||
83 | length = ntohs(asconf_param->param_hdr.length); | ||
84 | asconf_param = (void *)asconf_param + length; | ||
85 | |||
86 | ... instead of the WORD_ROUND()'ed length, thus resulting here | ||
87 | in an off-by-one that leads to reading the follow-up garbage | ||
88 | parameter length of 12336, and thus throwing an skb_over_panic | ||
89 | for the reply when trying to sctp_addto_chunk() next time, | ||
90 | which implicitly calls the skb_put() with that length. | ||
91 | |||
92 | Fix it by using sctp_walk_params() [ which is also used in | ||
93 | INIT parameter processing ] macro in the verification *and* | ||
94 | in ASCONF processing: it will make sure we don't spill over, | ||
95 | that we walk parameters WORD_ROUND()'ed. Moreover, we're being | ||
96 | more defensive and guard against unknown parameter types and | ||
97 | missized addresses. | ||
98 | |||
99 | Joint work with Vlad Yasevich. | ||
100 | |||
101 | Fixes CVE-2014-3673 | ||
102 | Upstream-Status: Backport | ||
103 | |||
104 | Fixes: b896b82be4ae ("[SCTP] ADDIP: Support for processing incoming ASCONF_ACK chunks.") | ||
105 | Signed-off-by: Daniel Borkmann <dborkman@redhat.com> | ||
106 | Signed-off-by: Vlad Yasevich <vyasevich@gmail.com> | ||
107 | Acked-by: Neil Horman <nhorman@tuxdriver.com> | ||
108 | Signed-off-by: David S. Miller <davem@davemloft.net> | ||
109 | Cc: Josh Boyer <jwboyer@fedoraproject.org> | ||
110 | Signed-off-by: Jiri Slaby <jslaby@suse.cz> | ||
111 | Signed-off-by: Sona Sarmadi <sona.sarmadi@enea.com> | ||
112 | --- | ||
113 | include/net/sctp/sm.h | 6 +-- | ||
114 | net/sctp/sm_make_chunk.c | 99 +++++++++++++++++++++++++++--------------------- | ||
115 | net/sctp/sm_statefuns.c | 18 +-------- | ||
116 | 3 files changed, 60 insertions(+), 63 deletions(-) | ||
117 | |||
118 | diff --git a/include/net/sctp/sm.h b/include/net/sctp/sm.h | ||
119 | index 4ef75af..c91b6f5 100644 | ||
120 | --- a/include/net/sctp/sm.h | ||
121 | +++ b/include/net/sctp/sm.h | ||
122 | @@ -249,9 +249,9 @@ struct sctp_chunk *sctp_make_asconf_update_ip(struct sctp_association *, | ||
123 | int, __be16); | ||
124 | struct sctp_chunk *sctp_make_asconf_set_prim(struct sctp_association *asoc, | ||
125 | union sctp_addr *addr); | ||
126 | -int sctp_verify_asconf(const struct sctp_association *asoc, | ||
127 | - struct sctp_paramhdr *param_hdr, void *chunk_end, | ||
128 | - struct sctp_paramhdr **errp); | ||
129 | +bool sctp_verify_asconf(const struct sctp_association *asoc, | ||
130 | + struct sctp_chunk *chunk, bool addr_param_needed, | ||
131 | + struct sctp_paramhdr **errp); | ||
132 | struct sctp_chunk *sctp_process_asconf(struct sctp_association *asoc, | ||
133 | struct sctp_chunk *asconf); | ||
134 | int sctp_process_asconf_ack(struct sctp_association *asoc, | ||
135 | diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c | ||
136 | index e342387..d800160 100644 | ||
137 | --- a/net/sctp/sm_make_chunk.c | ||
138 | +++ b/net/sctp/sm_make_chunk.c | ||
139 | @@ -3126,50 +3126,63 @@ static __be16 sctp_process_asconf_param(struct sctp_association *asoc, | ||
140 | return SCTP_ERROR_NO_ERROR; | ||
141 | } | ||
142 | |||
143 | -/* Verify the ASCONF packet before we process it. */ | ||
144 | -int sctp_verify_asconf(const struct sctp_association *asoc, | ||
145 | - struct sctp_paramhdr *param_hdr, void *chunk_end, | ||
146 | - struct sctp_paramhdr **errp) { | ||
147 | - sctp_addip_param_t *asconf_param; | ||
148 | +/* Verify the ASCONF packet before we process it. */ | ||
149 | +bool sctp_verify_asconf(const struct sctp_association *asoc, | ||
150 | + struct sctp_chunk *chunk, bool addr_param_needed, | ||
151 | + struct sctp_paramhdr **errp) | ||
152 | +{ | ||
153 | + sctp_addip_chunk_t *addip = (sctp_addip_chunk_t *) chunk->chunk_hdr; | ||
154 | union sctp_params param; | ||
155 | - int length, plen; | ||
156 | - | ||
157 | - param.v = (sctp_paramhdr_t *) param_hdr; | ||
158 | - while (param.v <= chunk_end - sizeof(sctp_paramhdr_t)) { | ||
159 | - length = ntohs(param.p->length); | ||
160 | - *errp = param.p; | ||
161 | + bool addr_param_seen = false; | ||
162 | |||
163 | - if (param.v > chunk_end - length || | ||
164 | - length < sizeof(sctp_paramhdr_t)) | ||
165 | - return 0; | ||
166 | + sctp_walk_params(param, addip, addip_hdr.params) { | ||
167 | + size_t length = ntohs(param.p->length); | ||
168 | |||
169 | + *errp = param.p; | ||
170 | switch (param.p->type) { | ||
171 | + case SCTP_PARAM_ERR_CAUSE: | ||
172 | + break; | ||
173 | + case SCTP_PARAM_IPV4_ADDRESS: | ||
174 | + if (length != sizeof(sctp_ipv4addr_param_t)) | ||
175 | + return false; | ||
176 | + addr_param_seen = true; | ||
177 | + break; | ||
178 | + case SCTP_PARAM_IPV6_ADDRESS: | ||
179 | + if (length != sizeof(sctp_ipv6addr_param_t)) | ||
180 | + return false; | ||
181 | + addr_param_seen = true; | ||
182 | + break; | ||
183 | case SCTP_PARAM_ADD_IP: | ||
184 | case SCTP_PARAM_DEL_IP: | ||
185 | case SCTP_PARAM_SET_PRIMARY: | ||
186 | - asconf_param = (sctp_addip_param_t *)param.v; | ||
187 | - plen = ntohs(asconf_param->param_hdr.length); | ||
188 | - if (plen < sizeof(sctp_addip_param_t) + | ||
189 | - sizeof(sctp_paramhdr_t)) | ||
190 | - return 0; | ||
191 | + /* In ASCONF chunks, these need to be first. */ | ||
192 | + if (addr_param_needed && !addr_param_seen) | ||
193 | + return false; | ||
194 | + length = ntohs(param.addip->param_hdr.length); | ||
195 | + if (length < sizeof(sctp_addip_param_t) + | ||
196 | + sizeof(sctp_paramhdr_t)) | ||
197 | + return false; | ||
198 | break; | ||
199 | case SCTP_PARAM_SUCCESS_REPORT: | ||
200 | case SCTP_PARAM_ADAPTATION_LAYER_IND: | ||
201 | if (length != sizeof(sctp_addip_param_t)) | ||
202 | - return 0; | ||
203 | - | ||
204 | + return false; | ||
205 | break; | ||
206 | default: | ||
207 | - break; | ||
208 | + /* This is unkown to us, reject! */ | ||
209 | + return false; | ||
210 | } | ||
211 | - | ||
212 | - param.v += WORD_ROUND(length); | ||
213 | } | ||
214 | |||
215 | - if (param.v != chunk_end) | ||
216 | - return 0; | ||
217 | + /* Remaining sanity checks. */ | ||
218 | + if (addr_param_needed && !addr_param_seen) | ||
219 | + return false; | ||
220 | + if (!addr_param_needed && addr_param_seen) | ||
221 | + return false; | ||
222 | + if (param.v != chunk->chunk_end) | ||
223 | + return false; | ||
224 | |||
225 | - return 1; | ||
226 | + return true; | ||
227 | } | ||
228 | |||
229 | /* Process an incoming ASCONF chunk with the next expected serial no. and | ||
230 | @@ -3178,16 +3191,17 @@ int sctp_verify_asconf(const struct sctp_association *asoc, | ||
231 | struct sctp_chunk *sctp_process_asconf(struct sctp_association *asoc, | ||
232 | struct sctp_chunk *asconf) | ||
233 | { | ||
234 | + sctp_addip_chunk_t *addip = (sctp_addip_chunk_t *) asconf->chunk_hdr; | ||
235 | + bool all_param_pass = true; | ||
236 | + union sctp_params param; | ||
237 | sctp_addiphdr_t *hdr; | ||
238 | union sctp_addr_param *addr_param; | ||
239 | sctp_addip_param_t *asconf_param; | ||
240 | struct sctp_chunk *asconf_ack; | ||
241 | - | ||
242 | __be16 err_code; | ||
243 | int length = 0; | ||
244 | int chunk_len; | ||
245 | __u32 serial; | ||
246 | - int all_param_pass = 1; | ||
247 | |||
248 | chunk_len = ntohs(asconf->chunk_hdr->length) - sizeof(sctp_chunkhdr_t); | ||
249 | hdr = (sctp_addiphdr_t *)asconf->skb->data; | ||
250 | @@ -3215,9 +3229,14 @@ struct sctp_chunk *sctp_process_asconf(struct sctp_association *asoc, | ||
251 | goto done; | ||
252 | |||
253 | /* Process the TLVs contained within the ASCONF chunk. */ | ||
254 | - while (chunk_len > 0) { | ||
255 | + sctp_walk_params(param, addip, addip_hdr.params) { | ||
256 | + /* Skip preceeding address parameters. */ | ||
257 | + if (param.p->type == SCTP_PARAM_IPV4_ADDRESS || | ||
258 | + param.p->type == SCTP_PARAM_IPV6_ADDRESS) | ||
259 | + continue; | ||
260 | + | ||
261 | err_code = sctp_process_asconf_param(asoc, asconf, | ||
262 | - asconf_param); | ||
263 | + param.addip); | ||
264 | /* ADDIP 4.1 A7) | ||
265 | * If an error response is received for a TLV parameter, | ||
266 | * all TLVs with no response before the failed TLV are | ||
267 | @@ -3225,28 +3244,20 @@ struct sctp_chunk *sctp_process_asconf(struct sctp_association *asoc, | ||
268 | * the failed response are considered unsuccessful unless | ||
269 | * a specific success indication is present for the parameter. | ||
270 | */ | ||
271 | - if (SCTP_ERROR_NO_ERROR != err_code) | ||
272 | - all_param_pass = 0; | ||
273 | - | ||
274 | + if (err_code != SCTP_ERROR_NO_ERROR) | ||
275 | + all_param_pass = false; | ||
276 | if (!all_param_pass) | ||
277 | - sctp_add_asconf_response(asconf_ack, | ||
278 | - asconf_param->crr_id, err_code, | ||
279 | - asconf_param); | ||
280 | + sctp_add_asconf_response(asconf_ack, param.addip->crr_id, | ||
281 | + err_code, param.addip); | ||
282 | |||
283 | /* ADDIP 4.3 D11) When an endpoint receiving an ASCONF to add | ||
284 | * an IP address sends an 'Out of Resource' in its response, it | ||
285 | * MUST also fail any subsequent add or delete requests bundled | ||
286 | * in the ASCONF. | ||
287 | */ | ||
288 | - if (SCTP_ERROR_RSRC_LOW == err_code) | ||
289 | + if (err_code == SCTP_ERROR_RSRC_LOW) | ||
290 | goto done; | ||
291 | - | ||
292 | - /* Move to the next ASCONF param. */ | ||
293 | - length = ntohs(asconf_param->param_hdr.length); | ||
294 | - asconf_param = (void *)asconf_param + length; | ||
295 | - chunk_len -= length; | ||
296 | } | ||
297 | - | ||
298 | done: | ||
299 | asoc->peer.addip_serial++; | ||
300 | |||
301 | diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c | ||
302 | index 62623cc..bf12098 100644 | ||
303 | --- a/net/sctp/sm_statefuns.c | ||
304 | +++ b/net/sctp/sm_statefuns.c | ||
305 | @@ -3595,9 +3595,7 @@ sctp_disposition_t sctp_sf_do_asconf(struct net *net, | ||
306 | struct sctp_chunk *asconf_ack = NULL; | ||
307 | struct sctp_paramhdr *err_param = NULL; | ||
308 | sctp_addiphdr_t *hdr; | ||
309 | - union sctp_addr_param *addr_param; | ||
310 | __u32 serial; | ||
311 | - int length; | ||
312 | |||
313 | if (!sctp_vtag_verify(chunk, asoc)) { | ||
314 | sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_BAD_TAG, | ||
315 | @@ -3622,17 +3620,8 @@ sctp_disposition_t sctp_sf_do_asconf(struct net *net, | ||
316 | hdr = (sctp_addiphdr_t *)chunk->skb->data; | ||
317 | serial = ntohl(hdr->serial); | ||
318 | |||
319 | - addr_param = (union sctp_addr_param *)hdr->params; | ||
320 | - length = ntohs(addr_param->p.length); | ||
321 | - if (length < sizeof(sctp_paramhdr_t)) | ||
322 | - return sctp_sf_violation_paramlen(net, ep, asoc, type, arg, | ||
323 | - (void *)addr_param, commands); | ||
324 | - | ||
325 | /* Verify the ASCONF chunk before processing it. */ | ||
326 | - if (!sctp_verify_asconf(asoc, | ||
327 | - (sctp_paramhdr_t *)((void *)addr_param + length), | ||
328 | - (void *)chunk->chunk_end, | ||
329 | - &err_param)) | ||
330 | + if (!sctp_verify_asconf(asoc, chunk, true, &err_param)) | ||
331 | return sctp_sf_violation_paramlen(net, ep, asoc, type, arg, | ||
332 | (void *)err_param, commands); | ||
333 | |||
334 | @@ -3750,10 +3739,7 @@ sctp_disposition_t sctp_sf_do_asconf_ack(struct net *net, | ||
335 | rcvd_serial = ntohl(addip_hdr->serial); | ||
336 | |||
337 | /* Verify the ASCONF-ACK chunk before processing it. */ | ||
338 | - if (!sctp_verify_asconf(asoc, | ||
339 | - (sctp_paramhdr_t *)addip_hdr->params, | ||
340 | - (void *)asconf_ack->chunk_end, | ||
341 | - &err_param)) | ||
342 | + if (!sctp_verify_asconf(asoc, asconf_ack, false, &err_param)) | ||
343 | return sctp_sf_violation_paramlen(net, ep, asoc, type, arg, | ||
344 | (void *)err_param, commands); | ||
345 | |||
346 | -- | ||
347 | 1.9.1 | ||
348 | |||
diff --git a/recipes-kernel/linux/files/0002-ALSA-CVE-2014-4653.patch b/recipes-kernel/linux/files/0002-ALSA-CVE-2014-4653.patch new file mode 100644 index 0000000..8612d74 --- /dev/null +++ b/recipes-kernel/linux/files/0002-ALSA-CVE-2014-4653.patch | |||
@@ -0,0 +1,92 @@ | |||
1 | From 0bf595fd311aa4d6e82c43879f2c0d0650e83271 Mon Sep 17 00:00:00 2001 | ||
2 | From: Lars-Peter Clausen <lars@metafoo.de> | ||
3 | Date: Wed, 18 Jun 2014 13:32:33 +0200 | ||
4 | Subject: [PATCH] ALSA: control: Don't access controls outside of protected | ||
5 | regions | ||
6 | |||
7 | commit fd9f26e4eca5d08a27d12c0933fceef76ed9663d upstream. | ||
8 | |||
9 | A control that is visible on the card->controls list can be freed at any time. | ||
10 | This means we must not access any of its memory while not holding the | ||
11 | controls_rw_lock. Otherwise we risk a use after free access. | ||
12 | |||
13 | This fixes CVE-2014-4653 | ||
14 | Upstream-Status: Backport | ||
15 | |||
16 | Signed-off-by: Lars-Peter Clausen <lars@metafoo.de> | ||
17 | Acked-by: Jaroslav Kysela <perex@perex.cz> | ||
18 | Signed-off-by: Takashi Iwai <tiwai@suse.de> | ||
19 | Signed-off-by: Jiri Slaby <jslaby@suse.cz> | ||
20 | Signed-off-by: Sona Sarmadi <sona.sarmadi@enea.com> | ||
21 | --- | ||
22 | sound/core/control.c | 15 ++++++++++----- | ||
23 | 1 file changed, 10 insertions(+), 5 deletions(-) | ||
24 | |||
25 | diff --git a/sound/core/control.c b/sound/core/control.c | ||
26 | index 15bc844..d4a597f 100644 | ||
27 | --- a/sound/core/control.c | ||
28 | +++ b/sound/core/control.c | ||
29 | @@ -331,6 +331,7 @@ int snd_ctl_add(struct snd_card *card, struct snd_kcontrol *kcontrol) | ||
30 | { | ||
31 | struct snd_ctl_elem_id id; | ||
32 | unsigned int idx; | ||
33 | + unsigned int count; | ||
34 | int err = -EINVAL; | ||
35 | |||
36 | if (! kcontrol) | ||
37 | @@ -359,8 +360,9 @@ int snd_ctl_add(struct snd_card *card, struct snd_kcontrol *kcontrol) | ||
38 | card->controls_count += kcontrol->count; | ||
39 | kcontrol->id.numid = card->last_numid + 1; | ||
40 | card->last_numid += kcontrol->count; | ||
41 | + count = kcontrol->count; | ||
42 | up_write(&card->controls_rwsem); | ||
43 | - for (idx = 0; idx < kcontrol->count; idx++, id.index++, id.numid++) | ||
44 | + for (idx = 0; idx < count; idx++, id.index++, id.numid++) | ||
45 | snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_ADD, &id); | ||
46 | return 0; | ||
47 | |||
48 | @@ -389,6 +391,7 @@ int snd_ctl_replace(struct snd_card *card, struct snd_kcontrol *kcontrol, | ||
49 | bool add_on_replace) | ||
50 | { | ||
51 | struct snd_ctl_elem_id id; | ||
52 | + unsigned int count; | ||
53 | unsigned int idx; | ||
54 | struct snd_kcontrol *old; | ||
55 | int ret; | ||
56 | @@ -424,8 +427,9 @@ add: | ||
57 | card->controls_count += kcontrol->count; | ||
58 | kcontrol->id.numid = card->last_numid + 1; | ||
59 | card->last_numid += kcontrol->count; | ||
60 | + count = kcontrol->count; | ||
61 | up_write(&card->controls_rwsem); | ||
62 | - for (idx = 0; idx < kcontrol->count; idx++, id.index++, id.numid++) | ||
63 | + for (idx = 0; idx < count; idx++, id.index++, id.numid++) | ||
64 | snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_ADD, &id); | ||
65 | return 0; | ||
66 | |||
67 | @@ -898,9 +902,9 @@ static int snd_ctl_elem_write(struct snd_card *card, struct snd_ctl_file *file, | ||
68 | result = kctl->put(kctl, control); | ||
69 | } | ||
70 | if (result > 0) { | ||
71 | + struct snd_ctl_elem_id id = control->id; | ||
72 | up_read(&card->controls_rwsem); | ||
73 | - snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE, | ||
74 | - &control->id); | ||
75 | + snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE, &id); | ||
76 | return 0; | ||
77 | } | ||
78 | } | ||
79 | @@ -1334,8 +1338,9 @@ static int snd_ctl_tlv_ioctl(struct snd_ctl_file *file, | ||
80 | } | ||
81 | err = kctl->tlv.c(kctl, op_flag, tlv.length, _tlv->tlv); | ||
82 | if (err > 0) { | ||
83 | + struct snd_ctl_elem_id id = kctl->id; | ||
84 | up_read(&card->controls_rwsem); | ||
85 | - snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_TLV, &kctl->id); | ||
86 | + snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_TLV, &id); | ||
87 | return 0; | ||
88 | } | ||
89 | } else { | ||
90 | -- | ||
91 | 1.9.1 | ||
92 | |||
diff --git a/recipes-kernel/linux/files/0002-HID-CVE-2014-3182.patch b/recipes-kernel/linux/files/0002-HID-CVE-2014-3182.patch new file mode 100644 index 0000000..a90d079 --- /dev/null +++ b/recipes-kernel/linux/files/0002-HID-CVE-2014-3182.patch | |||
@@ -0,0 +1,65 @@ | |||
1 | From ad3e14d7c5268c2e24477c6ef54bbdf88add5d36 Mon Sep 17 00:00:00 2001 | ||
2 | From: Jiri Kosina <jkosina@suse.cz> | ||
3 | Date: Thu, 21 Aug 2014 09:57:17 -0500 | ||
4 | Subject: [PATCH] HID: logitech: perform bounds checking on device_id early | ||
5 | enough | ||
6 | |||
7 | device_index is a char type and the size of paired_dj_deivces is 7 | ||
8 | elements, therefore proper bounds checking has to be applied to | ||
9 | device_index before it is used. | ||
10 | |||
11 | We are currently performing the bounds checking in | ||
12 | logi_dj_recv_add_djhid_device(), which is too late, as malicious device | ||
13 | could send REPORT_TYPE_NOTIF_DEVICE_UNPAIRED early enough and trigger the | ||
14 | problem in one of the report forwarding functions called from | ||
15 | logi_dj_raw_event(). | ||
16 | |||
17 | Fix this by performing the check at the earliest possible ocasion in | ||
18 | logi_dj_raw_event(). | ||
19 | |||
20 | This fixes CVE-2014-3182 | ||
21 | Upstream-Status: Backport | ||
22 | |||
23 | Cc: stable@vger.kernel.org | ||
24 | Reported-by: Ben Hawkes <hawkes@google.com> | ||
25 | Reviewed-by: Benjamin Tissoires <benjamin.tissoires@redhat.com> | ||
26 | Signed-off-by: Jiri Kosina <jkosina@suse.cz> | ||
27 | Signed-off-by: Sona Sarmadi <sona.sarmadi@enea.com> | ||
28 | --- | ||
29 | drivers/hid/hid-logitech-dj.c | 13 ++++++------- | ||
30 | 1 file changed, 6 insertions(+), 7 deletions(-) | ||
31 | |||
32 | diff --git a/drivers/hid/hid-logitech-dj.c b/drivers/hid/hid-logitech-dj.c | ||
33 | index ca0ab51..b7ba829 100644 | ||
34 | --- a/drivers/hid/hid-logitech-dj.c | ||
35 | +++ b/drivers/hid/hid-logitech-dj.c | ||
36 | @@ -238,13 +238,6 @@ static void logi_dj_recv_add_djhid_device(struct dj_receiver_dev *djrcv_dev, | ||
37 | return; | ||
38 | } | ||
39 | |||
40 | - if ((dj_report->device_index < DJ_DEVICE_INDEX_MIN) || | ||
41 | - (dj_report->device_index > DJ_DEVICE_INDEX_MAX)) { | ||
42 | - dev_err(&djrcv_hdev->dev, "%s: invalid device index:%d\n", | ||
43 | - __func__, dj_report->device_index); | ||
44 | - return; | ||
45 | - } | ||
46 | - | ||
47 | if (djrcv_dev->paired_dj_devices[dj_report->device_index]) { | ||
48 | /* The device is already known. No need to reallocate it. */ | ||
49 | dbg_hid("%s: device is already known\n", __func__); | ||
50 | @@ -690,6 +683,12 @@ static int logi_dj_raw_event(struct hid_device *hdev, | ||
51 | * device (via hid_input_report() ) and return 1 so hid-core does not do | ||
52 | * anything else with it. | ||
53 | */ | ||
54 | + if ((dj_report->device_index < DJ_DEVICE_INDEX_MIN) || | ||
55 | + (dj_report->device_index > DJ_DEVICE_INDEX_MAX)) { | ||
56 | + dev_err(&hdev->dev, "%s: invalid device index:%d\n", | ||
57 | + __func__, dj_report->device_index); | ||
58 | + return false; | ||
59 | + } | ||
60 | |||
61 | spin_lock_irqsave(&djrcv_dev->lock, flags); | ||
62 | if (dj_report->report_id == REPORT_ID_DJ_SHORT) { | ||
63 | -- | ||
64 | 1.9.1 | ||
65 | |||
diff --git a/recipes-kernel/linux/files/0002-kvm-iommu-CVE-2014-8369.patch b/recipes-kernel/linux/files/0002-kvm-iommu-CVE-2014-8369.patch new file mode 100644 index 0000000..e43771c --- /dev/null +++ b/recipes-kernel/linux/files/0002-kvm-iommu-CVE-2014-8369.patch | |||
@@ -0,0 +1,86 @@ | |||
1 | From 248541357433e3035d954435dafcdb9e70afee4e Mon Sep 17 00:00:00 2001 | ||
2 | From: Quentin Casasnovas <quentin.casasnovas@oracle.com> | ||
3 | Date: Fri, 17 Oct 2014 22:55:59 +0200 | ||
4 | Subject: [PATCH] kvm: fix excessive pages un-pinning in kvm_iommu_map error | ||
5 | path. | ||
6 | |||
7 | commit 3d32e4dbe71374a6780eaf51d719d76f9a9bf22f upstream. | ||
8 | |||
9 | The third parameter of kvm_unpin_pages() when called from | ||
10 | kvm_iommu_map_pages() is wrong, it should be the number of pages to un-pin | ||
11 | and not the page size. | ||
12 | |||
13 | This error was facilitated with an inconsistent API: kvm_pin_pages() takes | ||
14 | a size, but kvn_unpin_pages() takes a number of pages, so fix the problem | ||
15 | by matching the two. | ||
16 | |||
17 | This was introduced by commit 350b8bd ("kvm: iommu: fix the third parameter | ||
18 | of kvm_iommu_put_pages (CVE-2014-3601)"), which fixes the lack of | ||
19 | un-pinning for pages intended to be un-pinned (i.e. memory leak) but | ||
20 | unfortunately potentially aggravated the number of pages we un-pin that | ||
21 | should have stayed pinned. As far as I understand though, the same | ||
22 | practical mitigations apply. | ||
23 | |||
24 | This issue was found during review of Red Hat 6.6 patches to prepare | ||
25 | Ksplice rebootless updates. | ||
26 | |||
27 | Thanks to Vegard for his time on a late Friday evening to help me in | ||
28 | understanding this code. | ||
29 | |||
30 | Fix for CVE-2014-8369 | ||
31 | |||
32 | Upstream-Status: Backport | ||
33 | |||
34 | Fixes: 350b8bd ("kvm: iommu: fix the third parameter of... (CVE-2014-3601)") | ||
35 | Signed-off-by: Quentin Casasnovas <quentin.casasnovas@oracle.com> | ||
36 | Signed-off-by: Vegard Nossum <vegard.nossum@oracle.com> | ||
37 | Signed-off-by: Jamie Iles <jamie.iles@oracle.com> | ||
38 | Reviewed-by: Sasha Levin <sasha.levin@oracle.com> | ||
39 | Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> | ||
40 | Signed-off-by: Jiri Slaby <jslaby@suse.cz> | ||
41 | Signed-off-by: Sona Sarmadi <sona.sarmadi@enea.com> | ||
42 | --- | ||
43 | virt/kvm/iommu.c | 8 ++++---- | ||
44 | 1 file changed, 4 insertions(+), 4 deletions(-) | ||
45 | |||
46 | diff --git a/virt/kvm/iommu.c b/virt/kvm/iommu.c | ||
47 | index dec9971..a650aa4 100644 | ||
48 | --- a/virt/kvm/iommu.c | ||
49 | +++ b/virt/kvm/iommu.c | ||
50 | @@ -43,13 +43,13 @@ static void kvm_iommu_put_pages(struct kvm *kvm, | ||
51 | gfn_t base_gfn, unsigned long npages); | ||
52 | |||
53 | static pfn_t kvm_pin_pages(struct kvm_memory_slot *slot, gfn_t gfn, | ||
54 | - unsigned long size) | ||
55 | + unsigned long npages) | ||
56 | { | ||
57 | gfn_t end_gfn; | ||
58 | pfn_t pfn; | ||
59 | |||
60 | pfn = gfn_to_pfn_memslot(slot, gfn); | ||
61 | - end_gfn = gfn + (size >> PAGE_SHIFT); | ||
62 | + end_gfn = gfn + npages; | ||
63 | gfn += 1; | ||
64 | |||
65 | if (is_error_noslot_pfn(pfn)) | ||
66 | @@ -119,7 +119,7 @@ int kvm_iommu_map_pages(struct kvm *kvm, struct kvm_memory_slot *slot) | ||
67 | * Pin all pages we are about to map in memory. This is | ||
68 | * important because we unmap and unpin in 4kb steps later. | ||
69 | */ | ||
70 | - pfn = kvm_pin_pages(slot, gfn, page_size); | ||
71 | + pfn = kvm_pin_pages(slot, gfn, page_size >> PAGE_SHIFT); | ||
72 | if (is_error_noslot_pfn(pfn)) { | ||
73 | gfn += 1; | ||
74 | continue; | ||
75 | @@ -131,7 +131,7 @@ int kvm_iommu_map_pages(struct kvm *kvm, struct kvm_memory_slot *slot) | ||
76 | if (r) { | ||
77 | printk(KERN_ERR "kvm_iommu_map_address:" | ||
78 | "iommu failed to map pfn=%llx\n", pfn); | ||
79 | - kvm_unpin_pages(kvm, pfn, page_size); | ||
80 | + kvm_unpin_pages(kvm, pfn, page_size >> PAGE_SHIFT); | ||
81 | goto unmap_pages; | ||
82 | } | ||
83 | |||
84 | -- | ||
85 | 1.9.1 | ||
86 | |||
diff --git a/recipes-kernel/linux/files/0002-mnt-CVE-2014-5206_CVE-2014-5207.patch b/recipes-kernel/linux/files/0002-mnt-CVE-2014-5206_CVE-2014-5207.patch new file mode 100644 index 0000000..b08f217 --- /dev/null +++ b/recipes-kernel/linux/files/0002-mnt-CVE-2014-5206_CVE-2014-5207.patch | |||
@@ -0,0 +1,62 @@ | |||
1 | From cab259f821fad20afa688d3fbeb47356447ac20b Mon Sep 17 00:00:00 2001 | ||
2 | From: "Eric W. Biederman" <ebiederm@xmission.com> | ||
3 | Date: Mon, 28 Jul 2014 17:10:56 -0700 | ||
4 | Subject: [PATCH] mnt: Move the test for MNT_LOCK_READONLY from | ||
5 | change_mount_flags into do_remount | ||
6 | |||
7 | commit 07b645589dcda8b7a5249e096fece2a67556f0f4 upstream. | ||
8 | |||
9 | There are no races as locked mount flags are guaranteed to never change. | ||
10 | |||
11 | Moving the test into do_remount makes it more visible, and ensures all | ||
12 | filesystem remounts pass the MNT_LOCK_READONLY permission check. This | ||
13 | second case is not an issue today as filesystem remounts are guarded | ||
14 | by capable(CAP_DAC_ADMIN) and thus will always fail in less privileged | ||
15 | mount namespaces, but it could become an issue in the future. | ||
16 | |||
17 | Fix for CVE-2014-5206 and CVE-2014-5207 | ||
18 | Upstream-Status: backport | ||
19 | |||
20 | Cc: stable@vger.kernel.org | ||
21 | Acked-by: Serge E. Hallyn <serge.hallyn@ubuntu.com> | ||
22 | Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com> | ||
23 | Signed-off-by: Jiri Slaby <jslaby@suse.cz> | ||
24 | Signed-off-by: Sona Sarmadi <sona.sarmadi@enea.com> | ||
25 | --- | ||
26 | fs/namespace.c | 13 ++++++++++--- | ||
27 | 1 file changed, 10 insertions(+), 3 deletions(-) | ||
28 | |||
29 | diff --git a/fs/namespace.c b/fs/namespace.c | ||
30 | index 34fa7a5..8e90b03 100644 | ||
31 | --- a/fs/namespace.c | ||
32 | +++ b/fs/namespace.c | ||
33 | @@ -1806,9 +1806,6 @@ static int change_mount_flags(struct vfsmount *mnt, int ms_flags) | ||
34 | if (readonly_request == __mnt_is_readonly(mnt)) | ||
35 | return 0; | ||
36 | |||
37 | - if (mnt->mnt_flags & MNT_LOCK_READONLY) | ||
38 | - return -EPERM; | ||
39 | - | ||
40 | if (readonly_request) | ||
41 | error = mnt_make_readonly(real_mount(mnt)); | ||
42 | else | ||
43 | @@ -1834,6 +1831,16 @@ static int do_remount(struct path *path, int flags, int mnt_flags, | ||
44 | if (path->dentry != path->mnt->mnt_root) | ||
45 | return -EINVAL; | ||
46 | |||
47 | + /* Don't allow changing of locked mnt flags. | ||
48 | + * | ||
49 | + * No locks need to be held here while testing the various | ||
50 | + * MNT_LOCK flags because those flags can never be cleared | ||
51 | + * once they are set. | ||
52 | + */ | ||
53 | + if ((mnt->mnt.mnt_flags & MNT_LOCK_READONLY) && | ||
54 | + !(mnt_flags & MNT_READONLY)) { | ||
55 | + return -EPERM; | ||
56 | + } | ||
57 | err = security_sb_remount(sb, data); | ||
58 | if (err) | ||
59 | return err; | ||
60 | -- | ||
61 | 1.9.1 | ||
62 | |||
diff --git a/recipes-kernel/linux/files/0002-net-sctp-CVE-2014-3687.patch b/recipes-kernel/linux/files/0002-net-sctp-CVE-2014-3687.patch new file mode 100644 index 0000000..b05aaf2 --- /dev/null +++ b/recipes-kernel/linux/files/0002-net-sctp-CVE-2014-3687.patch | |||
@@ -0,0 +1,102 @@ | |||
1 | From a723db0be941b8aebaa1a98b33d17a91b16603e4 Mon Sep 17 00:00:00 2001 | ||
2 | From: Daniel Borkmann <dborkman@redhat.com> | ||
3 | Date: Thu, 9 Oct 2014 22:55:32 +0200 | ||
4 | Subject: [PATCH] net: sctp: fix panic on duplicate ASCONF chunks | ||
5 | |||
6 | commit b69040d8e39f20d5215a03502a8e8b4c6ab78395 upstream. | ||
7 | |||
8 | When receiving a e.g. semi-good formed connection scan in the | ||
9 | form of ... | ||
10 | |||
11 | -------------- INIT[ASCONF; ASCONF_ACK] -------------> | ||
12 | <----------- INIT-ACK[ASCONF; ASCONF_ACK] ------------ | ||
13 | -------------------- COOKIE-ECHO --------------------> | ||
14 | <-------------------- COOKIE-ACK --------------------- | ||
15 | ---------------- ASCONF_a; ASCONF_b -----------------> | ||
16 | |||
17 | ... where ASCONF_a equals ASCONF_b chunk (at least both serials | ||
18 | need to be equal), we panic an SCTP server! | ||
19 | |||
20 | The problem is that good-formed ASCONF chunks that we reply with | ||
21 | ASCONF_ACK chunks are cached per serial. Thus, when we receive a | ||
22 | same ASCONF chunk twice (e.g. through a lost ASCONF_ACK), we do | ||
23 | not need to process them again on the server side (that was the | ||
24 | idea, also proposed in the RFC). Instead, we know it was cached | ||
25 | and we just resend the cached chunk instead. So far, so good. | ||
26 | |||
27 | Where things get nasty is in SCTP's side effect interpreter, that | ||
28 | is, sctp_cmd_interpreter(): | ||
29 | |||
30 | While incoming ASCONF_a (chunk = event_arg) is being marked | ||
31 | !end_of_packet and !singleton, and we have an association context, | ||
32 | we do not flush the outqueue the first time after processing the | ||
33 | ASCONF_ACK singleton chunk via SCTP_CMD_REPLY. Instead, we keep it | ||
34 | queued up, although we set local_cork to 1. Commit 2e3216cd54b1 | ||
35 | changed the precedence, so that as long as we get bundled, incoming | ||
36 | chunks we try possible bundling on outgoing queue as well. Before | ||
37 | this commit, we would just flush the output queue. | ||
38 | |||
39 | Now, while ASCONF_a's ASCONF_ACK sits in the corked outq, we | ||
40 | continue to process the same ASCONF_b chunk from the packet. As | ||
41 | we have cached the previous ASCONF_ACK, we find it, grab it and | ||
42 | do another SCTP_CMD_REPLY command on it. So, effectively, we rip | ||
43 | the chunk->list pointers and requeue the same ASCONF_ACK chunk | ||
44 | another time. Since we process ASCONF_b, it's correctly marked | ||
45 | with end_of_packet and we enforce an uncork, and thus flush, thus | ||
46 | crashing the kernel. | ||
47 | |||
48 | Fix it by testing if the ASCONF_ACK is currently pending and if | ||
49 | that is the case, do not requeue it. When flushing the output | ||
50 | queue we may relink the chunk for preparing an outgoing packet, | ||
51 | but eventually unlink it when it's copied into the skb right | ||
52 | before transmission. | ||
53 | |||
54 | Joint work with Vlad Yasevich. | ||
55 | |||
56 | Fixes CVE-2014-3687 | ||
57 | Upstream-Status: Backport | ||
58 | |||
59 | Fixes: 2e3216cd54b1 ("sctp: Follow security requirement of responding with 1 packet") | ||
60 | Signed-off-by: Daniel Borkmann <dborkman@redhat.com> | ||
61 | Signed-off-by: Vlad Yasevich <vyasevich@gmail.com> | ||
62 | Signed-off-by: David S. Miller <davem@davemloft.net> | ||
63 | Cc: Josh Boyer <jwboyer@fedoraproject.org> | ||
64 | Signed-off-by: Jiri Slaby <jslaby@suse.cz> | ||
65 | Signed-off-by: Sona Sarmadi <sona.sarmadi@enea.com> | ||
66 | --- | ||
67 | include/net/sctp/sctp.h | 5 +++++ | ||
68 | net/sctp/associola.c | 2 ++ | ||
69 | 2 files changed, 7 insertions(+) | ||
70 | |||
71 | diff --git a/include/net/sctp/sctp.h b/include/net/sctp/sctp.h | ||
72 | index 3794c5a..3848934 100644 | ||
73 | --- a/include/net/sctp/sctp.h | ||
74 | +++ b/include/net/sctp/sctp.h | ||
75 | @@ -454,6 +454,11 @@ static inline void sctp_assoc_pending_pmtu(struct sock *sk, struct sctp_associat | ||
76 | asoc->pmtu_pending = 0; | ||
77 | } | ||
78 | |||
79 | +static inline bool sctp_chunk_pending(const struct sctp_chunk *chunk) | ||
80 | +{ | ||
81 | + return !list_empty(&chunk->list); | ||
82 | +} | ||
83 | + | ||
84 | /* Walk through a list of TLV parameters. Don't trust the | ||
85 | * individual parameter lengths and instead depend on | ||
86 | * the chunk length to indicate when to stop. Make sure | ||
87 | diff --git a/net/sctp/associola.c b/net/sctp/associola.c | ||
88 | index ad5cd6f..737050f 100644 | ||
89 | --- a/net/sctp/associola.c | ||
90 | +++ b/net/sctp/associola.c | ||
91 | @@ -1645,6 +1645,8 @@ struct sctp_chunk *sctp_assoc_lookup_asconf_ack( | ||
92 | * ack chunk whose serial number matches that of the request. | ||
93 | */ | ||
94 | list_for_each_entry(ack, &asoc->asconf_ack_list, transmitted_list) { | ||
95 | + if (sctp_chunk_pending(ack)) | ||
96 | + continue; | ||
97 | if (ack->subh.addip_hdr->serial == serial) { | ||
98 | sctp_chunk_hold(ack); | ||
99 | return ack; | ||
100 | -- | ||
101 | 1.9.1 | ||
102 | |||
diff --git a/recipes-kernel/linux/files/0003-HID-CVE-2014-3184.patch b/recipes-kernel/linux/files/0003-HID-CVE-2014-3184.patch new file mode 100644 index 0000000..f58b2f0 --- /dev/null +++ b/recipes-kernel/linux/files/0003-HID-CVE-2014-3184.patch | |||
@@ -0,0 +1,114 @@ | |||
1 | From 4ab25786c87eb20857bbb715c3ae34ec8fd6a214 Mon Sep 17 00:00:00 2001 | ||
2 | From: Jiri Kosina <jkosina@suse.cz> | ||
3 | Date: Thu, 21 Aug 2014 09:57:48 -0500 | ||
4 | Subject: [PATCH] HID: fix a couple of off-by-ones | ||
5 | |||
6 | There are a few very theoretical off-by-one bugs in report descriptor size | ||
7 | checking when performing a pre-parsing fixup. Fix those. | ||
8 | |||
9 | This fixes CVE-2014-3184 | ||
10 | Upstream-Status: Backport | ||
11 | |||
12 | Cc: stable@vger.kernel.org | ||
13 | Reported-by: Ben Hawkes <hawkes@google.com> | ||
14 | Reviewed-by: Benjamin Tissoires <benjamin.tissoires@redhat.com> | ||
15 | Signed-off-by: Jiri Kosina <jkosina@suse.cz> | ||
16 | Signed-off-by: Sona Sarmadi <sona.sarmadi@enea.com> | ||
17 | --- | ||
18 | drivers/hid/hid-cherry.c | 2 +- | ||
19 | drivers/hid/hid-kye.c | 2 +- | ||
20 | drivers/hid/hid-lg.c | 4 ++-- | ||
21 | drivers/hid/hid-monterey.c | 2 +- | ||
22 | drivers/hid/hid-petalynx.c | 2 +- | ||
23 | drivers/hid/hid-sunplus.c | 2 +- | ||
24 | 6 files changed, 7 insertions(+), 7 deletions(-) | ||
25 | |||
26 | diff --git a/drivers/hid/hid-cherry.c b/drivers/hid/hid-cherry.c | ||
27 | index 1bdcccc..f745d2c 100644 | ||
28 | --- a/drivers/hid/hid-cherry.c | ||
29 | +++ b/drivers/hid/hid-cherry.c | ||
30 | @@ -28,7 +28,7 @@ | ||
31 | static __u8 *ch_report_fixup(struct hid_device *hdev, __u8 *rdesc, | ||
32 | unsigned int *rsize) | ||
33 | { | ||
34 | - if (*rsize >= 17 && rdesc[11] == 0x3c && rdesc[12] == 0x02) { | ||
35 | + if (*rsize >= 18 && rdesc[11] == 0x3c && rdesc[12] == 0x02) { | ||
36 | hid_info(hdev, "fixing up Cherry Cymotion report descriptor\n"); | ||
37 | rdesc[11] = rdesc[16] = 0xff; | ||
38 | rdesc[12] = rdesc[17] = 0x03; | ||
39 | diff --git a/drivers/hid/hid-kye.c b/drivers/hid/hid-kye.c | ||
40 | index e776963..b92bf01 100644 | ||
41 | --- a/drivers/hid/hid-kye.c | ||
42 | +++ b/drivers/hid/hid-kye.c | ||
43 | @@ -300,7 +300,7 @@ static __u8 *kye_report_fixup(struct hid_device *hdev, __u8 *rdesc, | ||
44 | * - change the button usage range to 4-7 for the extra | ||
45 | * buttons | ||
46 | */ | ||
47 | - if (*rsize >= 74 && | ||
48 | + if (*rsize >= 75 && | ||
49 | rdesc[61] == 0x05 && rdesc[62] == 0x08 && | ||
50 | rdesc[63] == 0x19 && rdesc[64] == 0x08 && | ||
51 | rdesc[65] == 0x29 && rdesc[66] == 0x0f && | ||
52 | diff --git a/drivers/hid/hid-lg.c b/drivers/hid/hid-lg.c | ||
53 | index a976f48..f91ff14 100644 | ||
54 | --- a/drivers/hid/hid-lg.c | ||
55 | +++ b/drivers/hid/hid-lg.c | ||
56 | @@ -345,14 +345,14 @@ static __u8 *lg_report_fixup(struct hid_device *hdev, __u8 *rdesc, | ||
57 | struct usb_device_descriptor *udesc; | ||
58 | __u16 bcdDevice, rev_maj, rev_min; | ||
59 | |||
60 | - if ((drv_data->quirks & LG_RDESC) && *rsize >= 90 && rdesc[83] == 0x26 && | ||
61 | + if ((drv_data->quirks & LG_RDESC) && *rsize >= 91 && rdesc[83] == 0x26 && | ||
62 | rdesc[84] == 0x8c && rdesc[85] == 0x02) { | ||
63 | hid_info(hdev, | ||
64 | "fixing up Logitech keyboard report descriptor\n"); | ||
65 | rdesc[84] = rdesc[89] = 0x4d; | ||
66 | rdesc[85] = rdesc[90] = 0x10; | ||
67 | } | ||
68 | - if ((drv_data->quirks & LG_RDESC_REL_ABS) && *rsize >= 50 && | ||
69 | + if ((drv_data->quirks & LG_RDESC_REL_ABS) && *rsize >= 51 && | ||
70 | rdesc[32] == 0x81 && rdesc[33] == 0x06 && | ||
71 | rdesc[49] == 0x81 && rdesc[50] == 0x06) { | ||
72 | hid_info(hdev, | ||
73 | diff --git a/drivers/hid/hid-monterey.c b/drivers/hid/hid-monterey.c | ||
74 | index 9e14c00..25daf28 100644 | ||
75 | --- a/drivers/hid/hid-monterey.c | ||
76 | +++ b/drivers/hid/hid-monterey.c | ||
77 | @@ -24,7 +24,7 @@ | ||
78 | static __u8 *mr_report_fixup(struct hid_device *hdev, __u8 *rdesc, | ||
79 | unsigned int *rsize) | ||
80 | { | ||
81 | - if (*rsize >= 30 && rdesc[29] == 0x05 && rdesc[30] == 0x09) { | ||
82 | + if (*rsize >= 31 && rdesc[29] == 0x05 && rdesc[30] == 0x09) { | ||
83 | hid_info(hdev, "fixing up button/consumer in HID report descriptor\n"); | ||
84 | rdesc[30] = 0x0c; | ||
85 | } | ||
86 | diff --git a/drivers/hid/hid-petalynx.c b/drivers/hid/hid-petalynx.c | ||
87 | index 736b250..6aca4f2 100644 | ||
88 | --- a/drivers/hid/hid-petalynx.c | ||
89 | +++ b/drivers/hid/hid-petalynx.c | ||
90 | @@ -25,7 +25,7 @@ | ||
91 | static __u8 *pl_report_fixup(struct hid_device *hdev, __u8 *rdesc, | ||
92 | unsigned int *rsize) | ||
93 | { | ||
94 | - if (*rsize >= 60 && rdesc[39] == 0x2a && rdesc[40] == 0xf5 && | ||
95 | + if (*rsize >= 62 && rdesc[39] == 0x2a && rdesc[40] == 0xf5 && | ||
96 | rdesc[41] == 0x00 && rdesc[59] == 0x26 && | ||
97 | rdesc[60] == 0xf9 && rdesc[61] == 0x00) { | ||
98 | hid_info(hdev, "fixing up Petalynx Maxter Remote report descriptor\n"); | ||
99 | diff --git a/drivers/hid/hid-sunplus.c b/drivers/hid/hid-sunplus.c | ||
100 | index 87fc91e..91072fa 100644 | ||
101 | --- a/drivers/hid/hid-sunplus.c | ||
102 | +++ b/drivers/hid/hid-sunplus.c | ||
103 | @@ -24,7 +24,7 @@ | ||
104 | static __u8 *sp_report_fixup(struct hid_device *hdev, __u8 *rdesc, | ||
105 | unsigned int *rsize) | ||
106 | { | ||
107 | - if (*rsize >= 107 && rdesc[104] == 0x26 && rdesc[105] == 0x80 && | ||
108 | + if (*rsize >= 112 && rdesc[104] == 0x26 && rdesc[105] == 0x80 && | ||
109 | rdesc[106] == 0x03) { | ||
110 | hid_info(hdev, "fixing up Sunplus Wireless Desktop report descriptor\n"); | ||
111 | rdesc[105] = rdesc[110] = 0x03; | ||
112 | -- | ||
113 | 1.9.1 | ||
114 | |||
diff --git a/recipes-kernel/linux/files/0003-mnt-CVE-2014-5206_CVE-2014-5207.patch b/recipes-kernel/linux/files/0003-mnt-CVE-2014-5206_CVE-2014-5207.patch new file mode 100644 index 0000000..aa5ca1b --- /dev/null +++ b/recipes-kernel/linux/files/0003-mnt-CVE-2014-5206_CVE-2014-5207.patch | |||
@@ -0,0 +1,137 @@ | |||
1 | From 8b18c0adbc5d0cb1530692e72bcfb88fd7bb77bb Mon Sep 17 00:00:00 2001 | ||
2 | From: "Eric W. Biederman" <ebiederm@xmission.com> | ||
3 | Date: Mon, 28 Jul 2014 17:26:07 -0700 | ||
4 | Subject: [PATCH] mnt: Correct permission checks in do_remount | ||
5 | |||
6 | commit 9566d6742852c527bf5af38af5cbb878dad75705 upstream. | ||
7 | |||
8 | While invesgiating the issue where in "mount --bind -oremount,ro ..." | ||
9 | would result in later "mount --bind -oremount,rw" succeeding even if | ||
10 | the mount started off locked I realized that there are several | ||
11 | additional mount flags that should be locked and are not. | ||
12 | |||
13 | In particular MNT_NOSUID, MNT_NODEV, MNT_NOEXEC, and the atime | ||
14 | flags in addition to MNT_READONLY should all be locked. These | ||
15 | flags are all per superblock, can all be changed with MS_BIND, | ||
16 | and should not be changable if set by a more privileged user. | ||
17 | |||
18 | The following additions to the current logic are added in this patch. | ||
19 | - nosuid may not be clearable by a less privileged user. | ||
20 | - nodev may not be clearable by a less privielged user. | ||
21 | - noexec may not be clearable by a less privileged user. | ||
22 | - atime flags may not be changeable by a less privileged user. | ||
23 | |||
24 | The logic with atime is that always setting atime on access is a | ||
25 | global policy and backup software and auditing software could break if | ||
26 | atime bits are not updated (when they are configured to be updated), | ||
27 | and serious performance degradation could result (DOS attack) if atime | ||
28 | updates happen when they have been explicitly disabled. Therefore an | ||
29 | unprivileged user should not be able to mess with the atime bits set | ||
30 | by a more privileged user. | ||
31 | |||
32 | The additional restrictions are implemented with the addition of | ||
33 | MNT_LOCK_NOSUID, MNT_LOCK_NODEV, MNT_LOCK_NOEXEC, and MNT_LOCK_ATIME | ||
34 | mnt flags. | ||
35 | |||
36 | Taken together these changes and the fixes for MNT_LOCK_READONLY | ||
37 | should make it safe for an unprivileged user to create a user | ||
38 | namespace and to call "mount --bind -o remount,... ..." without | ||
39 | the danger of mount flags being changed maliciously. | ||
40 | |||
41 | Fix for CVE-2014-5206 and CVE-2014-5207 | ||
42 | Upstream-Status: backport | ||
43 | |||
44 | Cc: stable@vger.kernel.org | ||
45 | Acked-by: Serge E. Hallyn <serge.hallyn@ubuntu.com> | ||
46 | Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com> | ||
47 | Signed-off-by: Jiri Slaby <jslaby@suse.cz> | ||
48 | Signed-off-by: Sona Sarmadi <sona.sarmadi@enea.com> | ||
49 | --- | ||
50 | fs/namespace.c | 36 +++++++++++++++++++++++++++++++++--- | ||
51 | include/linux/mount.h | 5 +++++ | ||
52 | 2 files changed, 38 insertions(+), 3 deletions(-) | ||
53 | |||
54 | diff --git a/fs/namespace.c b/fs/namespace.c | ||
55 | index 8e90b03..7c67de8 100644 | ||
56 | --- a/fs/namespace.c | ||
57 | +++ b/fs/namespace.c | ||
58 | @@ -827,8 +827,21 @@ static struct mount *clone_mnt(struct mount *old, struct dentry *root, | ||
59 | |||
60 | mnt->mnt.mnt_flags = old->mnt.mnt_flags & ~MNT_WRITE_HOLD; | ||
61 | /* Don't allow unprivileged users to change mount flags */ | ||
62 | - if ((flag & CL_UNPRIVILEGED) && (mnt->mnt.mnt_flags & MNT_READONLY)) | ||
63 | - mnt->mnt.mnt_flags |= MNT_LOCK_READONLY; | ||
64 | + if (flag & CL_UNPRIVILEGED) { | ||
65 | + mnt->mnt.mnt_flags |= MNT_LOCK_ATIME; | ||
66 | + | ||
67 | + if (mnt->mnt.mnt_flags & MNT_READONLY) | ||
68 | + mnt->mnt.mnt_flags |= MNT_LOCK_READONLY; | ||
69 | + | ||
70 | + if (mnt->mnt.mnt_flags & MNT_NODEV) | ||
71 | + mnt->mnt.mnt_flags |= MNT_LOCK_NODEV; | ||
72 | + | ||
73 | + if (mnt->mnt.mnt_flags & MNT_NOSUID) | ||
74 | + mnt->mnt.mnt_flags |= MNT_LOCK_NOSUID; | ||
75 | + | ||
76 | + if (mnt->mnt.mnt_flags & MNT_NOEXEC) | ||
77 | + mnt->mnt.mnt_flags |= MNT_LOCK_NOEXEC; | ||
78 | + } | ||
79 | |||
80 | /* Don't allow unprivileged users to reveal what is under a mount */ | ||
81 | if ((flag & CL_UNPRIVILEGED) && list_empty(&old->mnt_expire)) | ||
82 | @@ -1841,6 +1854,23 @@ static int do_remount(struct path *path, int flags, int mnt_flags, | ||
83 | !(mnt_flags & MNT_READONLY)) { | ||
84 | return -EPERM; | ||
85 | } | ||
86 | + if ((mnt->mnt.mnt_flags & MNT_LOCK_NODEV) && | ||
87 | + !(mnt_flags & MNT_NODEV)) { | ||
88 | + return -EPERM; | ||
89 | + } | ||
90 | + if ((mnt->mnt.mnt_flags & MNT_LOCK_NOSUID) && | ||
91 | + !(mnt_flags & MNT_NOSUID)) { | ||
92 | + return -EPERM; | ||
93 | + } | ||
94 | + if ((mnt->mnt.mnt_flags & MNT_LOCK_NOEXEC) && | ||
95 | + !(mnt_flags & MNT_NOEXEC)) { | ||
96 | + return -EPERM; | ||
97 | + } | ||
98 | + if ((mnt->mnt.mnt_flags & MNT_LOCK_ATIME) && | ||
99 | + ((mnt->mnt.mnt_flags & MNT_ATIME_MASK) != (mnt_flags & MNT_ATIME_MASK))) { | ||
100 | + return -EPERM; | ||
101 | + } | ||
102 | + | ||
103 | err = security_sb_remount(sb, data); | ||
104 | if (err) | ||
105 | return err; | ||
106 | @@ -2043,7 +2073,7 @@ static int do_new_mount(struct path *path, const char *fstype, int flags, | ||
107 | */ | ||
108 | if (!(type->fs_flags & FS_USERNS_DEV_MOUNT)) { | ||
109 | flags |= MS_NODEV; | ||
110 | - mnt_flags |= MNT_NODEV; | ||
111 | + mnt_flags |= MNT_NODEV | MNT_LOCK_NODEV; | ||
112 | } | ||
113 | } | ||
114 | |||
115 | diff --git a/include/linux/mount.h b/include/linux/mount.h | ||
116 | index 8707c9e..22e5b96 100644 | ||
117 | --- a/include/linux/mount.h | ||
118 | +++ b/include/linux/mount.h | ||
119 | @@ -45,10 +45,15 @@ struct mnt_namespace; | ||
120 | #define MNT_USER_SETTABLE_MASK (MNT_NOSUID | MNT_NODEV | MNT_NOEXEC \ | ||
121 | | MNT_NOATIME | MNT_NODIRATIME | MNT_RELATIME \ | ||
122 | | MNT_READONLY) | ||
123 | +#define MNT_ATIME_MASK (MNT_NOATIME | MNT_NODIRATIME | MNT_RELATIME ) | ||
124 | |||
125 | |||
126 | #define MNT_INTERNAL 0x4000 | ||
127 | |||
128 | +#define MNT_LOCK_ATIME 0x040000 | ||
129 | +#define MNT_LOCK_NOEXEC 0x080000 | ||
130 | +#define MNT_LOCK_NOSUID 0x100000 | ||
131 | +#define MNT_LOCK_NODEV 0x200000 | ||
132 | #define MNT_LOCK_READONLY 0x400000 | ||
133 | #define MNT_LOCKED 0x800000 | ||
134 | |||
135 | -- | ||
136 | 1.9.1 | ||
137 | |||
diff --git a/recipes-kernel/linux/files/0003-net-sctp-CVE-2014-3688.patch b/recipes-kernel/linux/files/0003-net-sctp-CVE-2014-3688.patch new file mode 100644 index 0000000..1b4716d --- /dev/null +++ b/recipes-kernel/linux/files/0003-net-sctp-CVE-2014-3688.patch | |||
@@ -0,0 +1,160 @@ | |||
1 | From e476841415c1b7b54e4118d8a219f5db71878675 Mon Sep 17 00:00:00 2001 | ||
2 | From: Daniel Borkmann <dborkman@redhat.com> | ||
3 | Date: Thu, 9 Oct 2014 22:55:33 +0200 | ||
4 | Subject: [PATCH] net: sctp: fix remote memory pressure from excessive queueing | ||
5 | |||
6 | commit 26b87c7881006311828bb0ab271a551a62dcceb4 upstream. | ||
7 | |||
8 | This scenario is not limited to ASCONF, just taken as one | ||
9 | example triggering the issue. When receiving ASCONF probes | ||
10 | in the form of ... | ||
11 | |||
12 | -------------- INIT[ASCONF; ASCONF_ACK] -------------> | ||
13 | <----------- INIT-ACK[ASCONF; ASCONF_ACK] ------------ | ||
14 | -------------------- COOKIE-ECHO --------------------> | ||
15 | <-------------------- COOKIE-ACK --------------------- | ||
16 | ---- ASCONF_a; [ASCONF_b; ...; ASCONF_n;] JUNK ------> | ||
17 | [...] | ||
18 | ---- ASCONF_m; [ASCONF_o; ...; ASCONF_z;] JUNK ------> | ||
19 | |||
20 | ... where ASCONF_a, ASCONF_b, ..., ASCONF_z are good-formed | ||
21 | ASCONFs and have increasing serial numbers, we process such | ||
22 | ASCONF chunk(s) marked with !end_of_packet and !singleton, | ||
23 | since we have not yet reached the SCTP packet end. SCTP does | ||
24 | only do verification on a chunk by chunk basis, as an SCTP | ||
25 | packet is nothing more than just a container of a stream of | ||
26 | chunks which it eats up one by one. | ||
27 | |||
28 | We could run into the case that we receive a packet with a | ||
29 | malformed tail, above marked as trailing JUNK. All previous | ||
30 | chunks are here goodformed, so the stack will eat up all | ||
31 | previous chunks up to this point. In case JUNK does not fit | ||
32 | into a chunk header and there are no more other chunks in | ||
33 | the input queue, or in case JUNK contains a garbage chunk | ||
34 | header, but the encoded chunk length would exceed the skb | ||
35 | tail, or we came here from an entirely different scenario | ||
36 | and the chunk has pdiscard=1 mark (without having had a flush | ||
37 | point), it will happen, that we will excessively queue up | ||
38 | the association's output queue (a correct final chunk may | ||
39 | then turn it into a response flood when flushing the | ||
40 | queue ;)): I ran a simple script with incremental ASCONF | ||
41 | serial numbers and could see the server side consuming | ||
42 | excessive amount of RAM [before/after: up to 2GB and more]. | ||
43 | |||
44 | The issue at heart is that the chunk train basically ends | ||
45 | with !end_of_packet and !singleton markers and since commit | ||
46 | 2e3216cd54b1 ("sctp: Follow security requirement of responding | ||
47 | with 1 packet") therefore preventing an output queue flush | ||
48 | point in sctp_do_sm() -> sctp_cmd_interpreter() on the input | ||
49 | chunk (chunk = event_arg) even though local_cork is set, | ||
50 | but its precedence has changed since then. In the normal | ||
51 | case, the last chunk with end_of_packet=1 would trigger the | ||
52 | queue flush to accommodate possible outgoing bundling. | ||
53 | |||
54 | In the input queue, sctp_inq_pop() seems to do the right thing | ||
55 | in terms of discarding invalid chunks. So, above JUNK will | ||
56 | not enter the state machine and instead be released and exit | ||
57 | the sctp_assoc_bh_rcv() chunk processing loop. It's simply | ||
58 | the flush point being missing at loop exit. Adding a try-flush | ||
59 | approach on the output queue might not work as the underlying | ||
60 | infrastructure might be long gone at this point due to the | ||
61 | side-effect interpreter run. | ||
62 | |||
63 | One possibility, albeit a bit of a kludge, would be to defer | ||
64 | invalid chunk freeing into the state machine in order to | ||
65 | possibly trigger packet discards and thus indirectly a queue | ||
66 | flush on error. It would surely be better to discard chunks | ||
67 | as in the current, perhaps better controlled environment, but | ||
68 | going back and forth, it's simply architecturally not possible. | ||
69 | I tried various trailing JUNK attack cases and it seems to | ||
70 | look good now. | ||
71 | |||
72 | Joint work with Vlad Yasevich. | ||
73 | |||
74 | Fixes CVE-2014-3688 | ||
75 | Upstream-Status: Backport | ||
76 | |||
77 | Fixes: 2e3216cd54b1 ("sctp: Follow security requirement of responding with 1 packet") | ||
78 | Signed-off-by: Daniel Borkmann <dborkman@redhat.com> | ||
79 | Signed-off-by: Vlad Yasevich <vyasevich@gmail.com> | ||
80 | Signed-off-by: David S. Miller <davem@davemloft.net> | ||
81 | Cc: Josh Boyer <jwboyer@fedoraproject.org> | ||
82 | Signed-off-by: Jiri Slaby <jslaby@suse.cz> | ||
83 | Signed-off-by: Sona Sarmadi <sona.sarmadi@enea.com> | ||
84 | --- | ||
85 | net/sctp/inqueue.c | 33 +++++++-------------------------- | ||
86 | net/sctp/sm_statefuns.c | 3 +++ | ||
87 | 2 files changed, 10 insertions(+), 26 deletions(-) | ||
88 | |||
89 | diff --git a/net/sctp/inqueue.c b/net/sctp/inqueue.c | ||
90 | index 5856932..560cd41 100644 | ||
91 | --- a/net/sctp/inqueue.c | ||
92 | +++ b/net/sctp/inqueue.c | ||
93 | @@ -141,18 +141,9 @@ struct sctp_chunk *sctp_inq_pop(struct sctp_inq *queue) | ||
94 | } else { | ||
95 | /* Nothing to do. Next chunk in the packet, please. */ | ||
96 | ch = (sctp_chunkhdr_t *) chunk->chunk_end; | ||
97 | - | ||
98 | /* Force chunk->skb->data to chunk->chunk_end. */ | ||
99 | - skb_pull(chunk->skb, | ||
100 | - chunk->chunk_end - chunk->skb->data); | ||
101 | - | ||
102 | - /* Verify that we have at least chunk headers | ||
103 | - * worth of buffer left. | ||
104 | - */ | ||
105 | - if (skb_headlen(chunk->skb) < sizeof(sctp_chunkhdr_t)) { | ||
106 | - sctp_chunk_free(chunk); | ||
107 | - chunk = queue->in_progress = NULL; | ||
108 | - } | ||
109 | + skb_pull(chunk->skb, chunk->chunk_end - chunk->skb->data); | ||
110 | + /* We are guaranteed to pull a SCTP header. */ | ||
111 | } | ||
112 | } | ||
113 | |||
114 | @@ -188,24 +179,14 @@ struct sctp_chunk *sctp_inq_pop(struct sctp_inq *queue) | ||
115 | skb_pull(chunk->skb, sizeof(sctp_chunkhdr_t)); | ||
116 | chunk->subh.v = NULL; /* Subheader is no longer valid. */ | ||
117 | |||
118 | - if (chunk->chunk_end < skb_tail_pointer(chunk->skb)) { | ||
119 | + if (chunk->chunk_end + sizeof(sctp_chunkhdr_t) < | ||
120 | + skb_tail_pointer(chunk->skb)) { | ||
121 | /* This is not a singleton */ | ||
122 | chunk->singleton = 0; | ||
123 | } else if (chunk->chunk_end > skb_tail_pointer(chunk->skb)) { | ||
124 | - /* RFC 2960, Section 6.10 Bundling | ||
125 | - * | ||
126 | - * Partial chunks MUST NOT be placed in an SCTP packet. | ||
127 | - * If the receiver detects a partial chunk, it MUST drop | ||
128 | - * the chunk. | ||
129 | - * | ||
130 | - * Since the end of the chunk is past the end of our buffer | ||
131 | - * (which contains the whole packet, we can freely discard | ||
132 | - * the whole packet. | ||
133 | - */ | ||
134 | - sctp_chunk_free(chunk); | ||
135 | - chunk = queue->in_progress = NULL; | ||
136 | - | ||
137 | - return NULL; | ||
138 | + /* Discard inside state machine. */ | ||
139 | + chunk->pdiscard = 1; | ||
140 | + chunk->chunk_end = skb_tail_pointer(chunk->skb); | ||
141 | } else { | ||
142 | /* We are at the end of the packet, so mark the chunk | ||
143 | * in case we need to send a SACK. | ||
144 | diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c | ||
145 | index 1dbcc6a..62623cc 100644 | ||
146 | --- a/net/sctp/sm_statefuns.c | ||
147 | +++ b/net/sctp/sm_statefuns.c | ||
148 | @@ -171,6 +171,9 @@ sctp_chunk_length_valid(struct sctp_chunk *chunk, | ||
149 | { | ||
150 | __u16 chunk_length = ntohs(chunk->chunk_hdr->length); | ||
151 | |||
152 | + /* Previously already marked? */ | ||
153 | + if (unlikely(chunk->pdiscard)) | ||
154 | + return 0; | ||
155 | if (unlikely(chunk_length < required_length)) | ||
156 | return 0; | ||
157 | |||
158 | -- | ||
159 | 1.9.1 | ||
160 | |||
diff --git a/recipes-kernel/linux/files/0004-USB-CVE-2014-3185.patch b/recipes-kernel/linux/files/0004-USB-CVE-2014-3185.patch new file mode 100644 index 0000000..0820807 --- /dev/null +++ b/recipes-kernel/linux/files/0004-USB-CVE-2014-3185.patch | |||
@@ -0,0 +1,51 @@ | |||
1 | From 6817ae225cd650fb1c3295d769298c38b1eba818 Mon Sep 17 00:00:00 2001 | ||
2 | From: James Forshaw <forshaw@google.com> | ||
3 | Date: Sat, 23 Aug 2014 14:39:48 -0700 | ||
4 | Subject: [PATCH] USB: whiteheat: Added bounds checking for bulk command | ||
5 | response | ||
6 | |||
7 | This patch fixes a potential security issue in the whiteheat USB driver | ||
8 | which might allow a local attacker to cause kernel memory corrpution. This | ||
9 | is due to an unchecked memcpy into a fixed size buffer (of 64 bytes). On | ||
10 | EHCI and XHCI busses it's possible to craft responses greater than 64 | ||
11 | bytes leading a buffer overflow. | ||
12 | |||
13 | This fixes CVE-2014-3185 | ||
14 | Upstream-Status: Backport | ||
15 | |||
16 | Signed-off-by: James Forshaw <forshaw@google.com> | ||
17 | Cc: stable <stable@vger.kernel.org> | ||
18 | Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | ||
19 | Signed-off-by: Sona Sarmadi <sona.sarmadi@enea.com> | ||
20 | --- | ||
21 | drivers/usb/serial/whiteheat.c | 7 ++++++- | ||
22 | 1 file changed, 6 insertions(+), 1 deletion(-) | ||
23 | |||
24 | diff --git a/drivers/usb/serial/whiteheat.c b/drivers/usb/serial/whiteheat.c | ||
25 | index e62f2df..6c3734d 100644 | ||
26 | --- a/drivers/usb/serial/whiteheat.c | ||
27 | +++ b/drivers/usb/serial/whiteheat.c | ||
28 | @@ -514,6 +514,10 @@ static void command_port_read_callback(struct urb *urb) | ||
29 | dev_dbg(&urb->dev->dev, "%s - command_info is NULL, exiting.\n", __func__); | ||
30 | return; | ||
31 | } | ||
32 | + if (!urb->actual_length) { | ||
33 | + dev_dbg(&urb->dev->dev, "%s - empty response, exiting.\n", __func__); | ||
34 | + return; | ||
35 | + } | ||
36 | if (status) { | ||
37 | dev_dbg(&urb->dev->dev, "%s - nonzero urb status: %d\n", __func__, status); | ||
38 | if (status != -ENOENT) | ||
39 | @@ -534,7 +538,8 @@ static void command_port_read_callback(struct urb *urb) | ||
40 | /* These are unsolicited reports from the firmware, hence no | ||
41 | waiting command to wakeup */ | ||
42 | dev_dbg(&urb->dev->dev, "%s - event received\n", __func__); | ||
43 | - } else if (data[0] == WHITEHEAT_GET_DTR_RTS) { | ||
44 | + } else if ((data[0] == WHITEHEAT_GET_DTR_RTS) && | ||
45 | + (urb->actual_length - 1 <= sizeof(command_info->result_buffer))) { | ||
46 | memcpy(command_info->result_buffer, &data[1], | ||
47 | urb->actual_length - 1); | ||
48 | command_info->command_finished = WHITEHEAT_CMD_COMPLETE; | ||
49 | -- | ||
50 | 1.9.1 | ||
51 | |||
diff --git a/recipes-kernel/linux/files/0004-mnt-CVE-2014-5206_CVE-2014-5207.patch b/recipes-kernel/linux/files/0004-mnt-CVE-2014-5206_CVE-2014-5207.patch new file mode 100644 index 0000000..8cd4b13 --- /dev/null +++ b/recipes-kernel/linux/files/0004-mnt-CVE-2014-5206_CVE-2014-5207.patch | |||
@@ -0,0 +1,64 @@ | |||
1 | From fafbc9412b8f2dae04bc3ca233ae7b49482c8df8 Mon Sep 17 00:00:00 2001 | ||
2 | From: "Eric W. Biederman" <ebiederm@xmission.com> | ||
3 | Date: Mon, 28 Jul 2014 17:36:04 -0700 | ||
4 | Subject: [PATCH] mnt: Change the default remount atime from relatime to the | ||
5 | existing value | ||
6 | |||
7 | commit ffbc6f0ead47fa5a1dc9642b0331cb75c20a640e upstream. | ||
8 | |||
9 | Since March 2009 the kernel has treated the state that if no | ||
10 | MS_..ATIME flags are passed then the kernel defaults to relatime. | ||
11 | |||
12 | Defaulting to relatime instead of the existing atime state during a | ||
13 | remount is silly, and causes problems in practice for people who don't | ||
14 | specify any MS_...ATIME flags and to get the default filesystem atime | ||
15 | setting. Those users may encounter a permission error because the | ||
16 | default atime setting does not work. | ||
17 | |||
18 | A default that does not work and causes permission problems is | ||
19 | ridiculous, so preserve the existing value to have a default | ||
20 | atime setting that is always guaranteed to work. | ||
21 | |||
22 | Using the default atime setting in this way is particularly | ||
23 | interesting for applications built to run in restricted userspace | ||
24 | environments without /proc mounted, as the existing atime mount | ||
25 | options of a filesystem can not be read from /proc/mounts. | ||
26 | |||
27 | In practice this fixes user space that uses the default atime | ||
28 | setting on remount that are broken by the permission checks | ||
29 | keeping less privileged users from changing more privileged users | ||
30 | atime settings. | ||
31 | |||
32 | Fix for CVE-2014-5206 and CVE-2014-5207 | ||
33 | Upstream-Status: backport | ||
34 | |||
35 | Acked-by: Serge E. Hallyn <serge.hallyn@ubuntu.com> | ||
36 | Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com> | ||
37 | Signed-off-by: Jiri Slaby <jslaby@suse.cz> | ||
38 | Signed-off-by: Sona Sarmadi <sona.sarmadi@enea.com> | ||
39 | --- | ||
40 | fs/namespace.c | 8 ++++++++ | ||
41 | 1 file changed, 8 insertions(+) | ||
42 | |||
43 | diff --git a/fs/namespace.c b/fs/namespace.c | ||
44 | index 7c67de8..4ea2b73 100644 | ||
45 | --- a/fs/namespace.c | ||
46 | +++ b/fs/namespace.c | ||
47 | @@ -2391,6 +2391,14 @@ long do_mount(const char *dev_name, const char *dir_name, | ||
48 | if (flags & MS_RDONLY) | ||
49 | mnt_flags |= MNT_READONLY; | ||
50 | |||
51 | + /* The default atime for remount is preservation */ | ||
52 | + if ((flags & MS_REMOUNT) && | ||
53 | + ((flags & (MS_NOATIME | MS_NODIRATIME | MS_RELATIME | | ||
54 | + MS_STRICTATIME)) == 0)) { | ||
55 | + mnt_flags &= ~MNT_ATIME_MASK; | ||
56 | + mnt_flags |= path.mnt->mnt_flags & MNT_ATIME_MASK; | ||
57 | + } | ||
58 | + | ||
59 | flags &= ~(MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_ACTIVE | MS_BORN | | ||
60 | MS_NOATIME | MS_NODIRATIME | MS_RELATIME| MS_KERNMOUNT | | ||
61 | MS_STRICTATIME); | ||
62 | -- | ||
63 | 1.9.1 | ||
64 | |||
diff --git a/recipes-kernel/linux/files/0005-mnt-CVE-2014-5206_CVE-2014-5207.patch b/recipes-kernel/linux/files/0005-mnt-CVE-2014-5206_CVE-2014-5207.patch new file mode 100644 index 0000000..caa89db --- /dev/null +++ b/recipes-kernel/linux/files/0005-mnt-CVE-2014-5206_CVE-2014-5207.patch | |||
@@ -0,0 +1,324 @@ | |||
1 | From 4194b9700ce41ff2f7031aa0c6108c2539028ab5 Mon Sep 17 00:00:00 2001 | ||
2 | From: "Eric W. Biederman" <ebiederm@xmission.com> | ||
3 | Date: Tue, 29 Jul 2014 15:50:44 -0700 | ||
4 | Subject: [PATCH] mnt: Add tests for unprivileged remount cases that have found | ||
5 | to be faulty | ||
6 | |||
7 | commit db181ce011e3c033328608299cd6fac06ea50130 upstream. | ||
8 | |||
9 | Kenton Varda <kenton@sandstorm.io> discovered that by remounting a | ||
10 | read-only bind mount read-only in a user namespace the | ||
11 | MNT_LOCK_READONLY bit would be cleared, allowing an unprivileged user | ||
12 | to the remount a read-only mount read-write. | ||
13 | |||
14 | Upon review of the code in remount it was discovered that the code allowed | ||
15 | nosuid, noexec, and nodev to be cleared. It was also discovered that | ||
16 | the code was allowing the per mount atime flags to be changed. | ||
17 | |||
18 | The first naive patch to fix these issues contained the flaw that using | ||
19 | default atime settings when remounting a filesystem could be disallowed. | ||
20 | |||
21 | To avoid this problems in the future add tests to ensure unprivileged | ||
22 | remounts are succeeding and failing at the appropriate times. | ||
23 | |||
24 | Fix for CVE-2014-5206 and CVE-2014-5207 | ||
25 | Upstream-Status: backport | ||
26 | |||
27 | Acked-by: Serge E. Hallyn <serge.hallyn@ubuntu.com> | ||
28 | Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com> | ||
29 | Signed-off-by: Jiri Slaby <jslaby@suse.cz> | ||
30 | Signed-off-by: Sona Sarmadi <sona.sarmadi@enea.com> | ||
31 | --- | ||
32 | tools/testing/selftests/Makefile | 1 + | ||
33 | tools/testing/selftests/mount/Makefile | 17 ++ | ||
34 | .../selftests/mount/unprivileged-remount-test.c | 242 +++++++++++++++++++++ | ||
35 | 3 files changed, 260 insertions(+) | ||
36 | create mode 100644 tools/testing/selftests/mount/Makefile | ||
37 | create mode 100644 tools/testing/selftests/mount/unprivileged-remount-test.c | ||
38 | |||
39 | diff --git a/tools/testing/selftests/Makefile b/tools/testing/selftests/Makefile | ||
40 | index 9f3eae2..2d9ab94 100644 | ||
41 | --- a/tools/testing/selftests/Makefile | ||
42 | +++ b/tools/testing/selftests/Makefile | ||
43 | @@ -4,6 +4,7 @@ TARGETS += efivarfs | ||
44 | TARGETS += kcmp | ||
45 | TARGETS += memory-hotplug | ||
46 | TARGETS += mqueue | ||
47 | +TARGETS += mount | ||
48 | TARGETS += net | ||
49 | TARGETS += ptrace | ||
50 | TARGETS += timers | ||
51 | diff --git a/tools/testing/selftests/mount/Makefile b/tools/testing/selftests/mount/Makefile | ||
52 | new file mode 100644 | ||
53 | index 0000000..337d853 | ||
54 | --- /dev/null | ||
55 | +++ b/tools/testing/selftests/mount/Makefile | ||
56 | @@ -0,0 +1,17 @@ | ||
57 | +# Makefile for mount selftests. | ||
58 | + | ||
59 | +all: unprivileged-remount-test | ||
60 | + | ||
61 | +unprivileged-remount-test: unprivileged-remount-test.c | ||
62 | + gcc -Wall -O2 unprivileged-remount-test.c -o unprivileged-remount-test | ||
63 | + | ||
64 | +# Allow specific tests to be selected. | ||
65 | +test_unprivileged_remount: unprivileged-remount-test | ||
66 | + @if [ -f /proc/self/uid_map ] ; then ./unprivileged-remount-test ; fi | ||
67 | + | ||
68 | +run_tests: all test_unprivileged_remount | ||
69 | + | ||
70 | +clean: | ||
71 | + rm -f unprivileged-remount-test | ||
72 | + | ||
73 | +.PHONY: all test_unprivileged_remount | ||
74 | diff --git a/tools/testing/selftests/mount/unprivileged-remount-test.c b/tools/testing/selftests/mount/unprivileged-remount-test.c | ||
75 | new file mode 100644 | ||
76 | index 0000000..1b3ff2f | ||
77 | --- /dev/null | ||
78 | +++ b/tools/testing/selftests/mount/unprivileged-remount-test.c | ||
79 | @@ -0,0 +1,242 @@ | ||
80 | +#define _GNU_SOURCE | ||
81 | +#include <sched.h> | ||
82 | +#include <stdio.h> | ||
83 | +#include <errno.h> | ||
84 | +#include <string.h> | ||
85 | +#include <sys/types.h> | ||
86 | +#include <sys/mount.h> | ||
87 | +#include <sys/wait.h> | ||
88 | +#include <stdlib.h> | ||
89 | +#include <unistd.h> | ||
90 | +#include <fcntl.h> | ||
91 | +#include <grp.h> | ||
92 | +#include <stdbool.h> | ||
93 | +#include <stdarg.h> | ||
94 | + | ||
95 | +#ifndef CLONE_NEWNS | ||
96 | +# define CLONE_NEWNS 0x00020000 | ||
97 | +#endif | ||
98 | +#ifndef CLONE_NEWUTS | ||
99 | +# define CLONE_NEWUTS 0x04000000 | ||
100 | +#endif | ||
101 | +#ifndef CLONE_NEWIPC | ||
102 | +# define CLONE_NEWIPC 0x08000000 | ||
103 | +#endif | ||
104 | +#ifndef CLONE_NEWNET | ||
105 | +# define CLONE_NEWNET 0x40000000 | ||
106 | +#endif | ||
107 | +#ifndef CLONE_NEWUSER | ||
108 | +# define CLONE_NEWUSER 0x10000000 | ||
109 | +#endif | ||
110 | +#ifndef CLONE_NEWPID | ||
111 | +# define CLONE_NEWPID 0x20000000 | ||
112 | +#endif | ||
113 | + | ||
114 | +#ifndef MS_RELATIME | ||
115 | +#define MS_RELATIME (1 << 21) | ||
116 | +#endif | ||
117 | +#ifndef MS_STRICTATIME | ||
118 | +#define MS_STRICTATIME (1 << 24) | ||
119 | +#endif | ||
120 | + | ||
121 | +static void die(char *fmt, ...) | ||
122 | +{ | ||
123 | + va_list ap; | ||
124 | + va_start(ap, fmt); | ||
125 | + vfprintf(stderr, fmt, ap); | ||
126 | + va_end(ap); | ||
127 | + exit(EXIT_FAILURE); | ||
128 | +} | ||
129 | + | ||
130 | +static void write_file(char *filename, char *fmt, ...) | ||
131 | +{ | ||
132 | + char buf[4096]; | ||
133 | + int fd; | ||
134 | + ssize_t written; | ||
135 | + int buf_len; | ||
136 | + va_list ap; | ||
137 | + | ||
138 | + va_start(ap, fmt); | ||
139 | + buf_len = vsnprintf(buf, sizeof(buf), fmt, ap); | ||
140 | + va_end(ap); | ||
141 | + if (buf_len < 0) { | ||
142 | + die("vsnprintf failed: %s\n", | ||
143 | + strerror(errno)); | ||
144 | + } | ||
145 | + if (buf_len >= sizeof(buf)) { | ||
146 | + die("vsnprintf output truncated\n"); | ||
147 | + } | ||
148 | + | ||
149 | + fd = open(filename, O_WRONLY); | ||
150 | + if (fd < 0) { | ||
151 | + die("open of %s failed: %s\n", | ||
152 | + filename, strerror(errno)); | ||
153 | + } | ||
154 | + written = write(fd, buf, buf_len); | ||
155 | + if (written != buf_len) { | ||
156 | + if (written >= 0) { | ||
157 | + die("short write to %s\n", filename); | ||
158 | + } else { | ||
159 | + die("write to %s failed: %s\n", | ||
160 | + filename, strerror(errno)); | ||
161 | + } | ||
162 | + } | ||
163 | + if (close(fd) != 0) { | ||
164 | + die("close of %s failed: %s\n", | ||
165 | + filename, strerror(errno)); | ||
166 | + } | ||
167 | +} | ||
168 | + | ||
169 | +static void create_and_enter_userns(void) | ||
170 | +{ | ||
171 | + uid_t uid; | ||
172 | + gid_t gid; | ||
173 | + | ||
174 | + uid = getuid(); | ||
175 | + gid = getgid(); | ||
176 | + | ||
177 | + if (unshare(CLONE_NEWUSER) !=0) { | ||
178 | + die("unshare(CLONE_NEWUSER) failed: %s\n", | ||
179 | + strerror(errno)); | ||
180 | + } | ||
181 | + | ||
182 | + write_file("/proc/self/uid_map", "0 %d 1", uid); | ||
183 | + write_file("/proc/self/gid_map", "0 %d 1", gid); | ||
184 | + | ||
185 | + if (setgroups(0, NULL) != 0) { | ||
186 | + die("setgroups failed: %s\n", | ||
187 | + strerror(errno)); | ||
188 | + } | ||
189 | + if (setgid(0) != 0) { | ||
190 | + die ("setgid(0) failed %s\n", | ||
191 | + strerror(errno)); | ||
192 | + } | ||
193 | + if (setuid(0) != 0) { | ||
194 | + die("setuid(0) failed %s\n", | ||
195 | + strerror(errno)); | ||
196 | + } | ||
197 | +} | ||
198 | + | ||
199 | +static | ||
200 | +bool test_unpriv_remount(int mount_flags, int remount_flags, int invalid_flags) | ||
201 | +{ | ||
202 | + pid_t child; | ||
203 | + | ||
204 | + child = fork(); | ||
205 | + if (child == -1) { | ||
206 | + die("fork failed: %s\n", | ||
207 | + strerror(errno)); | ||
208 | + } | ||
209 | + if (child != 0) { /* parent */ | ||
210 | + pid_t pid; | ||
211 | + int status; | ||
212 | + pid = waitpid(child, &status, 0); | ||
213 | + if (pid == -1) { | ||
214 | + die("waitpid failed: %s\n", | ||
215 | + strerror(errno)); | ||
216 | + } | ||
217 | + if (pid != child) { | ||
218 | + die("waited for %d got %d\n", | ||
219 | + child, pid); | ||
220 | + } | ||
221 | + if (!WIFEXITED(status)) { | ||
222 | + die("child did not terminate cleanly\n"); | ||
223 | + } | ||
224 | + return WEXITSTATUS(status) == EXIT_SUCCESS ? true : false; | ||
225 | + } | ||
226 | + | ||
227 | + create_and_enter_userns(); | ||
228 | + if (unshare(CLONE_NEWNS) != 0) { | ||
229 | + die("unshare(CLONE_NEWNS) failed: %s\n", | ||
230 | + strerror(errno)); | ||
231 | + } | ||
232 | + | ||
233 | + if (mount("testing", "/tmp", "ramfs", mount_flags, NULL) != 0) { | ||
234 | + die("mount of /tmp failed: %s\n", | ||
235 | + strerror(errno)); | ||
236 | + } | ||
237 | + | ||
238 | + create_and_enter_userns(); | ||
239 | + | ||
240 | + if (unshare(CLONE_NEWNS) != 0) { | ||
241 | + die("unshare(CLONE_NEWNS) failed: %s\n", | ||
242 | + strerror(errno)); | ||
243 | + } | ||
244 | + | ||
245 | + if (mount("/tmp", "/tmp", "none", | ||
246 | + MS_REMOUNT | MS_BIND | remount_flags, NULL) != 0) { | ||
247 | + /* system("cat /proc/self/mounts"); */ | ||
248 | + die("remount of /tmp failed: %s\n", | ||
249 | + strerror(errno)); | ||
250 | + } | ||
251 | + | ||
252 | + if (mount("/tmp", "/tmp", "none", | ||
253 | + MS_REMOUNT | MS_BIND | invalid_flags, NULL) == 0) { | ||
254 | + /* system("cat /proc/self/mounts"); */ | ||
255 | + die("remount of /tmp with invalid flags " | ||
256 | + "succeeded unexpectedly\n"); | ||
257 | + } | ||
258 | + exit(EXIT_SUCCESS); | ||
259 | +} | ||
260 | + | ||
261 | +static bool test_unpriv_remount_simple(int mount_flags) | ||
262 | +{ | ||
263 | + return test_unpriv_remount(mount_flags, mount_flags, 0); | ||
264 | +} | ||
265 | + | ||
266 | +static bool test_unpriv_remount_atime(int mount_flags, int invalid_flags) | ||
267 | +{ | ||
268 | + return test_unpriv_remount(mount_flags, mount_flags, invalid_flags); | ||
269 | +} | ||
270 | + | ||
271 | +int main(int argc, char **argv) | ||
272 | +{ | ||
273 | + if (!test_unpriv_remount_simple(MS_RDONLY|MS_NODEV)) { | ||
274 | + die("MS_RDONLY malfunctions\n"); | ||
275 | + } | ||
276 | + if (!test_unpriv_remount_simple(MS_NODEV)) { | ||
277 | + die("MS_NODEV malfunctions\n"); | ||
278 | + } | ||
279 | + if (!test_unpriv_remount_simple(MS_NOSUID|MS_NODEV)) { | ||
280 | + die("MS_NOSUID malfunctions\n"); | ||
281 | + } | ||
282 | + if (!test_unpriv_remount_simple(MS_NOEXEC|MS_NODEV)) { | ||
283 | + die("MS_NOEXEC malfunctions\n"); | ||
284 | + } | ||
285 | + if (!test_unpriv_remount_atime(MS_RELATIME|MS_NODEV, | ||
286 | + MS_NOATIME|MS_NODEV)) | ||
287 | + { | ||
288 | + die("MS_RELATIME malfunctions\n"); | ||
289 | + } | ||
290 | + if (!test_unpriv_remount_atime(MS_STRICTATIME|MS_NODEV, | ||
291 | + MS_NOATIME|MS_NODEV)) | ||
292 | + { | ||
293 | + die("MS_STRICTATIME malfunctions\n"); | ||
294 | + } | ||
295 | + if (!test_unpriv_remount_atime(MS_NOATIME|MS_NODEV, | ||
296 | + MS_STRICTATIME|MS_NODEV)) | ||
297 | + { | ||
298 | + die("MS_RELATIME malfunctions\n"); | ||
299 | + } | ||
300 | + if (!test_unpriv_remount_atime(MS_RELATIME|MS_NODIRATIME|MS_NODEV, | ||
301 | + MS_NOATIME|MS_NODEV)) | ||
302 | + { | ||
303 | + die("MS_RELATIME malfunctions\n"); | ||
304 | + } | ||
305 | + if (!test_unpriv_remount_atime(MS_STRICTATIME|MS_NODIRATIME|MS_NODEV, | ||
306 | + MS_NOATIME|MS_NODEV)) | ||
307 | + { | ||
308 | + die("MS_RELATIME malfunctions\n"); | ||
309 | + } | ||
310 | + if (!test_unpriv_remount_atime(MS_NOATIME|MS_NODIRATIME|MS_NODEV, | ||
311 | + MS_STRICTATIME|MS_NODEV)) | ||
312 | + { | ||
313 | + die("MS_RELATIME malfunctions\n"); | ||
314 | + } | ||
315 | + if (!test_unpriv_remount(MS_STRICTATIME|MS_NODEV, MS_NODEV, | ||
316 | + MS_NOATIME|MS_NODEV)) | ||
317 | + { | ||
318 | + die("Default atime malfunctions\n"); | ||
319 | + } | ||
320 | + return EXIT_SUCCESS; | ||
321 | +} | ||
322 | -- | ||
323 | 1.9.1 | ||
324 | |||
diff --git a/recipes-kernel/linux/files/Fix-CVE-2014-5077-sctp-inherit-auth-capable-on-INIT-collisions.patch b/recipes-kernel/linux/files/Fix-CVE-2014-5077-sctp-inherit-auth-capable-on-INIT-collisions.patch new file mode 100644 index 0000000..7d16535 --- /dev/null +++ b/recipes-kernel/linux/files/Fix-CVE-2014-5077-sctp-inherit-auth-capable-on-INIT-collisions.patch | |||
@@ -0,0 +1,41 @@ | |||
1 | CVE-2014-5077 Kernel/SCTP: fix a NULL pointer dereference | ||
2 | |||
3 | A NULL pointer dereference flaw was found in the way the | ||
4 | Linux kernel's Stream Control Transmission Protocol | ||
5 | (SCTP) implementation handled simultaneous connections | ||
6 | between the same hosts. A remote attacker could use this | ||
7 | flaw to crash the system. | ||
8 | |||
9 | Upstream-Status: Backport (from v3.16, commit 1be9a950c646c) | ||
10 | |||
11 | References: | ||
12 | - https://access.redhat.com/security/cve/CVE-2014-5077 | ||
13 | - http://patchwork.ozlabs.org/patch/372475/ | ||
14 | |||
15 | Fixes: 730fc3d05cd4 ("[SCTP]: Implete SCTP-AUTH parameter processing") | ||
16 | Reported-by: Jason Gunthorpe <jgunthorpe@obsidianresearch.com> | ||
17 | Signed-off-by: Daniel Borkmann <dborkman@redhat.com> | ||
18 | Tested-by: Jason Gunthorpe <jgunthorpe@obsidianresearch.com> | ||
19 | Cc: Vlad Yasevich <vyasevich@gmail.com> | ||
20 | Acked-by: Vlad Yasevich <vyasevich@gmail.com> | ||
21 | Signed-off-by: David S. Miller <davem@davemloft.net> | ||
22 | Signed-off-by: Liviu Gheorghisan <liviu.gheorghisan@enea.com> | ||
23 | --- | ||
24 | net/sctp/associola.c | 1 + | ||
25 | 1 file changed, 1 insertion(+) | ||
26 | |||
27 | diff --git a/net/sctp/associola.c b/net/sctp/associola.c | ||
28 | index 9de23a2..06a9ee6 100644 | ||
29 | --- a/net/sctp/associola.c | ||
30 | +++ b/net/sctp/associola.c | ||
31 | @@ -1097,6 +1097,7 @@ void sctp_assoc_update(struct sctp_association *asoc, | ||
32 | asoc->c = new->c; | ||
33 | asoc->peer.rwnd = new->peer.rwnd; | ||
34 | asoc->peer.sack_needed = new->peer.sack_needed; | ||
35 | + asoc->peer.auth_capable = new->peer.auth_capable; | ||
36 | asoc->peer.i = new->peer.i; | ||
37 | sctp_tsnmap_init(&asoc->peer.tsn_map, SCTP_TSN_MAP_INITIAL, | ||
38 | asoc->peer.i.initial_tsn, GFP_ATOMIC); | ||
39 | -- | ||
40 | 1.9.1 | ||
41 | |||
diff --git a/recipes-kernel/linux/files/Fix-CVE-2014-5471_CVE-2014-5472.patch b/recipes-kernel/linux/files/Fix-CVE-2014-5471_CVE-2014-5472.patch new file mode 100644 index 0000000..65107d6 --- /dev/null +++ b/recipes-kernel/linux/files/Fix-CVE-2014-5471_CVE-2014-5472.patch | |||
@@ -0,0 +1,212 @@ | |||
1 | From 4488e1f5ef40441c9846b1d0a29152c208a05e66 Mon Sep 17 00:00:00 2001 | ||
2 | From: Jan Kara <jack@suse.cz> | ||
3 | Date: Sun, 17 Aug 2014 11:49:57 +0200 | ||
4 | Subject: [PATCH] isofs: Fix unbounded recursion when processing relocated | ||
5 | directories | ||
6 | |||
7 | commit 410dd3cf4c9b36f27ed4542ee18b1af5e68645a4 upstream. | ||
8 | |||
9 | We did not check relocated directory in any way when processing Rock | ||
10 | Ridge 'CL' tag. Thus a corrupted isofs image can possibly have a CL | ||
11 | entry pointing to another CL entry leading to possibly unbounded | ||
12 | recursion in kernel code and thus stack overflow or deadlocks (if there | ||
13 | is a loop created from CL entries). | ||
14 | |||
15 | Fix the problem by not allowing CL entry to point to a directory entry | ||
16 | with CL entry (such use makes no good sense anyway) and by checking | ||
17 | whether CL entry doesn't point to itself. | ||
18 | |||
19 | Upstream status: backported (from v3.12 e4ca8b780c82c04ec0) | ||
20 | |||
21 | Reported-by: Chris Evans <cevans@google.com> | ||
22 | Signed-off-by: Jan Kara <jack@suse.cz> | ||
23 | Signed-off-by: Jiri Slaby <jslaby@suse.cz> | ||
24 | Signed-off-by: Sona Sarmadi <sona.sarmadi@enea.com> | ||
25 | --- | ||
26 | fs/isofs/inode.c | 15 ++++++++------- | ||
27 | fs/isofs/isofs.h | 23 +++++++++++++++++++---- | ||
28 | fs/isofs/rock.c | 39 ++++++++++++++++++++++++++++----------- | ||
29 | 3 files changed, 55 insertions(+), 22 deletions(-) | ||
30 | |||
31 | diff --git a/fs/isofs/inode.c b/fs/isofs/inode.c | ||
32 | index e5d408a..2e2af97 100644 | ||
33 | --- a/fs/isofs/inode.c | ||
34 | +++ b/fs/isofs/inode.c | ||
35 | @@ -61,7 +61,7 @@ static void isofs_put_super(struct super_block *sb) | ||
36 | return; | ||
37 | } | ||
38 | |||
39 | -static int isofs_read_inode(struct inode *); | ||
40 | +static int isofs_read_inode(struct inode *, int relocated); | ||
41 | static int isofs_statfs (struct dentry *, struct kstatfs *); | ||
42 | |||
43 | static struct kmem_cache *isofs_inode_cachep; | ||
44 | @@ -1258,7 +1258,7 @@ out_toomany: | ||
45 | goto out; | ||
46 | } | ||
47 | |||
48 | -static int isofs_read_inode(struct inode *inode) | ||
49 | +static int isofs_read_inode(struct inode *inode, int relocated) | ||
50 | { | ||
51 | struct super_block *sb = inode->i_sb; | ||
52 | struct isofs_sb_info *sbi = ISOFS_SB(sb); | ||
53 | @@ -1403,7 +1403,7 @@ static int isofs_read_inode(struct inode *inode) | ||
54 | */ | ||
55 | |||
56 | if (!high_sierra) { | ||
57 | - parse_rock_ridge_inode(de, inode); | ||
58 | + parse_rock_ridge_inode(de, inode, relocated); | ||
59 | /* if we want uid/gid set, override the rock ridge setting */ | ||
60 | if (sbi->s_uid_set) | ||
61 | inode->i_uid = sbi->s_uid; | ||
62 | @@ -1482,9 +1482,10 @@ static int isofs_iget5_set(struct inode *ino, void *data) | ||
63 | * offset that point to the underlying meta-data for the inode. The | ||
64 | * code below is otherwise similar to the iget() code in | ||
65 | * include/linux/fs.h */ | ||
66 | -struct inode *isofs_iget(struct super_block *sb, | ||
67 | - unsigned long block, | ||
68 | - unsigned long offset) | ||
69 | +struct inode *__isofs_iget(struct super_block *sb, | ||
70 | + unsigned long block, | ||
71 | + unsigned long offset, | ||
72 | + int relocated) | ||
73 | { | ||
74 | unsigned long hashval; | ||
75 | struct inode *inode; | ||
76 | @@ -1506,7 +1507,7 @@ struct inode *isofs_iget(struct super_block *sb, | ||
77 | return ERR_PTR(-ENOMEM); | ||
78 | |||
79 | if (inode->i_state & I_NEW) { | ||
80 | - ret = isofs_read_inode(inode); | ||
81 | + ret = isofs_read_inode(inode, relocated); | ||
82 | if (ret < 0) { | ||
83 | iget_failed(inode); | ||
84 | inode = ERR_PTR(ret); | ||
85 | diff --git a/fs/isofs/isofs.h b/fs/isofs/isofs.h | ||
86 | index 9916723..0ac4c1f 100644 | ||
87 | --- a/fs/isofs/isofs.h | ||
88 | +++ b/fs/isofs/isofs.h | ||
89 | @@ -107,7 +107,7 @@ extern int iso_date(char *, int); | ||
90 | |||
91 | struct inode; /* To make gcc happy */ | ||
92 | |||
93 | -extern int parse_rock_ridge_inode(struct iso_directory_record *, struct inode *); | ||
94 | +extern int parse_rock_ridge_inode(struct iso_directory_record *, struct inode *, int relocated); | ||
95 | extern int get_rock_ridge_filename(struct iso_directory_record *, char *, struct inode *); | ||
96 | extern int isofs_name_translate(struct iso_directory_record *, char *, struct inode *); | ||
97 | |||
98 | @@ -118,9 +118,24 @@ extern struct dentry *isofs_lookup(struct inode *, struct dentry *, unsigned int | ||
99 | extern struct buffer_head *isofs_bread(struct inode *, sector_t); | ||
100 | extern int isofs_get_blocks(struct inode *, sector_t, struct buffer_head **, unsigned long); | ||
101 | |||
102 | -extern struct inode *isofs_iget(struct super_block *sb, | ||
103 | - unsigned long block, | ||
104 | - unsigned long offset); | ||
105 | +struct inode *__isofs_iget(struct super_block *sb, | ||
106 | + unsigned long block, | ||
107 | + unsigned long offset, | ||
108 | + int relocated); | ||
109 | + | ||
110 | +static inline struct inode *isofs_iget(struct super_block *sb, | ||
111 | + unsigned long block, | ||
112 | + unsigned long offset) | ||
113 | +{ | ||
114 | + return __isofs_iget(sb, block, offset, 0); | ||
115 | +} | ||
116 | + | ||
117 | +static inline struct inode *isofs_iget_reloc(struct super_block *sb, | ||
118 | + unsigned long block, | ||
119 | + unsigned long offset) | ||
120 | +{ | ||
121 | + return __isofs_iget(sb, block, offset, 1); | ||
122 | +} | ||
123 | |||
124 | /* Because the inode number is no longer relevant to finding the | ||
125 | * underlying meta-data for an inode, we are free to choose a more | ||
126 | diff --git a/fs/isofs/rock.c b/fs/isofs/rock.c | ||
127 | index c0bf424..f488bba 100644 | ||
128 | --- a/fs/isofs/rock.c | ||
129 | +++ b/fs/isofs/rock.c | ||
130 | @@ -288,12 +288,16 @@ eio: | ||
131 | goto out; | ||
132 | } | ||
133 | |||
134 | +#define RR_REGARD_XA 1 | ||
135 | +#define RR_RELOC_DE 2 | ||
136 | + | ||
137 | static int | ||
138 | parse_rock_ridge_inode_internal(struct iso_directory_record *de, | ||
139 | - struct inode *inode, int regard_xa) | ||
140 | + struct inode *inode, int flags) | ||
141 | { | ||
142 | int symlink_len = 0; | ||
143 | int cnt, sig; | ||
144 | + unsigned int reloc_block; | ||
145 | struct inode *reloc; | ||
146 | struct rock_ridge *rr; | ||
147 | int rootflag; | ||
148 | @@ -305,7 +309,7 @@ parse_rock_ridge_inode_internal(struct iso_directory_record *de, | ||
149 | |||
150 | init_rock_state(&rs, inode); | ||
151 | setup_rock_ridge(de, inode, &rs); | ||
152 | - if (regard_xa) { | ||
153 | + if (flags & RR_REGARD_XA) { | ||
154 | rs.chr += 14; | ||
155 | rs.len -= 14; | ||
156 | if (rs.len < 0) | ||
157 | @@ -485,12 +489,22 @@ repeat: | ||
158 | "relocated directory\n"); | ||
159 | goto out; | ||
160 | case SIG('C', 'L'): | ||
161 | - ISOFS_I(inode)->i_first_extent = | ||
162 | - isonum_733(rr->u.CL.location); | ||
163 | - reloc = | ||
164 | - isofs_iget(inode->i_sb, | ||
165 | - ISOFS_I(inode)->i_first_extent, | ||
166 | - 0); | ||
167 | + if (flags & RR_RELOC_DE) { | ||
168 | + printk(KERN_ERR | ||
169 | + "ISOFS: Recursive directory relocation " | ||
170 | + "is not supported\n"); | ||
171 | + goto eio; | ||
172 | + } | ||
173 | + reloc_block = isonum_733(rr->u.CL.location); | ||
174 | + if (reloc_block == ISOFS_I(inode)->i_iget5_block && | ||
175 | + ISOFS_I(inode)->i_iget5_offset == 0) { | ||
176 | + printk(KERN_ERR | ||
177 | + "ISOFS: Directory relocation points to " | ||
178 | + "itself\n"); | ||
179 | + goto eio; | ||
180 | + } | ||
181 | + ISOFS_I(inode)->i_first_extent = reloc_block; | ||
182 | + reloc = isofs_iget_reloc(inode->i_sb, reloc_block, 0); | ||
183 | if (IS_ERR(reloc)) { | ||
184 | ret = PTR_ERR(reloc); | ||
185 | goto out; | ||
186 | @@ -637,9 +651,11 @@ static char *get_symlink_chunk(char *rpnt, struct rock_ridge *rr, char *plimit) | ||
187 | return rpnt; | ||
188 | } | ||
189 | |||
190 | -int parse_rock_ridge_inode(struct iso_directory_record *de, struct inode *inode) | ||
191 | +int parse_rock_ridge_inode(struct iso_directory_record *de, struct inode *inode, | ||
192 | + int relocated) | ||
193 | { | ||
194 | - int result = parse_rock_ridge_inode_internal(de, inode, 0); | ||
195 | + int flags = relocated ? RR_RELOC_DE : 0; | ||
196 | + int result = parse_rock_ridge_inode_internal(de, inode, flags); | ||
197 | |||
198 | /* | ||
199 | * if rockridge flag was reset and we didn't look for attributes | ||
200 | @@ -647,7 +663,8 @@ int parse_rock_ridge_inode(struct iso_directory_record *de, struct inode *inode) | ||
201 | */ | ||
202 | if ((ISOFS_SB(inode->i_sb)->s_rock_offset == -1) | ||
203 | && (ISOFS_SB(inode->i_sb)->s_rock == 2)) { | ||
204 | - result = parse_rock_ridge_inode_internal(de, inode, 14); | ||
205 | + result = parse_rock_ridge_inode_internal(de, inode, | ||
206 | + flags | RR_REGARD_XA); | ||
207 | } | ||
208 | return result; | ||
209 | } | ||
210 | -- | ||
211 | 1.9.1 | ||
212 | |||
diff --git a/recipes-kernel/linux/files/Fix-for-CVE-2014-5045-fs-umount-on-symlink-leak.patch b/recipes-kernel/linux/files/Fix-for-CVE-2014-5045-fs-umount-on-symlink-leak.patch new file mode 100644 index 0000000..1ae600f --- /dev/null +++ b/recipes-kernel/linux/files/Fix-for-CVE-2014-5045-fs-umount-on-symlink-leak.patch | |||
@@ -0,0 +1,47 @@ | |||
1 | fs: umount on symlink leaks mnt count | ||
2 | |||
3 | commit 295dc39d941dc2ae53d5c170365af4c9d5c16212 upstream. | ||
4 | |||
5 | Currently umount on symlink blocks following umount: | ||
6 | |||
7 | /vz is separate mount | ||
8 | |||
9 | drwxr-xr-x. 2 root root 4096 Jul 19 01:14 testdir | ||
10 | lrwxrwxrwx. 1 root root 11 Jul 19 01:16 testlink -> /vz/testdir | ||
11 | umount: /vz/testlink: not mounted (expected) | ||
12 | |||
13 | umount: /vz: device is busy. (unexpected) | ||
14 | |||
15 | In this case mountpoint_last() gets an extra refcount on path->mnt | ||
16 | |||
17 | Upstream-Status: Backport | ||
18 | |||
19 | Signed-off-by: Vasily Averin <vvs@openvz.org> | ||
20 | Acked-by: Ian Kent <raven@themaw.net> | ||
21 | Acked-by: Jeff Layton <jlayton@primarydata.com> | ||
22 | Cc: stable@vger.kernel.org | ||
23 | Signed-off-by: Christoph Hellwig <hch@lst.de> | ||
24 | Signed-off-by: Sona Sarmadi <sona.sarmadi@enea.com> | ||
25 | --- | ||
26 | fs/namei.c | 3 ++- | ||
27 | 1 file changed, 2 insertions(+), 1 deletion(-) | ||
28 | |||
29 | diff --git a/fs/namei.c b/fs/namei.c | ||
30 | index 187cacf..c199dcc 100644 | ||
31 | --- a/fs/namei.c | ||
32 | +++ b/fs/namei.c | ||
33 | @@ -2280,9 +2280,10 @@ done: | ||
34 | goto out; | ||
35 | } | ||
36 | path->dentry = dentry; | ||
37 | - path->mnt = mntget(nd->path.mnt); | ||
38 | + path->mnt = nd->path.mnt; | ||
39 | if (should_follow_link(dentry->d_inode, nd->flags & LOOKUP_FOLLOW)) | ||
40 | return 1; | ||
41 | + mntget(path->mnt); | ||
42 | follow_mount(path); | ||
43 | error = 0; | ||
44 | out: | ||
45 | -- | ||
46 | 1.9.1 | ||
47 | |||
diff --git a/recipes-kernel/linux/files/auditsc-CVE-2014-3917.patch b/recipes-kernel/linux/files/auditsc-CVE-2014-3917.patch new file mode 100644 index 0000000..a0bdc27 --- /dev/null +++ b/recipes-kernel/linux/files/auditsc-CVE-2014-3917.patch | |||
@@ -0,0 +1,91 @@ | |||
1 | From 6004b0e5ac2e8e9e1bb0f012dc9242e03cca95df Mon Sep 17 00:00:00 2001 | ||
2 | From: Andy Lutomirski <luto@amacapital.net> | ||
3 | Date: Wed, 28 May 2014 23:09:58 -0400 | ||
4 | Subject: [PATCH] auditsc: audit_krule mask accesses need bounds checking | ||
5 | |||
6 | commit a3c54931199565930d6d84f4c3456f6440aefd41 upstream. | ||
7 | |||
8 | Fixes an easy DoS and possible information disclosure. | ||
9 | |||
10 | This does nothing about the broken state of x32 auditing. | ||
11 | |||
12 | eparis: If the admin has enabled auditd and has specifically loaded | ||
13 | audit rules. This bug has been around since before git. Wow... | ||
14 | |||
15 | This fixes CVE-2014-3917 | ||
16 | Upstream-Status: Backport | ||
17 | |||
18 | Signed-off-by: Andy Lutomirski <luto@amacapital.net> | ||
19 | Signed-off-by: Eric Paris <eparis@redhat.com> | ||
20 | Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> | ||
21 | Signed-off-by: Jiri Slaby <jslaby@suse.cz> | ||
22 | Signed-off-by: Sona Sarmadi <sona.sarmadi@enea.com> | ||
23 | --- | ||
24 | kernel/auditsc.c | 27 ++++++++++++++++++--------- | ||
25 | 1 file changed, 18 insertions(+), 9 deletions(-) | ||
26 | |||
27 | diff --git a/kernel/auditsc.c b/kernel/auditsc.c | ||
28 | index 3b79a47..979c00b 100644 | ||
29 | --- a/kernel/auditsc.c | ||
30 | +++ b/kernel/auditsc.c | ||
31 | @@ -733,6 +733,22 @@ static enum audit_state audit_filter_task(struct task_struct *tsk, char **key) | ||
32 | return AUDIT_BUILD_CONTEXT; | ||
33 | } | ||
34 | |||
35 | +static int audit_in_mask(const struct audit_krule *rule, unsigned long val) | ||
36 | +{ | ||
37 | + int word, bit; | ||
38 | + | ||
39 | + if (val > 0xffffffff) | ||
40 | + return false; | ||
41 | + | ||
42 | + word = AUDIT_WORD(val); | ||
43 | + if (word >= AUDIT_BITMASK_SIZE) | ||
44 | + return false; | ||
45 | + | ||
46 | + bit = AUDIT_BIT(val); | ||
47 | + | ||
48 | + return rule->mask[word] & bit; | ||
49 | +} | ||
50 | + | ||
51 | /* At syscall entry and exit time, this filter is called if the | ||
52 | * audit_state is not low enough that auditing cannot take place, but is | ||
53 | * also not high enough that we already know we have to write an audit | ||
54 | @@ -750,11 +766,8 @@ static enum audit_state audit_filter_syscall(struct task_struct *tsk, | ||
55 | |||
56 | rcu_read_lock(); | ||
57 | if (!list_empty(list)) { | ||
58 | - int word = AUDIT_WORD(ctx->major); | ||
59 | - int bit = AUDIT_BIT(ctx->major); | ||
60 | - | ||
61 | list_for_each_entry_rcu(e, list, list) { | ||
62 | - if ((e->rule.mask[word] & bit) == bit && | ||
63 | + if (audit_in_mask(&e->rule, ctx->major) && | ||
64 | audit_filter_rules(tsk, &e->rule, ctx, NULL, | ||
65 | &state, false)) { | ||
66 | rcu_read_unlock(); | ||
67 | @@ -774,20 +787,16 @@ static enum audit_state audit_filter_syscall(struct task_struct *tsk, | ||
68 | static int audit_filter_inode_name(struct task_struct *tsk, | ||
69 | struct audit_names *n, | ||
70 | struct audit_context *ctx) { | ||
71 | - int word, bit; | ||
72 | int h = audit_hash_ino((u32)n->ino); | ||
73 | struct list_head *list = &audit_inode_hash[h]; | ||
74 | struct audit_entry *e; | ||
75 | enum audit_state state; | ||
76 | |||
77 | - word = AUDIT_WORD(ctx->major); | ||
78 | - bit = AUDIT_BIT(ctx->major); | ||
79 | - | ||
80 | if (list_empty(list)) | ||
81 | return 0; | ||
82 | |||
83 | list_for_each_entry_rcu(e, list, list) { | ||
84 | - if ((e->rule.mask[word] & bit) == bit && | ||
85 | + if (audit_in_mask(&e->rule, ctx->major) && | ||
86 | audit_filter_rules(tsk, &e->rule, ctx, n, &state, false)) { | ||
87 | ctx->current_state = state; | ||
88 | return 1; | ||
89 | -- | ||
90 | 1.9.1 | ||
91 | |||
diff --git a/recipes-kernel/linux/files/modify-defconfig-t1040-nr-cpus.patch b/recipes-kernel/linux/files/modify-defconfig-t1040-nr-cpus.patch new file mode 100644 index 0000000..635c2bb --- /dev/null +++ b/recipes-kernel/linux/files/modify-defconfig-t1040-nr-cpus.patch | |||
@@ -0,0 +1,47 @@ | |||
1 | From 8545129540a5862b22aad03badb2a9f93bf29117 Mon Sep 17 00:00:00 2001 | ||
2 | From: Bob Cochran <yocto@mindchasers.com> | ||
3 | Date: Mon, 3 Nov 2014 22:45:35 -0500 | ||
4 | Subject: [meta-fsl-ppc][PATCH] linux-qoriq: Change defconfig for T1040 to | ||
5 | match number of CPUS | ||
6 | |||
7 | Having a number higher than necessary for NR_CPUS wastes memory by | ||
8 | instantiating unnecessary structures in RAM. An example is in the DPAA where | ||
9 | DPAA_ETH_TX_QUEUES is defined based on NR_CPUS and used to create | ||
10 | dozens of extra qman_fq structures. Using the prior value of 24, which was | ||
11 | left over from the T4240 created an additonal 60 frame queue structures alone. | ||
12 | |||
13 | This has been tested on t1040rdb-64b. . | ||
14 | |||
15 | Signed-off-by: Bob Cochran <yocto@mindchasers.com> | ||
16 | --- | ||
17 | arch/powerpc/configs/corenet32_fmanv3_smp_defconfig | 2 +- | ||
18 | arch/powerpc/configs/corenet64_fmanv3_smp_defconfig | 2 +- | ||
19 | 2 files changed, 2 insertions(+), 2 deletions(-) | ||
20 | |||
21 | diff --git a/arch/powerpc/configs/corenet32_fmanv3_smp_defconfig b/arch/powerpc/configs/corenet32_fmanv3_smp_defconfig | ||
22 | index a401e7c..5542248 100644 | ||
23 | --- a/arch/powerpc/configs/corenet32_fmanv3_smp_defconfig | ||
24 | +++ b/arch/powerpc/configs/corenet32_fmanv3_smp_defconfig | ||
25 | @@ -1,6 +1,6 @@ | ||
26 | CONFIG_PPC_85xx=y | ||
27 | CONFIG_SMP=y | ||
28 | -CONFIG_NR_CPUS=8 | ||
29 | +CONFIG_NR_CPUS=4 | ||
30 | CONFIG_EXPERIMENTAL=y | ||
31 | CONFIG_SYSVIPC=y | ||
32 | CONFIG_POSIX_MQUEUE=y | ||
33 | diff --git a/arch/powerpc/configs/corenet64_fmanv3_smp_defconfig b/arch/powerpc/configs/corenet64_fmanv3_smp_defconfig | ||
34 | index 1b987d9..bc0dacf 100644 | ||
35 | --- a/arch/powerpc/configs/corenet64_fmanv3_smp_defconfig | ||
36 | +++ b/arch/powerpc/configs/corenet64_fmanv3_smp_defconfig | ||
37 | @@ -2,7 +2,7 @@ CONFIG_PPC64=y | ||
38 | CONFIG_PPC_BOOK3E_64=y | ||
39 | CONFIG_ALTIVEC=y | ||
40 | CONFIG_SMP=y | ||
41 | -CONFIG_NR_CPUS=24 | ||
42 | +CONFIG_NR_CPUS=4 | ||
43 | CONFIG_SYSVIPC=y | ||
44 | CONFIG_POSIX_MQUEUE=y | ||
45 | CONFIG_IRQ_DOMAIN_DEBUG=y | ||
46 | -- | ||
47 | 1.7.9.5 | ||
diff --git a/recipes-kernel/linux/files/net-sctp-CVE-2014-0101.patch b/recipes-kernel/linux/files/net-sctp-CVE-2014-0101.patch new file mode 100644 index 0000000..6fc5610 --- /dev/null +++ b/recipes-kernel/linux/files/net-sctp-CVE-2014-0101.patch | |||
@@ -0,0 +1,145 @@ | |||
1 | From 00c53b02cb01976b35d37670a4b5c5d7a6ad3c62 Mon Sep 17 00:00:00 2001 | ||
2 | From: Daniel Borkmann <dborkman@redhat.com> | ||
3 | Date: Mon, 3 Mar 2014 17:23:04 +0100 | ||
4 | Subject: [PATCH] net: sctp: fix sctp_sf_do_5_1D_ce to verify if we/peer is | ||
5 | AUTH capable | ||
6 | |||
7 | [ Upstream commit ec0223ec48a90cb605244b45f7c62de856403729 ] | ||
8 | |||
9 | RFC4895 introduced AUTH chunks for SCTP; during the SCTP | ||
10 | handshake RANDOM; CHUNKS; HMAC-ALGO are negotiated (CHUNKS | ||
11 | being optional though): | ||
12 | |||
13 | ---------- INIT[RANDOM; CHUNKS; HMAC-ALGO] ----------> | ||
14 | <------- INIT-ACK[RANDOM; CHUNKS; HMAC-ALGO] --------- | ||
15 | -------------------- COOKIE-ECHO --------------------> | ||
16 | <-------------------- COOKIE-ACK --------------------- | ||
17 | |||
18 | A special case is when an endpoint requires COOKIE-ECHO | ||
19 | chunks to be authenticated: | ||
20 | |||
21 | ---------- INIT[RANDOM; CHUNKS; HMAC-ALGO] ----------> | ||
22 | <------- INIT-ACK[RANDOM; CHUNKS; HMAC-ALGO] --------- | ||
23 | ------------------ AUTH; COOKIE-ECHO ----------------> | ||
24 | <-------------------- COOKIE-ACK --------------------- | ||
25 | |||
26 | RFC4895, section 6.3. Receiving Authenticated Chunks says: | ||
27 | |||
28 | The receiver MUST use the HMAC algorithm indicated in | ||
29 | the HMAC Identifier field. If this algorithm was not | ||
30 | specified by the receiver in the HMAC-ALGO parameter in | ||
31 | the INIT or INIT-ACK chunk during association setup, the | ||
32 | AUTH chunk and all the chunks after it MUST be discarded | ||
33 | and an ERROR chunk SHOULD be sent with the error cause | ||
34 | defined in Section 4.1. [...] If no endpoint pair shared | ||
35 | key has been configured for that Shared Key Identifier, | ||
36 | all authenticated chunks MUST be silently discarded. [...] | ||
37 | |||
38 | When an endpoint requires COOKIE-ECHO chunks to be | ||
39 | authenticated, some special procedures have to be followed | ||
40 | because the reception of a COOKIE-ECHO chunk might result | ||
41 | in the creation of an SCTP association. If a packet arrives | ||
42 | containing an AUTH chunk as a first chunk, a COOKIE-ECHO | ||
43 | chunk as the second chunk, and possibly more chunks after | ||
44 | them, and the receiver does not have an STCB for that | ||
45 | packet, then authentication is based on the contents of | ||
46 | the COOKIE-ECHO chunk. In this situation, the receiver MUST | ||
47 | authenticate the chunks in the packet by using the RANDOM | ||
48 | parameters, CHUNKS parameters and HMAC_ALGO parameters | ||
49 | obtained from the COOKIE-ECHO chunk, and possibly a local | ||
50 | shared secret as inputs to the authentication procedure | ||
51 | specified in Section 6.3. If authentication fails, then | ||
52 | the packet is discarded. If the authentication is successful, | ||
53 | the COOKIE-ECHO and all the chunks after the COOKIE-ECHO | ||
54 | MUST be processed. If the receiver has an STCB, it MUST | ||
55 | process the AUTH chunk as described above using the STCB | ||
56 | from the existing association to authenticate the | ||
57 | COOKIE-ECHO chunk and all the chunks after it. [...] | ||
58 | |||
59 | Commit bbd0d59809f9 introduced the possibility to receive | ||
60 | and verification of AUTH chunk, including the edge case for | ||
61 | authenticated COOKIE-ECHO. On reception of COOKIE-ECHO, | ||
62 | the function sctp_sf_do_5_1D_ce() handles processing, | ||
63 | unpacks and creates a new association if it passed sanity | ||
64 | checks and also tests for authentication chunks being | ||
65 | present. After a new association has been processed, it | ||
66 | invokes sctp_process_init() on the new association and | ||
67 | walks through the parameter list it received from the INIT | ||
68 | chunk. It checks SCTP_PARAM_RANDOM, SCTP_PARAM_HMAC_ALGO | ||
69 | and SCTP_PARAM_CHUNKS, and copies them into asoc->peer | ||
70 | meta data (peer_random, peer_hmacs, peer_chunks) in case | ||
71 | sysctl -w net.sctp.auth_enable=1 is set. If in INIT's | ||
72 | SCTP_PARAM_SUPPORTED_EXT parameter SCTP_CID_AUTH is set, | ||
73 | peer_random != NULL and peer_hmacs != NULL the peer is to be | ||
74 | assumed asoc->peer.auth_capable=1, in any other case | ||
75 | asoc->peer.auth_capable=0. | ||
76 | |||
77 | Now, if in sctp_sf_do_5_1D_ce() chunk->auth_chunk is | ||
78 | available, we set up a fake auth chunk and pass that on to | ||
79 | sctp_sf_authenticate(), which at latest in | ||
80 | sctp_auth_calculate_hmac() reliably dereferences a NULL pointer | ||
81 | at position 0..0008 when setting up the crypto key in | ||
82 | crypto_hash_setkey() by using asoc->asoc_shared_key that is | ||
83 | NULL as condition key_id == asoc->active_key_id is true if | ||
84 | the AUTH chunk was injected correctly from remote. This | ||
85 | happens no matter what net.sctp.auth_enable sysctl says. | ||
86 | |||
87 | The fix is to check for net->sctp.auth_enable and for | ||
88 | asoc->peer.auth_capable before doing any operations like | ||
89 | sctp_sf_authenticate() as no key is activated in | ||
90 | sctp_auth_asoc_init_active_key() for each case. | ||
91 | |||
92 | Now as RFC4895 section 6.3 states that if the used HMAC-ALGO | ||
93 | passed from the INIT chunk was not used in the AUTH chunk, we | ||
94 | SHOULD send an error; however in this case it would be better | ||
95 | to just silently discard such a maliciously prepared handshake | ||
96 | as we didn't even receive a parameter at all. Also, as our | ||
97 | endpoint has no shared key configured, section 6.3 says that | ||
98 | MUST silently discard, which we are doing from now onwards. | ||
99 | |||
100 | Before calling sctp_sf_pdiscard(), we need not only to free | ||
101 | the association, but also the chunk->auth_chunk skb, as | ||
102 | commit bbd0d59809f9 created a skb clone in that case. | ||
103 | |||
104 | I have tested this locally by using netfilter's nfqueue and | ||
105 | re-injecting packets into the local stack after maliciously | ||
106 | modifying the INIT chunk (removing RANDOM; HMAC-ALGO param) | ||
107 | and the SCTP packet containing the COOKIE_ECHO (injecting | ||
108 | AUTH chunk before COOKIE_ECHO). Fixed with this patch applied. | ||
109 | |||
110 | This fixes CVE-2014-0101 | ||
111 | Upstream-Status: Backport | ||
112 | |||
113 | Fixes: bbd0d59809f9 ("[SCTP]: Implement the receive and verification of AUTH chunk") | ||
114 | Signed-off-by: Daniel Borkmann <dborkman@redhat.com> | ||
115 | Cc: Vlad Yasevich <yasevich@gmail.com> | ||
116 | Cc: Neil Horman <nhorman@tuxdriver.com> | ||
117 | Acked-by: Vlad Yasevich <vyasevich@gmail.com> | ||
118 | Signed-off-by: David S. Miller <davem@davemloft.net> | ||
119 | Signed-off-by: Jiri Slaby <jslaby@suse.cz> | ||
120 | Signed-off-by: Sona Sarmadi <sona.sarmadi@enea.com> | ||
121 | --- | ||
122 | net/sctp/sm_statefuns.c | 7 +++++++ | ||
123 | 1 file changed, 7 insertions(+) | ||
124 | |||
125 | diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c | ||
126 | index dfe3f36..56ebe71 100644 | ||
127 | --- a/net/sctp/sm_statefuns.c | ||
128 | +++ b/net/sctp/sm_statefuns.c | ||
129 | @@ -759,6 +759,13 @@ sctp_disposition_t sctp_sf_do_5_1D_ce(struct net *net, | ||
130 | struct sctp_chunk auth; | ||
131 | sctp_ierror_t ret; | ||
132 | |||
133 | + /* Make sure that we and the peer are AUTH capable */ | ||
134 | + if (!net->sctp.auth_enable || !new_asoc->peer.auth_capable) { | ||
135 | + kfree_skb(chunk->auth_chunk); | ||
136 | + sctp_association_free(new_asoc); | ||
137 | + return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands); | ||
138 | + } | ||
139 | + | ||
140 | /* set-up our fake chunk so that we can process it */ | ||
141 | auth.skb = chunk->auth_chunk; | ||
142 | auth.asoc = chunk->asoc; | ||
143 | -- | ||
144 | 1.9.1 | ||
145 | |||
diff --git a/recipes-kernel/linux/files/powerpc-Fix-64-bit-builds-with-binutils-2.24.patch b/recipes-kernel/linux/files/powerpc-Fix-64-bit-builds-with-binutils-2.24.patch new file mode 100644 index 0000000..2fdcc9f --- /dev/null +++ b/recipes-kernel/linux/files/powerpc-Fix-64-bit-builds-with-binutils-2.24.patch | |||
@@ -0,0 +1,80 @@ | |||
1 | From 7998eb3dc700aaf499f93f50b3d77da834ef9e1d Mon Sep 17 00:00:00 2001 | ||
2 | From: Guenter Roeck <linux@roeck-us.net> | ||
3 | Date: Thu, 15 May 2014 09:33:42 -0700 | ||
4 | Subject: powerpc: Fix 64 bit builds with binutils 2.24 | ||
5 | |||
6 | Upstream-Status: Backport | ||
7 | |||
8 | With binutils 2.24, various 64 bit builds fail with relocation errors | ||
9 | such as | ||
10 | |||
11 | arch/powerpc/kernel/built-in.o: In function `exc_debug_crit_book3e': | ||
12 | (.text+0x165ee): relocation truncated to fit: R_PPC64_ADDR16_HI | ||
13 | against symbol `interrupt_base_book3e' defined in .text section | ||
14 | in arch/powerpc/kernel/built-in.o | ||
15 | arch/powerpc/kernel/built-in.o: In function `exc_debug_crit_book3e': | ||
16 | (.text+0x16602): relocation truncated to fit: R_PPC64_ADDR16_HI | ||
17 | against symbol `interrupt_end_book3e' defined in .text section | ||
18 | in arch/powerpc/kernel/built-in.o | ||
19 | |||
20 | The assembler maintainer says: | ||
21 | |||
22 | I changed the ABI, something that had to be done but unfortunately | ||
23 | happens to break the booke kernel code. When building up a 64-bit | ||
24 | value with lis, ori, shl, oris, ori or similar sequences, you now | ||
25 | should use @high and @higha in place of @h and @ha. @h and @ha | ||
26 | (and their associated relocs R_PPC64_ADDR16_HI and R_PPC64_ADDR16_HA) | ||
27 | now report overflow if the value is out of 32-bit signed range. | ||
28 | ie. @h and @ha assume you're building a 32-bit value. This is needed | ||
29 | to report out-of-range -mcmodel=medium toc pointer offsets in @toc@h | ||
30 | and @toc@ha expressions, and for consistency I did the same for all | ||
31 | other @h and @ha relocs. | ||
32 | |||
33 | Replacing @h with @high in one strategic location fixes the relocation | ||
34 | errors. This has to be done conditionally since the assembler either | ||
35 | supports @h or @high but not both. | ||
36 | |||
37 | Cc: <stable@vger.kernel.org> | ||
38 | Signed-off-by: Guenter Roeck <linux@roeck-us.net> | ||
39 | Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> | ||
40 | |||
41 | diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile | ||
42 | index 4c0cedf..ce4c68a 100644 | ||
43 | --- a/arch/powerpc/Makefile | ||
44 | +++ b/arch/powerpc/Makefile | ||
45 | @@ -150,7 +150,9 @@ endif | ||
46 | |||
47 | CFLAGS-$(CONFIG_TUNE_CELL) += $(call cc-option,-mtune=cell) | ||
48 | |||
49 | -KBUILD_CPPFLAGS += -Iarch/$(ARCH) | ||
50 | +asinstr := $(call as-instr,lis 9$(comma)foo@high,-DHAVE_AS_ATHIGH=1) | ||
51 | + | ||
52 | +KBUILD_CPPFLAGS += -Iarch/$(ARCH) $(asinstr) | ||
53 | KBUILD_AFLAGS += -Iarch/$(ARCH) | ||
54 | KBUILD_CFLAGS += -msoft-float -pipe -Iarch/$(ARCH) $(CFLAGS-y) | ||
55 | CPP = $(CC) -E $(KBUILD_CFLAGS) | ||
56 | diff --git a/arch/powerpc/include/asm/ppc_asm.h b/arch/powerpc/include/asm/ppc_asm.h | ||
57 | index 6586a40..cded7c1 100644 | ||
58 | --- a/arch/powerpc/include/asm/ppc_asm.h | ||
59 | +++ b/arch/powerpc/include/asm/ppc_asm.h | ||
60 | @@ -318,11 +318,16 @@ n: | ||
61 | addi reg,reg,(name - 0b)@l; | ||
62 | |||
63 | #ifdef __powerpc64__ | ||
64 | +#ifdef HAVE_AS_ATHIGH | ||
65 | +#define __AS_ATHIGH high | ||
66 | +#else | ||
67 | +#define __AS_ATHIGH h | ||
68 | +#endif | ||
69 | #define LOAD_REG_IMMEDIATE(reg,expr) \ | ||
70 | lis reg,(expr)@highest; \ | ||
71 | ori reg,reg,(expr)@higher; \ | ||
72 | rldicr reg,reg,32,31; \ | ||
73 | - oris reg,reg,(expr)@h; \ | ||
74 | + oris reg,reg,(expr)@__AS_ATHIGH; \ | ||
75 | ori reg,reg,(expr)@l; | ||
76 | |||
77 | #define LOAD_REG_ADDR(reg,name) \ | ||
78 | -- | ||
79 | cgit v0.10.1 | ||
80 | |||
diff --git a/recipes-kernel/linux/files/sctp-CVE-2014-4667.patch b/recipes-kernel/linux/files/sctp-CVE-2014-4667.patch new file mode 100644 index 0000000..e7b1228 --- /dev/null +++ b/recipes-kernel/linux/files/sctp-CVE-2014-4667.patch | |||
@@ -0,0 +1,51 @@ | |||
1 | From ddb638e68690ca61959775b262a5ef0719c5c066 Mon Sep 17 00:00:00 2001 | ||
2 | From: Xufeng Zhang <xufeng.zhang@windriver.com> | ||
3 | Date: Thu, 12 Jun 2014 10:53:36 +0800 | ||
4 | Subject: [PATCH] sctp: Fix sk_ack_backlog wrap-around problem | ||
5 | |||
6 | [ Upstream commit d3217b15a19a4779c39b212358a5c71d725822ee ] | ||
7 | |||
8 | Consider the scenario: | ||
9 | For a TCP-style socket, while processing the COOKIE_ECHO chunk in | ||
10 | sctp_sf_do_5_1D_ce(), after it has passed a series of sanity check, | ||
11 | a new association would be created in sctp_unpack_cookie(), but afterwards, | ||
12 | some processing maybe failed, and sctp_association_free() will be called to | ||
13 | free the previously allocated association, in sctp_association_free(), | ||
14 | sk_ack_backlog value is decremented for this socket, since the initial | ||
15 | value for sk_ack_backlog is 0, after the decrement, it will be 65535, | ||
16 | a wrap-around problem happens, and if we want to establish new associations | ||
17 | afterward in the same socket, ABORT would be triggered since sctp deem the | ||
18 | accept queue as full. | ||
19 | Fix this issue by only decrementing sk_ack_backlog for associations in | ||
20 | the endpoint's list. | ||
21 | |||
22 | Fixes CVE-2014-4667 | ||
23 | Upstream-Status: Backport | ||
24 | |||
25 | Fix-suggested-by: Neil Horman <nhorman@tuxdriver.com> | ||
26 | Signed-off-by: Xufeng Zhang <xufeng.zhang@windriver.com> | ||
27 | Acked-by: Daniel Borkmann <dborkman@redhat.com> | ||
28 | Acked-by: Vlad Yasevich <vyasevich@gmail.com> | ||
29 | Signed-off-by: David S. Miller <davem@davemloft.net> | ||
30 | Signed-off-by: Jiri Slaby <jslaby@suse.cz> | ||
31 | Signed-off-by: Sona Sarmadi <sona.sarmadi@enea.com> | ||
32 | --- | ||
33 | net/sctp/associola.c | 2 +- | ||
34 | 1 file changed, 1 insertion(+), 1 deletion(-) | ||
35 | |||
36 | diff --git a/net/sctp/associola.c b/net/sctp/associola.c | ||
37 | index cef5099..f6d6dcd 100644 | ||
38 | --- a/net/sctp/associola.c | ||
39 | +++ b/net/sctp/associola.c | ||
40 | @@ -375,7 +375,7 @@ void sctp_association_free(struct sctp_association *asoc) | ||
41 | /* Only real associations count against the endpoint, so | ||
42 | * don't bother for if this is a temporary association. | ||
43 | */ | ||
44 | - if (!asoc->temp) { | ||
45 | + if (!list_empty(&asoc->asocs)) { | ||
46 | list_del(&asoc->asocs); | ||
47 | |||
48 | /* Decrement the backlog value for a TCP-style listening | ||
49 | -- | ||
50 | 1.9.1 | ||
51 | |||
diff --git a/recipes-kernel/linux/files/sctp-CVE-2014-7841.patch b/recipes-kernel/linux/files/sctp-CVE-2014-7841.patch new file mode 100644 index 0000000..0c4beb3 --- /dev/null +++ b/recipes-kernel/linux/files/sctp-CVE-2014-7841.patch | |||
@@ -0,0 +1,85 @@ | |||
1 | From 4008f1dbe6fea8114e7f79ed2d238e369dc9138f Mon Sep 17 00:00:00 2001 | ||
2 | From: Daniel Borkmann <dborkman@redhat.com> | ||
3 | Date: Mon, 10 Nov 2014 17:54:26 +0100 | ||
4 | Subject: [PATCH] net: sctp: fix NULL pointer dereference in | ||
5 | af->from_addr_param on malformed packet | ||
6 | |||
7 | [ Upstream commit e40607cbe270a9e8360907cb1e62ddf0736e4864 ] | ||
8 | |||
9 | An SCTP server doing ASCONF will panic on malformed INIT ping-of-death | ||
10 | in the form of: | ||
11 | |||
12 | ------------ INIT[PARAM: SET_PRIMARY_IP] ------------> | ||
13 | |||
14 | While the INIT chunk parameter verification dissects through many things | ||
15 | in order to detect malformed input, it misses to actually check parameters | ||
16 | inside of parameters. E.g. RFC5061, section 4.2.4 proposes a 'set primary | ||
17 | IP address' parameter in ASCONF, which has as a subparameter an address | ||
18 | parameter. | ||
19 | |||
20 | So an attacker may send a parameter type other than SCTP_PARAM_IPV4_ADDRESS | ||
21 | or SCTP_PARAM_IPV6_ADDRESS, param_type2af() will subsequently return 0 | ||
22 | and thus sctp_get_af_specific() returns NULL, too, which we then happily | ||
23 | dereference unconditionally through af->from_addr_param(). | ||
24 | |||
25 | The trace for the log: | ||
26 | |||
27 | BUG: unable to handle kernel NULL pointer dereference at 0000000000000078 | ||
28 | IP: [<ffffffffa01e9c62>] sctp_process_init+0x492/0x990 [sctp] | ||
29 | PGD 0 | ||
30 | Oops: 0000 [#1] SMP | ||
31 | [...] | ||
32 | Pid: 0, comm: swapper Not tainted 2.6.32-504.el6.x86_64 #1 Bochs Bochs | ||
33 | RIP: 0010:[<ffffffffa01e9c62>] [<ffffffffa01e9c62>] sctp_process_init+0x492/0x990 [sctp] | ||
34 | [...] | ||
35 | Call Trace: | ||
36 | <IRQ> | ||
37 | [<ffffffffa01f2add>] ? sctp_bind_addr_copy+0x5d/0xe0 [sctp] | ||
38 | [<ffffffffa01e1fcb>] sctp_sf_do_5_1B_init+0x21b/0x340 [sctp] | ||
39 | [<ffffffffa01e3751>] sctp_do_sm+0x71/0x1210 [sctp] | ||
40 | [<ffffffffa01e5c09>] ? sctp_endpoint_lookup_assoc+0xc9/0xf0 [sctp] | ||
41 | [<ffffffffa01e61f6>] sctp_endpoint_bh_rcv+0x116/0x230 [sctp] | ||
42 | [<ffffffffa01ee986>] sctp_inq_push+0x56/0x80 [sctp] | ||
43 | [<ffffffffa01fcc42>] sctp_rcv+0x982/0xa10 [sctp] | ||
44 | [<ffffffffa01d5123>] ? ipt_local_in_hook+0x23/0x28 [iptable_filter] | ||
45 | [<ffffffff8148bdc9>] ? nf_iterate+0x69/0xb0 | ||
46 | [<ffffffff81496d10>] ? ip_local_deliver_finish+0x0/0x2d0 | ||
47 | [<ffffffff8148bf86>] ? nf_hook_slow+0x76/0x120 | ||
48 | [<ffffffff81496d10>] ? ip_local_deliver_finish+0x0/0x2d0 | ||
49 | [...] | ||
50 | |||
51 | A minimal way to address this is to check for NULL as we do on all | ||
52 | other such occasions where we know sctp_get_af_specific() could | ||
53 | possibly return with NULL. | ||
54 | |||
55 | Fix for CVE-2014-7841 | ||
56 | Upstream-Status: Backport | ||
57 | |||
58 | Fixes: d6de3097592b ("[SCTP]: Add the handling of "Set Primary IP Address" parameter to INIT") | ||
59 | Signed-off-by: Daniel Borkmann <dborkman@redhat.com> | ||
60 | Cc: Vlad Yasevich <vyasevich@gmail.com> | ||
61 | Acked-by: Neil Horman <nhorman@tuxdriver.com> | ||
62 | Signed-off-by: David S. Miller <davem@davemloft.net> | ||
63 | Signed-off-by: Jiri Slaby <jslaby@suse.cz> | ||
64 | Signed-off-by: Sona Sarmadi <sona.sarmadi@enea.com> | ||
65 | --- | ||
66 | net/sctp/sm_make_chunk.c | 3 +++ | ||
67 | 1 file changed, 3 insertions(+) | ||
68 | |||
69 | diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c | ||
70 | index 1e06f3b..e342387 100644 | ||
71 | --- a/net/sctp/sm_make_chunk.c | ||
72 | +++ b/net/sctp/sm_make_chunk.c | ||
73 | @@ -2622,6 +2622,9 @@ do_addr_param: | ||
74 | addr_param = param.v + sizeof(sctp_addip_param_t); | ||
75 | |||
76 | af = sctp_get_af_specific(param_type2af(param.p->type)); | ||
77 | + if (af == NULL) | ||
78 | + break; | ||
79 | + | ||
80 | af->from_addr_param(&addr, addr_param, | ||
81 | htons(asoc->peer.port), 0); | ||
82 | |||
83 | -- | ||
84 | 1.9.1 | ||
85 | |||
diff --git a/recipes-kernel/linux/files/udf-CVE-2014-6410.patch b/recipes-kernel/linux/files/udf-CVE-2014-6410.patch new file mode 100644 index 0000000..9086e0a --- /dev/null +++ b/recipes-kernel/linux/files/udf-CVE-2014-6410.patch | |||
@@ -0,0 +1,96 @@ | |||
1 | From 07d209bd092d023976fdb881ba6d4b30fe18aebe Mon Sep 17 00:00:00 2001 | ||
2 | From: Jan Kara <jack@suse.cz> | ||
3 | Date: Thu, 4 Sep 2014 14:06:55 +0200 | ||
4 | Subject: [PATCH] udf: Avoid infinite loop when processing indirect ICBs | ||
5 | |||
6 | commit c03aa9f6e1f938618e6db2e23afef0574efeeb65 upstream. | ||
7 | |||
8 | We did not implement any bound on number of indirect ICBs we follow when | ||
9 | loading inode. Thus corrupted medium could cause kernel to go into an | ||
10 | infinite loop, possibly causing a stack overflow. | ||
11 | |||
12 | Fix the possible stack overflow by removing recursion from | ||
13 | __udf_read_inode() and limit number of indirect ICBs we follow to avoid | ||
14 | infinite loops. | ||
15 | |||
16 | Upstream-Status: Backport | ||
17 | |||
18 | Signed-off-by: Jan Kara <jack@suse.cz> | ||
19 | Cc: Chuck Ebbert <cebbert.lkml@gmail.com> | ||
20 | Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | ||
21 | Signed-off-by: Sona Sarmadi <sona.sarmadi@enea.com> | ||
22 | --- | ||
23 | fs/udf/inode.c | 35 +++++++++++++++++++++-------------- | ||
24 | 1 file changed, 21 insertions(+), 14 deletions(-) | ||
25 | |||
26 | diff --git a/fs/udf/inode.c b/fs/udf/inode.c | ||
27 | index b6d15d3..aa02328 100644 | ||
28 | --- a/fs/udf/inode.c | ||
29 | +++ b/fs/udf/inode.c | ||
30 | @@ -1270,13 +1270,22 @@ update_time: | ||
31 | return 0; | ||
32 | } | ||
33 | |||
34 | +/* | ||
35 | + * Maximum length of linked list formed by ICB hierarchy. The chosen number is | ||
36 | + * arbitrary - just that we hopefully don't limit any real use of rewritten | ||
37 | + * inode on write-once media but avoid looping for too long on corrupted media. | ||
38 | + */ | ||
39 | +#define UDF_MAX_ICB_NESTING 1024 | ||
40 | + | ||
41 | static void __udf_read_inode(struct inode *inode) | ||
42 | { | ||
43 | struct buffer_head *bh = NULL; | ||
44 | struct fileEntry *fe; | ||
45 | uint16_t ident; | ||
46 | struct udf_inode_info *iinfo = UDF_I(inode); | ||
47 | + unsigned int indirections = 0; | ||
48 | |||
49 | +reread: | ||
50 | /* | ||
51 | * Set defaults, but the inode is still incomplete! | ||
52 | * Note: get_new_inode() sets the following on a new inode: | ||
53 | @@ -1313,28 +1322,26 @@ static void __udf_read_inode(struct inode *inode) | ||
54 | ibh = udf_read_ptagged(inode->i_sb, &iinfo->i_location, 1, | ||
55 | &ident); | ||
56 | if (ident == TAG_IDENT_IE && ibh) { | ||
57 | - struct buffer_head *nbh = NULL; | ||
58 | struct kernel_lb_addr loc; | ||
59 | struct indirectEntry *ie; | ||
60 | |||
61 | ie = (struct indirectEntry *)ibh->b_data; | ||
62 | loc = lelb_to_cpu(ie->indirectICB.extLocation); | ||
63 | |||
64 | - if (ie->indirectICB.extLength && | ||
65 | - (nbh = udf_read_ptagged(inode->i_sb, &loc, 0, | ||
66 | - &ident))) { | ||
67 | - if (ident == TAG_IDENT_FE || | ||
68 | - ident == TAG_IDENT_EFE) { | ||
69 | - memcpy(&iinfo->i_location, | ||
70 | - &loc, | ||
71 | - sizeof(struct kernel_lb_addr)); | ||
72 | - brelse(bh); | ||
73 | - brelse(ibh); | ||
74 | - brelse(nbh); | ||
75 | - __udf_read_inode(inode); | ||
76 | + if (ie->indirectICB.extLength) { | ||
77 | + brelse(bh); | ||
78 | + brelse(ibh); | ||
79 | + memcpy(&iinfo->i_location, &loc, | ||
80 | + sizeof(struct kernel_lb_addr)); | ||
81 | + if (++indirections > UDF_MAX_ICB_NESTING) { | ||
82 | + udf_err(inode->i_sb, | ||
83 | + "too many ICBs in ICB hierarchy" | ||
84 | + " (max %d supported)\n", | ||
85 | + UDF_MAX_ICB_NESTING); | ||
86 | + make_bad_inode(inode); | ||
87 | return; | ||
88 | } | ||
89 | - brelse(nbh); | ||
90 | + goto reread; | ||
91 | } | ||
92 | } | ||
93 | brelse(ibh); | ||
94 | -- | ||
95 | 1.9.1 | ||
96 | |||
diff --git a/recipes-kernel/linux/linux-qoriq-prt_3.12.bb b/recipes-kernel/linux/linux-qoriq-prt_3.12.bb new file mode 100644 index 0000000..1716651 --- /dev/null +++ b/recipes-kernel/linux/linux-qoriq-prt_3.12.bb | |||
@@ -0,0 +1,8 @@ | |||
1 | require recipes-kernel/linux/linux-qoriq.inc | ||
2 | |||
3 | SRC_URI = "git://git.freescale.com/ppc/sdk/linux.git;nobranch=1 \ | ||
4 | file://powerpc-Fix-64-bit-builds-with-binutils-2.24.patch \ | ||
5 | file://Fix-CVE-2014-5077-sctp-inherit-auth-capable-on-INIT-collisions.patch \ | ||
6 | " | ||
7 | SRCREV = "c29fe1a733308cbe592b3af054a97be1b91cf2dd" | ||
8 | |||
diff --git a/recipes-kernel/linux/linux-qoriq.inc b/recipes-kernel/linux/linux-qoriq.inc new file mode 100644 index 0000000..3534445 --- /dev/null +++ b/recipes-kernel/linux/linux-qoriq.inc | |||
@@ -0,0 +1,46 @@ | |||
1 | inherit kernel qoriq_build_64bit_kernel | ||
2 | require recipes-kernel/linux/linux-dtb.inc | ||
3 | |||
4 | DESCRIPTION = "Linux kernel for Freescale platforms" | ||
5 | SECTION = "kernel" | ||
6 | LICENSE = "GPLv2" | ||
7 | LIC_FILES_CHKSUM = "file://COPYING;md5=d7810fab7487fb0aad327b76f1be7cd7" | ||
8 | |||
9 | KSRC ?= "" | ||
10 | S = '${@base_conditional("KSRC", "", "${WORKDIR}/git", "${KSRC}", d)}' | ||
11 | |||
12 | DEPENDS_append = " libgcc" | ||
13 | KERNEL_CC_append = " ${TOOLCHAIN_OPTIONS}" | ||
14 | KERNEL_LD_append = " ${TOOLCHAIN_OPTIONS}" | ||
15 | |||
16 | SCMVERSION ?= "y" | ||
17 | DELTA_KERNEL_DEFCONFIG ?= "" | ||
18 | do_configure_prepend() { | ||
19 | # copy desired defconfig so we pick it up for the real kernel_do_configure | ||
20 | cp ${KERNEL_DEFCONFIG} ${B}/.config | ||
21 | |||
22 | # add config fragments | ||
23 | for deltacfg in ${DELTA_KERNEL_DEFCONFIG}; do | ||
24 | if [ -f "${WORKDIR}/${deltacfg}" ]; then | ||
25 | ${S}/scripts/kconfig/merge_config.sh -m .config ${WORKDIR}/${deltacfg} | ||
26 | elif [ -f "${S}/arch/powerpc/configs/${deltacfg}" ]; then | ||
27 | ${S}/scripts/kconfig/merge_config.sh -m .config \ | ||
28 | ${S}/arch/powerpc/configs/${deltacfg} | ||
29 | fi | ||
30 | done | ||
31 | |||
32 | #add git revision to the local version | ||
33 | if [ "${SCMVERSION}" = "y" ]; then | ||
34 | # append sdk version if SDK_VERSION is defined | ||
35 | sdkversion='' | ||
36 | if [ -n "${SDK_VERSION}" ]; then | ||
37 | sdkversion="-${SDK_VERSION}" | ||
38 | fi | ||
39 | head=`git --git-dir=${S}/.git rev-parse --verify --short HEAD 2> /dev/null` | ||
40 | printf "%s%s%s" $sdkversion +g $head > ${B}/.scmversion | ||
41 | fi | ||
42 | } | ||
43 | |||
44 | # make everything compatible for the time being | ||
45 | COMPATIBLE_MACHINE_$MACHINE = "$MACHINE" | ||
46 | |||
diff --git a/recipes-kernel/linux/linux-qoriq_3.12.bb b/recipes-kernel/linux/linux-qoriq_3.12.bb new file mode 100644 index 0000000..5c67dc3 --- /dev/null +++ b/recipes-kernel/linux/linux-qoriq_3.12.bb | |||
@@ -0,0 +1,32 @@ | |||
1 | require recipes-kernel/linux/linux-qoriq.inc | ||
2 | |||
3 | SRC_URI = "git://git.freescale.com/ppc/sdk/linux.git;nobranch=1 \ | ||
4 | file://powerpc-Fix-64-bit-builds-with-binutils-2.24.patch \ | ||
5 | file://Fix-for-CVE-2014-5045-fs-umount-on-symlink-leak.patch \ | ||
6 | file://Fix-CVE-2014-5077-sctp-inherit-auth-capable-on-INIT-collisions.patch \ | ||
7 | file://Fix-CVE-2014-5471_CVE-2014-5472.patch \ | ||
8 | file://modify-defconfig-t1040-nr-cpus.patch \ | ||
9 | file://0001-mnt-CVE-2014-5206_CVE-2014-5207.patch \ | ||
10 | file://0002-mnt-CVE-2014-5206_CVE-2014-5207.patch \ | ||
11 | file://0003-mnt-CVE-2014-5206_CVE-2014-5207.patch \ | ||
12 | file://0004-mnt-CVE-2014-5206_CVE-2014-5207.patch \ | ||
13 | file://0005-mnt-CVE-2014-5206_CVE-2014-5207.patch \ | ||
14 | file://udf-CVE-2014-6410.patch \ | ||
15 | file://net-sctp-CVE-2014-0101.patch \ | ||
16 | file://0001-HID-CVE-2014-3181.patch \ | ||
17 | file://0002-HID-CVE-2014-3182.patch \ | ||
18 | file://0003-HID-CVE-2014-3184.patch \ | ||
19 | file://0004-USB-CVE-2014-3185.patch \ | ||
20 | file://0001-kvm-iommu-CVE-2014-3601.patch \ | ||
21 | file://0002-kvm-iommu-CVE-2014-8369.patch \ | ||
22 | file://0001-net-sctp-CVE-2014-3673.patch \ | ||
23 | file://0002-net-sctp-CVE-2014-3687.patch \ | ||
24 | file://0003-net-sctp-CVE-2014-3688.patch \ | ||
25 | file://auditsc-CVE-2014-3917.patch \ | ||
26 | file://0001-ALSA-CVE-2014-4652.patch \ | ||
27 | file://0002-ALSA-CVE-2014-4653.patch \ | ||
28 | file://sctp-CVE-2014-4667.patch \ | ||
29 | file://sctp-CVE-2014-7841.patch \ | ||
30 | " | ||
31 | SRCREV = "6619b8b55796cdf0cec04b66a71288edd3057229" | ||
32 | |||
diff --git a/recipes-kernel/lttng/lttng-modules_%.bbappend b/recipes-kernel/lttng/lttng-modules_%.bbappend new file mode 100644 index 0000000..5ff765d --- /dev/null +++ b/recipes-kernel/lttng/lttng-modules_%.bbappend | |||
@@ -0,0 +1,2 @@ | |||
1 | inherit qoriq_build_64bit_kernel | ||
2 | |||
diff --git a/recipes-kernel/pkc-host/pkc-host_git.bb b/recipes-kernel/pkc-host/pkc-host_git.bb new file mode 100644 index 0000000..2d5e316 --- /dev/null +++ b/recipes-kernel/pkc-host/pkc-host_git.bb | |||
@@ -0,0 +1,33 @@ | |||
1 | DESCRIPTION = "pkc host driver" | ||
2 | SECTION = "pkc-host" | ||
3 | LICENSE = "GPLv2" | ||
4 | LIC_FILES_CHKSUM = "file://Makefile;endline=30;md5=6a26ed8e76a8ea2e019c525369ed0f03" | ||
5 | |||
6 | inherit module qoriq_build_64bit_kernel | ||
7 | RDEPENDS_${PN} += "cryptodev-module" | ||
8 | |||
9 | # Currently pkc-host does not support RSA_KEYGEN, remove this | ||
10 | # if it is fixed. | ||
11 | REQUIRED_DISTRO_FEATURES = "c29x_pkc" | ||
12 | |||
13 | SRC_URI = "git://git.freescale.com/ppc/sdk/pkc-host.git;nobranch=1" | ||
14 | SRCREV = "cae512c94e2a26cc6b0d6393d307cdea2d7282c9" | ||
15 | |||
16 | S = "${WORKDIR}/git" | ||
17 | |||
18 | EXTRA_OEMAKE='KERNEL_DIR="${STAGING_KERNEL_DIR}" PREFIX="${D}"' | ||
19 | |||
20 | do_install() { | ||
21 | install -d ${D}/lib/modules/c2x0 | ||
22 | install -d ${D}/etc/crypto | ||
23 | install -d ${D}/${bindir} | ||
24 | cp ${S}/*.ko ${D}/lib/modules/c2x0 | ||
25 | cp ${S}/crypto.cfg ${D}/etc/crypto | ||
26 | cp ${S}/images/pkc-firmware.bin ${D}/etc/crypto | ||
27 | cp ${S}/perf/mini_calc/mini_calc ${D}/${bindir} | ||
28 | cp ${S}/apps/cli/cli ${D}/${bindir} | ||
29 | cp ${S}/perf/c29x_driver_perf_profile.sh ${D}/${bindir} | ||
30 | } | ||
31 | |||
32 | |||
33 | FILES_${PN} += "${bindir}/mini_calc ${bindir}/cli ${bindir}/c29x_driver_perf_profile.sh /etc/crypto/crypto.cfg /etc/crypto/pkc-firmware.bin" | ||
diff --git a/recipes-kernel/qoriq-debug/qoriq-debug_git.bb b/recipes-kernel/qoriq-debug/qoriq-debug_git.bb new file mode 100644 index 0000000..c08f057 --- /dev/null +++ b/recipes-kernel/qoriq-debug/qoriq-debug_git.bb | |||
@@ -0,0 +1,15 @@ | |||
1 | DESCRIPTION = "QorIQ Debug File System Module" | ||
2 | SECTION = "qoriq-debug" | ||
3 | LICENSE = "GPLv2+" | ||
4 | LIC_FILES_CHKSUM = "file://COPYING;md5=e29234dd5d40dc352cc60cc0c93437ba" | ||
5 | |||
6 | inherit module autotools-brokensep qoriq_build_64bit_kernel | ||
7 | |||
8 | SRC_URI = "git://git.freescale.com/ppc/sdk/qoriq-debug.git;nobranch=1" | ||
9 | SRCREV = "20615c1ea332102635f8314cee5787c48c1a4254" | ||
10 | |||
11 | S = "${WORKDIR}/git" | ||
12 | |||
13 | EXTRA_OECONF += "--with-linux=${STAGING_KERNEL_DIR}" | ||
14 | EXTRA_OEMAKE += 'SYSROOT="${D}"' | ||
15 | |||
diff --git a/recipes-kernel/skmm-host/skmm-host_git.bb b/recipes-kernel/skmm-host/skmm-host_git.bb new file mode 100644 index 0000000..a1c43f3 --- /dev/null +++ b/recipes-kernel/skmm-host/skmm-host_git.bb | |||
@@ -0,0 +1,15 @@ | |||
1 | DESCRIPTION = "skmm host driver offload data to PCIe EP and push the data en-decrypted back to application" | ||
2 | SECTION = "c293-skmm-host" | ||
3 | LICENSE = "Freescale-EULA" | ||
4 | LIC_FILES_CHKSUM = "file://Makefile;endline=7;md5=edffaac1da9e809ade0d2fcfcc18d8df" | ||
5 | |||
6 | inherit module qoriq_build_64bit_kernel | ||
7 | |||
8 | SRC_URI = "git://git.freescale.com/ppc/sdk/skmm-host.git;nobranch=1" | ||
9 | SRCREV = "97c9241a359edccdf8913cb9accbfe4ceb511523" | ||
10 | |||
11 | S = "${WORKDIR}/git" | ||
12 | |||
13 | EXTRA_OEMAKE='KERNEL_DIR="${STAGING_KERNEL_DIR}" PREFIX="${D}"' | ||
14 | |||
15 | FILES_${PN} += "/etc/skmm/" | ||
diff --git a/recipes-kernel/uio-seville/uio-seville_0.1.bb b/recipes-kernel/uio-seville/uio-seville_0.1.bb new file mode 100755 index 0000000..51e1475 --- /dev/null +++ b/recipes-kernel/uio-seville/uio-seville_0.1.bb | |||
@@ -0,0 +1,15 @@ | |||
1 | DESCRIPTION = "UIO driver for T1040 L2 Switch" | ||
2 | LICENSE = "GPLv2" | ||
3 | LIC_FILES_CHKSUM = "file://COPYING;md5=12f884d2ae1ff87c09e5b7ccc2c4ca7e" | ||
4 | |||
5 | SRC_URI = "git://git.freescale.com/ppc/sdk/l2switch-uio.git;branch=sdk-v1.7.x" | ||
6 | SRCREV = "35af73f3ba00745777f32787400d9eb0317d7ff5" | ||
7 | |||
8 | inherit module | ||
9 | |||
10 | S = "${WORKDIR}/git/uio-driver" | ||
11 | |||
12 | COMPATIBLE_MACHINE ?= "(none)" | ||
13 | COMPATIBLE_MACHINE_t1040 = ".*" | ||
14 | COMPATIBLE_MACHINE_t1042 = ".*" | ||
15 | |||