Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

KEYS: trusted: dcp: fix improper sg use with CONFIG_VMAP_STACK=y

With vmalloc stack addresses enabled (CONFIG_VMAP_STACK=y) DCP trusted
keys can crash during en- and decryption of the blob encryption key via
the DCP crypto driver. This is caused by improperly using sg_init_one()
with vmalloc'd stack buffers (plain_key_blob).

Fix this by always using kmalloc() for buffers we give to the DCP crypto
driver.

Cc: stable@vger.kernel.org # v6.10+
Fixes: 0e28bf61a5f9 ("KEYS: trusted: dcp: fix leak of blob encryption key")
Signed-off-by: David Gstir <david@sigma-star.at>
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>

authored by

David Gstir and committed by
Jarkko Sakkinen
e8d9fab3 5f56d41a

+18 -4
+18 -4
security/keys/trusted-keys/trusted_dcp.c
··· 201 201 { 202 202 struct dcp_blob_fmt *b = (struct dcp_blob_fmt *)p->blob; 203 203 int blen, ret; 204 - u8 plain_blob_key[AES_KEYSIZE_128]; 204 + u8 *plain_blob_key; 205 205 206 206 blen = calc_blob_len(p->key_len); 207 207 if (blen > MAX_BLOB_SIZE) 208 208 return -E2BIG; 209 + 210 + plain_blob_key = kmalloc(AES_KEYSIZE_128, GFP_KERNEL); 211 + if (!plain_blob_key) 212 + return -ENOMEM; 209 213 210 214 b->fmt_version = DCP_BLOB_VERSION; 211 215 get_random_bytes(b->nonce, AES_KEYSIZE_128); ··· 233 229 ret = 0; 234 230 235 231 out: 236 - memzero_explicit(plain_blob_key, sizeof(plain_blob_key)); 232 + memzero_explicit(plain_blob_key, AES_KEYSIZE_128); 233 + kfree(plain_blob_key); 237 234 238 235 return ret; 239 236 } ··· 243 238 { 244 239 struct dcp_blob_fmt *b = (struct dcp_blob_fmt *)p->blob; 245 240 int blen, ret; 246 - u8 plain_blob_key[AES_KEYSIZE_128]; 241 + u8 *plain_blob_key = NULL; 247 242 248 243 if (b->fmt_version != DCP_BLOB_VERSION) { 249 244 pr_err("DCP blob has bad version: %i, expected %i\n", ··· 258 253 pr_err("DCP blob has bad length: %i != %i\n", blen, 259 254 p->blob_len); 260 255 ret = -EINVAL; 256 + goto out; 257 + } 258 + 259 + plain_blob_key = kmalloc(AES_KEYSIZE_128, GFP_KERNEL); 260 + if (!plain_blob_key) { 261 + ret = -ENOMEM; 261 262 goto out; 262 263 } 263 264 ··· 282 271 283 272 ret = 0; 284 273 out: 285 - memzero_explicit(plain_blob_key, sizeof(plain_blob_key)); 274 + if (plain_blob_key) { 275 + memzero_explicit(plain_blob_key, AES_KEYSIZE_128); 276 + kfree(plain_blob_key); 277 + } 286 278 287 279 return ret; 288 280 }