Commit 5a147c9f57bab06183b2bdde78aa49f3e332a557
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security
Pull key subsystem fixes from James Morris: "Fixes for the keys subsystem, one of which addresses a use-after-free bug" * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security: PEFILE: Relax the check on the length of the PKCS#7 cert KEYS: Fix use-after-free in assoc_array_gc() KEYS: Fix public_key asymmetric key subtype name KEYS: Increase root_maxkeys and root_maxbytes sizes
Showing 4 changed files Side-by-side Diff
crypto/asymmetric_keys/public_key.c
... | ... | @@ -121,6 +121,7 @@ |
121 | 121 | struct asymmetric_key_subtype public_key_subtype = { |
122 | 122 | .owner = THIS_MODULE, |
123 | 123 | .name = "public_key", |
124 | + .name_len = sizeof("public_key") - 1, | |
124 | 125 | .describe = public_key_describe, |
125 | 126 | .destroy = public_key_destroy, |
126 | 127 | .verify_signature = public_key_verify_signature_2, |
crypto/asymmetric_keys/verify_pefile.c
... | ... | @@ -128,6 +128,7 @@ |
128 | 128 | { |
129 | 129 | struct win_certificate wrapper; |
130 | 130 | const u8 *pkcs7; |
131 | + unsigned len; | |
131 | 132 | |
132 | 133 | if (ctx->sig_len < sizeof(wrapper)) { |
133 | 134 | pr_debug("Signature wrapper too short\n"); |
134 | 135 | |
135 | 136 | |
136 | 137 | |
137 | 138 | |
... | ... | @@ -154,33 +155,49 @@ |
154 | 155 | return -ENOTSUPP; |
155 | 156 | } |
156 | 157 | |
157 | - /* Looks like actual pkcs signature length is in wrapper->length. | |
158 | - * size obtained from data dir entries lists the total size of | |
159 | - * certificate table which is also aligned to octawrod boundary. | |
160 | - * | |
161 | - * So set signature length field appropriately. | |
158 | + /* It looks like the pkcs signature length in wrapper->length and the | |
159 | + * size obtained from the data dir entries, which lists the total size | |
160 | + * of certificate table, are both aligned to an octaword boundary, so | |
161 | + * we may have to deal with some padding. | |
162 | 162 | */ |
163 | 163 | ctx->sig_len = wrapper.length; |
164 | 164 | ctx->sig_offset += sizeof(wrapper); |
165 | 165 | ctx->sig_len -= sizeof(wrapper); |
166 | - if (ctx->sig_len == 0) { | |
166 | + if (ctx->sig_len < 4) { | |
167 | 167 | pr_debug("Signature data missing\n"); |
168 | 168 | return -EKEYREJECTED; |
169 | 169 | } |
170 | 170 | |
171 | - /* What's left should a PKCS#7 cert */ | |
171 | + /* What's left should be a PKCS#7 cert */ | |
172 | 172 | pkcs7 = pebuf + ctx->sig_offset; |
173 | - if (pkcs7[0] == (ASN1_CONS_BIT | ASN1_SEQ)) { | |
174 | - if (pkcs7[1] == 0x82 && | |
175 | - pkcs7[2] == (((ctx->sig_len - 4) >> 8) & 0xff) && | |
176 | - pkcs7[3] == ((ctx->sig_len - 4) & 0xff)) | |
177 | - return 0; | |
178 | - if (pkcs7[1] == 0x80) | |
179 | - return 0; | |
180 | - if (pkcs7[1] > 0x82) | |
181 | - return -EMSGSIZE; | |
173 | + if (pkcs7[0] != (ASN1_CONS_BIT | ASN1_SEQ)) | |
174 | + goto not_pkcs7; | |
175 | + | |
176 | + switch (pkcs7[1]) { | |
177 | + case 0 ... 0x7f: | |
178 | + len = pkcs7[1] + 2; | |
179 | + goto check_len; | |
180 | + case ASN1_INDEFINITE_LENGTH: | |
181 | + return 0; | |
182 | + case 0x81: | |
183 | + len = pkcs7[2] + 3; | |
184 | + goto check_len; | |
185 | + case 0x82: | |
186 | + len = ((pkcs7[2] << 8) | pkcs7[3]) + 4; | |
187 | + goto check_len; | |
188 | + case 0x83 ... 0xff: | |
189 | + return -EMSGSIZE; | |
190 | + default: | |
191 | + goto not_pkcs7; | |
182 | 192 | } |
183 | 193 | |
194 | +check_len: | |
195 | + if (len <= ctx->sig_len) { | |
196 | + /* There may be padding */ | |
197 | + ctx->sig_len = len; | |
198 | + return 0; | |
199 | + } | |
200 | +not_pkcs7: | |
184 | 201 | pr_debug("Signature data not PKCS#7\n"); |
185 | 202 | return -ELIBBAD; |
186 | 203 | } |
lib/assoc_array.c
security/keys/key.c
... | ... | @@ -27,8 +27,8 @@ |
27 | 27 | struct rb_root key_user_tree; /* tree of quota records indexed by UID */ |
28 | 28 | DEFINE_SPINLOCK(key_user_lock); |
29 | 29 | |
30 | -unsigned int key_quota_root_maxkeys = 200; /* root's key count quota */ | |
31 | -unsigned int key_quota_root_maxbytes = 20000; /* root's key space quota */ | |
30 | +unsigned int key_quota_root_maxkeys = 1000000; /* root's key count quota */ | |
31 | +unsigned int key_quota_root_maxbytes = 25000000; /* root's key space quota */ | |
32 | 32 | unsigned int key_quota_maxkeys = 200; /* general key count quota */ |
33 | 33 | unsigned int key_quota_maxbytes = 20000; /* general key space quota */ |
34 | 34 |