summaryrefslogtreecommitdiffstats
path: root/crypto
diff options
context:
space:
mode:
authorKees Cook <keescook@chromium.org>2018-04-26 22:57:28 -0400
committerHerbert Xu <herbert@gondor.apana.org.au>2018-05-05 02:52:53 -0400
commit4e234eed58518a8df69a5d14d303b18ed9559832 (patch)
tree3e1de3cf13e7f764b249f1a37a5a30b29550b3c3 /crypto
parente99ce921c468ab5d2ccbe17c545061916f3ca82a (diff)
crypto: tcrypt - Remove VLA usage
In the quest to remove all stack VLA usage from the kernel[1], this allocates the return code buffers before starting jiffie timers, rather than using stack space for the array. Additionally cleans up some exit paths and make sure that the num_mb module_param() is used only once per execution to avoid possible races in the value changing. [1] https://lkml.kernel.org/r/CA+55aFzCG-zNmZwX4A2FQpadafLfEzK6CC=qPXydAacU1RqZWA@mail.gmail.com Signed-off-by: Kees Cook <keescook@chromium.org> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'crypto')
-rw-r--r--crypto/tcrypt.c118
1 files changed, 79 insertions, 39 deletions
diff --git a/crypto/tcrypt.c b/crypto/tcrypt.c
index 51fe7c8744ae..e721faab6fc8 100644
--- a/crypto/tcrypt.c
+++ b/crypto/tcrypt.c
@@ -158,9 +158,9 @@ struct test_mb_aead_data {
158}; 158};
159 159
160static int do_mult_aead_op(struct test_mb_aead_data *data, int enc, 160static int do_mult_aead_op(struct test_mb_aead_data *data, int enc,
161 u32 num_mb) 161 u32 num_mb, int *rc)
162{ 162{
163 int i, rc[num_mb], err = 0; 163 int i, err = 0;
164 164
165 /* Fire up a bunch of concurrent requests */ 165 /* Fire up a bunch of concurrent requests */
166 for (i = 0; i < num_mb; i++) { 166 for (i = 0; i < num_mb; i++) {
@@ -188,18 +188,26 @@ static int test_mb_aead_jiffies(struct test_mb_aead_data *data, int enc,
188{ 188{
189 unsigned long start, end; 189 unsigned long start, end;
190 int bcount; 190 int bcount;
191 int ret; 191 int ret = 0;
192 int *rc;
193
194 rc = kcalloc(num_mb, sizeof(*rc), GFP_KERNEL);
195 if (!rc)
196 return -ENOMEM;
192 197
193 for (start = jiffies, end = start + secs * HZ, bcount = 0; 198 for (start = jiffies, end = start + secs * HZ, bcount = 0;
194 time_before(jiffies, end); bcount++) { 199 time_before(jiffies, end); bcount++) {
195 ret = do_mult_aead_op(data, enc, num_mb); 200 ret = do_mult_aead_op(data, enc, num_mb, rc);
196 if (ret) 201 if (ret)
197 return ret; 202 goto out;
198 } 203 }
199 204
200 pr_cont("%d operations in %d seconds (%ld bytes)\n", 205 pr_cont("%d operations in %d seconds (%ld bytes)\n",
201 bcount * num_mb, secs, (long)bcount * blen * num_mb); 206 bcount * num_mb, secs, (long)bcount * blen * num_mb);
202 return 0; 207
208out:
209 kfree(rc);
210 return ret;
203} 211}
204 212
205static int test_mb_aead_cycles(struct test_mb_aead_data *data, int enc, 213static int test_mb_aead_cycles(struct test_mb_aead_data *data, int enc,
@@ -208,10 +216,15 @@ static int test_mb_aead_cycles(struct test_mb_aead_data *data, int enc,
208 unsigned long cycles = 0; 216 unsigned long cycles = 0;
209 int ret = 0; 217 int ret = 0;
210 int i; 218 int i;
219 int *rc;
220
221 rc = kcalloc(num_mb, sizeof(*rc), GFP_KERNEL);
222 if (!rc)
223 return -ENOMEM;
211 224
212 /* Warm-up run. */ 225 /* Warm-up run. */
213 for (i = 0; i < 4; i++) { 226 for (i = 0; i < 4; i++) {
214 ret = do_mult_aead_op(data, enc, num_mb); 227 ret = do_mult_aead_op(data, enc, num_mb, rc);
215 if (ret) 228 if (ret)
216 goto out; 229 goto out;
217 } 230 }
@@ -221,7 +234,7 @@ static int test_mb_aead_cycles(struct test_mb_aead_data *data, int enc,
221 cycles_t start, end; 234 cycles_t start, end;
222 235
223 start = get_cycles(); 236 start = get_cycles();
224 ret = do_mult_aead_op(data, enc, num_mb); 237 ret = do_mult_aead_op(data, enc, num_mb, rc);
225 end = get_cycles(); 238 end = get_cycles();
226 239
227 if (ret) 240 if (ret)
@@ -230,11 +243,11 @@ static int test_mb_aead_cycles(struct test_mb_aead_data *data, int enc,
230 cycles += end - start; 243 cycles += end - start;
231 } 244 }
232 245
233out: 246 pr_cont("1 operation in %lu cycles (%d bytes)\n",
234 if (ret == 0) 247 (cycles + 4) / (8 * num_mb), blen);
235 pr_cont("1 operation in %lu cycles (%d bytes)\n",
236 (cycles + 4) / (8 * num_mb), blen);
237 248
249out:
250 kfree(rc);
238 return ret; 251 return ret;
239} 252}
240 253
@@ -705,9 +718,10 @@ struct test_mb_ahash_data {
705 char *xbuf[XBUFSIZE]; 718 char *xbuf[XBUFSIZE];
706}; 719};
707 720
708static inline int do_mult_ahash_op(struct test_mb_ahash_data *data, u32 num_mb) 721static inline int do_mult_ahash_op(struct test_mb_ahash_data *data, u32 num_mb,
722 int *rc)
709{ 723{
710 int i, rc[num_mb], err = 0; 724 int i, err = 0;
711 725
712 /* Fire up a bunch of concurrent requests */ 726 /* Fire up a bunch of concurrent requests */
713 for (i = 0; i < num_mb; i++) 727 for (i = 0; i < num_mb; i++)
@@ -731,18 +745,26 @@ static int test_mb_ahash_jiffies(struct test_mb_ahash_data *data, int blen,
731{ 745{
732 unsigned long start, end; 746 unsigned long start, end;
733 int bcount; 747 int bcount;
734 int ret; 748 int ret = 0;
749 int *rc;
750
751 rc = kcalloc(num_mb, sizeof(*rc), GFP_KERNEL);
752 if (!rc)
753 return -ENOMEM;
735 754
736 for (start = jiffies, end = start + secs * HZ, bcount = 0; 755 for (start = jiffies, end = start + secs * HZ, bcount = 0;
737 time_before(jiffies, end); bcount++) { 756 time_before(jiffies, end); bcount++) {
738 ret = do_mult_ahash_op(data, num_mb); 757 ret = do_mult_ahash_op(data, num_mb, rc);
739 if (ret) 758 if (ret)
740 return ret; 759 goto out;
741 } 760 }
742 761
743 pr_cont("%d operations in %d seconds (%ld bytes)\n", 762 pr_cont("%d operations in %d seconds (%ld bytes)\n",
744 bcount * num_mb, secs, (long)bcount * blen * num_mb); 763 bcount * num_mb, secs, (long)bcount * blen * num_mb);
745 return 0; 764
765out:
766 kfree(rc);
767 return ret;
746} 768}
747 769
748static int test_mb_ahash_cycles(struct test_mb_ahash_data *data, int blen, 770static int test_mb_ahash_cycles(struct test_mb_ahash_data *data, int blen,
@@ -751,10 +773,15 @@ static int test_mb_ahash_cycles(struct test_mb_ahash_data *data, int blen,
751 unsigned long cycles = 0; 773 unsigned long cycles = 0;
752 int ret = 0; 774 int ret = 0;
753 int i; 775 int i;
776 int *rc;
777
778 rc = kcalloc(num_mb, sizeof(*rc), GFP_KERNEL);
779 if (!rc)
780 return -ENOMEM;
754 781
755 /* Warm-up run. */ 782 /* Warm-up run. */
756 for (i = 0; i < 4; i++) { 783 for (i = 0; i < 4; i++) {
757 ret = do_mult_ahash_op(data, num_mb); 784 ret = do_mult_ahash_op(data, num_mb, rc);
758 if (ret) 785 if (ret)
759 goto out; 786 goto out;
760 } 787 }
@@ -764,7 +791,7 @@ static int test_mb_ahash_cycles(struct test_mb_ahash_data *data, int blen,
764 cycles_t start, end; 791 cycles_t start, end;
765 792
766 start = get_cycles(); 793 start = get_cycles();
767 ret = do_mult_ahash_op(data, num_mb); 794 ret = do_mult_ahash_op(data, num_mb, rc);
768 end = get_cycles(); 795 end = get_cycles();
769 796
770 if (ret) 797 if (ret)
@@ -773,11 +800,11 @@ static int test_mb_ahash_cycles(struct test_mb_ahash_data *data, int blen,
773 cycles += end - start; 800 cycles += end - start;
774 } 801 }
775 802
776out: 803 pr_cont("1 operation in %lu cycles (%d bytes)\n",
777 if (ret == 0) 804 (cycles + 4) / (8 * num_mb), blen);
778 pr_cont("1 operation in %lu cycles (%d bytes)\n",
779 (cycles + 4) / (8 * num_mb), blen);
780 805
806out:
807 kfree(rc);
781 return ret; 808 return ret;
782} 809}
783 810
@@ -1118,9 +1145,9 @@ struct test_mb_skcipher_data {
1118}; 1145};
1119 1146
1120static int do_mult_acipher_op(struct test_mb_skcipher_data *data, int enc, 1147static int do_mult_acipher_op(struct test_mb_skcipher_data *data, int enc,
1121 u32 num_mb) 1148 u32 num_mb, int *rc)
1122{ 1149{
1123 int i, rc[num_mb], err = 0; 1150 int i, err = 0;
1124 1151
1125 /* Fire up a bunch of concurrent requests */ 1152 /* Fire up a bunch of concurrent requests */
1126 for (i = 0; i < num_mb; i++) { 1153 for (i = 0; i < num_mb; i++) {
@@ -1148,18 +1175,26 @@ static int test_mb_acipher_jiffies(struct test_mb_skcipher_data *data, int enc,
1148{ 1175{
1149 unsigned long start, end; 1176 unsigned long start, end;
1150 int bcount; 1177 int bcount;
1151 int ret; 1178 int ret = 0;
1179 int *rc;
1180
1181 rc = kcalloc(num_mb, sizeof(*rc), GFP_KERNEL);
1182 if (!rc)
1183 return -ENOMEM;
1152 1184
1153 for (start = jiffies, end = start + secs * HZ, bcount = 0; 1185 for (start = jiffies, end = start + secs * HZ, bcount = 0;
1154 time_before(jiffies, end); bcount++) { 1186 time_before(jiffies, end); bcount++) {
1155 ret = do_mult_acipher_op(data, enc, num_mb); 1187 ret = do_mult_acipher_op(data, enc, num_mb, rc);
1156 if (ret) 1188 if (ret)
1157 return ret; 1189 goto out;
1158 } 1190 }
1159 1191
1160 pr_cont("%d operations in %d seconds (%ld bytes)\n", 1192 pr_cont("%d operations in %d seconds (%ld bytes)\n",
1161 bcount * num_mb, secs, (long)bcount * blen * num_mb); 1193 bcount * num_mb, secs, (long)bcount * blen * num_mb);
1162 return 0; 1194
1195out:
1196 kfree(rc);
1197 return ret;
1163} 1198}
1164 1199
1165static int test_mb_acipher_cycles(struct test_mb_skcipher_data *data, int enc, 1200static int test_mb_acipher_cycles(struct test_mb_skcipher_data *data, int enc,
@@ -1168,10 +1203,15 @@ static int test_mb_acipher_cycles(struct test_mb_skcipher_data *data, int enc,
1168 unsigned long cycles = 0; 1203 unsigned long cycles = 0;
1169 int ret = 0; 1204 int ret = 0;
1170 int i; 1205 int i;
1206 int *rc;
1207
1208 rc = kcalloc(num_mb, sizeof(*rc), GFP_KERNEL);
1209 if (!rc)
1210 return -ENOMEM;
1171 1211
1172 /* Warm-up run. */ 1212 /* Warm-up run. */
1173 for (i = 0; i < 4; i++) { 1213 for (i = 0; i < 4; i++) {
1174 ret = do_mult_acipher_op(data, enc, num_mb); 1214 ret = do_mult_acipher_op(data, enc, num_mb, rc);
1175 if (ret) 1215 if (ret)
1176 goto out; 1216 goto out;
1177 } 1217 }
@@ -1181,7 +1221,7 @@ static int test_mb_acipher_cycles(struct test_mb_skcipher_data *data, int enc,
1181 cycles_t start, end; 1221 cycles_t start, end;
1182 1222
1183 start = get_cycles(); 1223 start = get_cycles();
1184 ret = do_mult_acipher_op(data, enc, num_mb); 1224 ret = do_mult_acipher_op(data, enc, num_mb, rc);
1185 end = get_cycles(); 1225 end = get_cycles();
1186 1226
1187 if (ret) 1227 if (ret)
@@ -1190,11 +1230,11 @@ static int test_mb_acipher_cycles(struct test_mb_skcipher_data *data, int enc,
1190 cycles += end - start; 1230 cycles += end - start;
1191 } 1231 }
1192 1232
1193out: 1233 pr_cont("1 operation in %lu cycles (%d bytes)\n",
1194 if (ret == 0) 1234 (cycles + 4) / (8 * num_mb), blen);
1195 pr_cont("1 operation in %lu cycles (%d bytes)\n",
1196 (cycles + 4) / (8 * num_mb), blen);
1197 1235
1236out:
1237 kfree(rc);
1198 return ret; 1238 return ret;
1199} 1239}
1200 1240
@@ -1606,7 +1646,7 @@ static inline int tcrypt_test(const char *alg)
1606 return ret; 1646 return ret;
1607} 1647}
1608 1648
1609static int do_test(const char *alg, u32 type, u32 mask, int m) 1649static int do_test(const char *alg, u32 type, u32 mask, int m, u32 num_mb)
1610{ 1650{
1611 int i; 1651 int i;
1612 int ret = 0; 1652 int ret = 0;
@@ -1621,7 +1661,7 @@ static int do_test(const char *alg, u32 type, u32 mask, int m)
1621 } 1661 }
1622 1662
1623 for (i = 1; i < 200; i++) 1663 for (i = 1; i < 200; i++)
1624 ret += do_test(NULL, 0, 0, i); 1664 ret += do_test(NULL, 0, 0, i, num_mb);
1625 break; 1665 break;
1626 1666
1627 case 1: 1667 case 1:
@@ -2903,7 +2943,7 @@ static int __init tcrypt_mod_init(void)
2903 goto err_free_tv; 2943 goto err_free_tv;
2904 } 2944 }
2905 2945
2906 err = do_test(alg, type, mask, mode); 2946 err = do_test(alg, type, mask, mode, num_mb);
2907 2947
2908 if (err) { 2948 if (err) {
2909 printk(KERN_ERR "tcrypt: one or more tests failed!\n"); 2949 printk(KERN_ERR "tcrypt: one or more tests failed!\n");