Commit 5a147c9f57bab06183b2bdde78aa49f3e332a557

Authored by Linus Torvalds

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 }
... ... @@ -1735,7 +1735,7 @@
1735 1735 gc_complete:
1736 1736 edit->set[0].to = new_root;
1737 1737 assoc_array_apply_edit(edit);
1738   - edit->array->nr_leaves_on_tree = nr_leaves_on_tree;
  1738 + array->nr_leaves_on_tree = nr_leaves_on_tree;
1739 1739 return 0;
1740 1740  
1741 1741 enomem:
... ... @@ -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