From bc0a8b2fd07c2d7385637dfca4e67d2780019c0f Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 7 Jun 2023 14:52:41 +0200 Subject: [PATCH] 6.1-stable patches added patches: fs-ntfs3-validate-mft-flags-before-replaying-logs.patch keys-asymmetric-copy-sig-and-digest-in-public_key_verify_signature.patch regmap-account-for-register-length-when-chunking.patch --- ...date-mft-flags-before-replaying-logs.patch | 137 ++++++++++++++++++ ...igest-in-public_key_verify_signature.patch | 112 ++++++++++++++ ...nt-for-register-length-when-chunking.patch | 46 ++++++ queue-6.1/series | 3 + 4 files changed, 298 insertions(+) create mode 100644 queue-6.1/fs-ntfs3-validate-mft-flags-before-replaying-logs.patch create mode 100644 queue-6.1/keys-asymmetric-copy-sig-and-digest-in-public_key_verify_signature.patch create mode 100644 queue-6.1/regmap-account-for-register-length-when-chunking.patch diff --git a/queue-6.1/fs-ntfs3-validate-mft-flags-before-replaying-logs.patch b/queue-6.1/fs-ntfs3-validate-mft-flags-before-replaying-logs.patch new file mode 100644 index 00000000000..f037792ff10 --- /dev/null +++ b/queue-6.1/fs-ntfs3-validate-mft-flags-before-replaying-logs.patch @@ -0,0 +1,137 @@ +From 98bea253aa28ad8be2ce565a9ca21beb4a9419e5 Mon Sep 17 00:00:00 2001 +From: Edward Lo +Date: Sat, 5 Nov 2022 23:39:44 +0800 +Subject: fs/ntfs3: Validate MFT flags before replaying logs + +From: Edward Lo + +commit 98bea253aa28ad8be2ce565a9ca21beb4a9419e5 upstream. + +Log load and replay is part of the metadata handle flow during mount +operation. The $MFT record will be loaded and used while replaying logs. +However, a malformed $MFT record, say, has RECORD_FLAG_DIR flag set and +contains an ATTR_ROOT attribute will misguide kernel to treat it as a +directory, and try to free the allocated resources when the +corresponding inode is freed, which will cause an invalid kfree because +the memory hasn't actually been allocated. + +[ 101.368647] BUG: KASAN: invalid-free in kvfree+0x2c/0x40 +[ 101.369457] +[ 101.369986] CPU: 0 PID: 198 Comm: mount Not tainted 6.0.0-rc7+ #5 +[ 101.370529] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.14.0-0-g155821a1990b-prebuilt.qemu.org 04/01/2014 +[ 101.371362] Call Trace: +[ 101.371795] +[ 101.372157] dump_stack_lvl+0x49/0x63 +[ 101.372658] print_report.cold+0xf5/0x689 +[ 101.373022] ? ni_write_inode+0x754/0xd90 +[ 101.373378] ? kvfree+0x2c/0x40 +[ 101.373698] kasan_report_invalid_free+0x77/0xf0 +[ 101.374058] ? kvfree+0x2c/0x40 +[ 101.374352] ? kvfree+0x2c/0x40 +[ 101.374668] __kasan_slab_free+0x189/0x1b0 +[ 101.374992] ? kvfree+0x2c/0x40 +[ 101.375271] kfree+0x168/0x3b0 +[ 101.375717] kvfree+0x2c/0x40 +[ 101.376002] indx_clear+0x26/0x60 +[ 101.376316] ni_clear+0xc5/0x290 +[ 101.376661] ntfs_evict_inode+0x45/0x70 +[ 101.377001] evict+0x199/0x280 +[ 101.377432] iput.part.0+0x286/0x320 +[ 101.377819] iput+0x32/0x50 +[ 101.378166] ntfs_loadlog_and_replay+0x143/0x320 +[ 101.378656] ? ntfs_bio_fill_1+0x510/0x510 +[ 101.378968] ? iput.part.0+0x286/0x320 +[ 101.379367] ntfs_fill_super+0xecb/0x1ba0 +[ 101.379729] ? put_ntfs+0x1d0/0x1d0 +[ 101.380046] ? vsprintf+0x20/0x20 +[ 101.380542] ? mutex_unlock+0x81/0xd0 +[ 101.380914] ? set_blocksize+0x95/0x150 +[ 101.381597] get_tree_bdev+0x232/0x370 +[ 101.382254] ? put_ntfs+0x1d0/0x1d0 +[ 101.382699] ntfs_fs_get_tree+0x15/0x20 +[ 101.383094] vfs_get_tree+0x4c/0x130 +[ 101.383675] path_mount+0x654/0xfe0 +[ 101.384203] ? putname+0x80/0xa0 +[ 101.384540] ? finish_automount+0x2e0/0x2e0 +[ 101.384943] ? putname+0x80/0xa0 +[ 101.385362] ? kmem_cache_free+0x1c4/0x440 +[ 101.385968] ? putname+0x80/0xa0 +[ 101.386666] do_mount+0xd6/0xf0 +[ 101.387228] ? path_mount+0xfe0/0xfe0 +[ 101.387585] ? __kasan_check_write+0x14/0x20 +[ 101.387979] __x64_sys_mount+0xca/0x110 +[ 101.388436] do_syscall_64+0x3b/0x90 +[ 101.388757] entry_SYSCALL_64_after_hwframe+0x63/0xcd +[ 101.389289] RIP: 0033:0x7fa0f70e948a +[ 101.390048] Code: 48 8b 0d 11 fa 2a 00 f7 d8 64 89 01 48 83 c8 ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 49 89 ca b8 a5 00 00 008 +[ 101.391297] RSP: 002b:00007ffc24fdecc8 EFLAGS: 00000202 ORIG_RAX: 00000000000000a5 +[ 101.391988] RAX: ffffffffffffffda RBX: 000055932c183060 RCX: 00007fa0f70e948a +[ 101.392494] RDX: 000055932c183260 RSI: 000055932c1832e0 RDI: 000055932c18bce0 +[ 101.393053] RBP: 0000000000000000 R08: 000055932c183280 R09: 0000000000000020 +[ 101.393577] R10: 00000000c0ed0000 R11: 0000000000000202 R12: 000055932c18bce0 +[ 101.394044] R13: 000055932c183260 R14: 0000000000000000 R15: 00000000ffffffff +[ 101.394747] +[ 101.395402] +[ 101.396047] Allocated by task 198: +[ 101.396724] kasan_save_stack+0x26/0x50 +[ 101.397400] __kasan_slab_alloc+0x6d/0x90 +[ 101.397974] kmem_cache_alloc_lru+0x192/0x5a0 +[ 101.398524] ntfs_alloc_inode+0x23/0x70 +[ 101.399137] alloc_inode+0x3b/0xf0 +[ 101.399534] iget5_locked+0x54/0xa0 +[ 101.400026] ntfs_iget5+0xaf/0x1780 +[ 101.400414] ntfs_loadlog_and_replay+0xe5/0x320 +[ 101.400883] ntfs_fill_super+0xecb/0x1ba0 +[ 101.401313] get_tree_bdev+0x232/0x370 +[ 101.401774] ntfs_fs_get_tree+0x15/0x20 +[ 101.402224] vfs_get_tree+0x4c/0x130 +[ 101.402673] path_mount+0x654/0xfe0 +[ 101.403160] do_mount+0xd6/0xf0 +[ 101.403537] __x64_sys_mount+0xca/0x110 +[ 101.404058] do_syscall_64+0x3b/0x90 +[ 101.404333] entry_SYSCALL_64_after_hwframe+0x63/0xcd +[ 101.404816] +[ 101.405067] The buggy address belongs to the object at ffff888008cc9ea0 +[ 101.405067] which belongs to the cache ntfs_inode_cache of size 992 +[ 101.406171] The buggy address is located 232 bytes inside of +[ 101.406171] 992-byte region [ffff888008cc9ea0, ffff888008cca280) +[ 101.406995] +[ 101.408559] The buggy address belongs to the physical page: +[ 101.409320] page:00000000dccf19dd refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x8cc8 +[ 101.410654] head:00000000dccf19dd order:2 compound_mapcount:0 compound_pincount:0 +[ 101.411533] flags: 0xfffffc0010200(slab|head|node=0|zone=1|lastcpupid=0x1fffff) +[ 101.412665] raw: 000fffffc0010200 0000000000000000 dead000000000122 ffff888003695140 +[ 101.413209] raw: 0000000000000000 00000000800e000e 00000001ffffffff 0000000000000000 +[ 101.413799] page dumped because: kasan: bad access detected +[ 101.414213] +[ 101.414427] Memory state around the buggy address: +[ 101.414991] ffff888008cc9e80: fc fc fc fc 00 00 00 00 00 00 00 00 00 00 00 00 +[ 101.415785] ffff888008cc9f00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +[ 101.416933] >ffff888008cc9f80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +[ 101.417857] ^ +[ 101.418566] ffff888008cca000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +[ 101.419704] ffff888008cca080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + +Signed-off-by: Edward Lo +Signed-off-by: Konstantin Komarov +Cc: Luiz Capitulino +Signed-off-by: Greg Kroah-Hartman +--- + fs/ntfs3/inode.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +--- a/fs/ntfs3/inode.c ++++ b/fs/ntfs3/inode.c +@@ -98,6 +98,12 @@ static struct inode *ntfs_read_mft(struc + /* Record should contain $I30 root. */ + is_dir = rec->flags & RECORD_FLAG_DIR; + ++ /* MFT_REC_MFT is not a dir */ ++ if (is_dir && ino == MFT_REC_MFT) { ++ err = -EINVAL; ++ goto out; ++ } ++ + inode->i_generation = le16_to_cpu(rec->seq); + + /* Enumerate all struct Attributes MFT. */ diff --git a/queue-6.1/keys-asymmetric-copy-sig-and-digest-in-public_key_verify_signature.patch b/queue-6.1/keys-asymmetric-copy-sig-and-digest-in-public_key_verify_signature.patch new file mode 100644 index 00000000000..d55fe76af18 --- /dev/null +++ b/queue-6.1/keys-asymmetric-copy-sig-and-digest-in-public_key_verify_signature.patch @@ -0,0 +1,112 @@ +From c3d03e8e35e005e1a614e51bb59053eeb5857f76 Mon Sep 17 00:00:00 2001 +From: Roberto Sassu +Date: Thu, 8 Dec 2022 10:56:46 +0100 +Subject: KEYS: asymmetric: Copy sig and digest in public_key_verify_signature() + +From: Roberto Sassu + +commit c3d03e8e35e005e1a614e51bb59053eeb5857f76 upstream. + +Commit ac4e97abce9b8 ("scatterlist: sg_set_buf() argument must be in linear +mapping") checks that both the signature and the digest reside in the +linear mapping area. + +However, more recently commit ba14a194a434c ("fork: Add generic vmalloced +stack support") made it possible to move the stack in the vmalloc area, +which is not contiguous, and thus not suitable for sg_set_buf() which needs +adjacent pages. + +Always make a copy of the signature and digest in the same buffer used to +store the key and its parameters, and pass them to sg_init_one(). Prefer it +to conditionally doing the copy if necessary, to keep the code simple. The +buffer allocated with kmalloc() is in the linear mapping area. + +Cc: stable@vger.kernel.org # 4.9.x +Fixes: ba14a194a434 ("fork: Add generic vmalloced stack support") +Link: https://lore.kernel.org/linux-integrity/Y4pIpxbjBdajymBJ@sol.localdomain/ +Suggested-by: Eric Biggers +Signed-off-by: Roberto Sassu +Reviewed-by: Eric Biggers +Tested-by: Stefan Berger +Signed-off-by: Greg Kroah-Hartman +--- + crypto/asymmetric_keys/public_key.c | 38 +++++++++++++++++++----------------- + 1 file changed, 21 insertions(+), 17 deletions(-) + +--- a/crypto/asymmetric_keys/public_key.c ++++ b/crypto/asymmetric_keys/public_key.c +@@ -380,9 +380,10 @@ int public_key_verify_signature(const st + struct crypto_wait cwait; + struct crypto_akcipher *tfm; + struct akcipher_request *req; +- struct scatterlist src_sg[2]; ++ struct scatterlist src_sg; + char alg_name[CRYPTO_MAX_ALG_NAME]; +- char *key, *ptr; ++ char *buf, *ptr; ++ size_t buf_len; + int ret; + + pr_devel("==>%s()\n", __func__); +@@ -420,34 +421,37 @@ int public_key_verify_signature(const st + if (!req) + goto error_free_tfm; + +- key = kmalloc(pkey->keylen + sizeof(u32) * 2 + pkey->paramlen, +- GFP_KERNEL); +- if (!key) ++ buf_len = max_t(size_t, pkey->keylen + sizeof(u32) * 2 + pkey->paramlen, ++ sig->s_size + sig->digest_size); ++ ++ buf = kmalloc(buf_len, GFP_KERNEL); ++ if (!buf) + goto error_free_req; + +- memcpy(key, pkey->key, pkey->keylen); +- ptr = key + pkey->keylen; ++ memcpy(buf, pkey->key, pkey->keylen); ++ ptr = buf + pkey->keylen; + ptr = pkey_pack_u32(ptr, pkey->algo); + ptr = pkey_pack_u32(ptr, pkey->paramlen); + memcpy(ptr, pkey->params, pkey->paramlen); + + if (pkey->key_is_private) +- ret = crypto_akcipher_set_priv_key(tfm, key, pkey->keylen); ++ ret = crypto_akcipher_set_priv_key(tfm, buf, pkey->keylen); + else +- ret = crypto_akcipher_set_pub_key(tfm, key, pkey->keylen); ++ ret = crypto_akcipher_set_pub_key(tfm, buf, pkey->keylen); + if (ret) +- goto error_free_key; ++ goto error_free_buf; + + if (strcmp(pkey->pkey_algo, "sm2") == 0 && sig->data_size) { + ret = cert_sig_digest_update(sig, tfm); + if (ret) +- goto error_free_key; ++ goto error_free_buf; + } + +- sg_init_table(src_sg, 2); +- sg_set_buf(&src_sg[0], sig->s, sig->s_size); +- sg_set_buf(&src_sg[1], sig->digest, sig->digest_size); +- akcipher_request_set_crypt(req, src_sg, NULL, sig->s_size, ++ memcpy(buf, sig->s, sig->s_size); ++ memcpy(buf + sig->s_size, sig->digest, sig->digest_size); ++ ++ sg_init_one(&src_sg, buf, sig->s_size + sig->digest_size); ++ akcipher_request_set_crypt(req, &src_sg, NULL, sig->s_size, + sig->digest_size); + crypto_init_wait(&cwait); + akcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG | +@@ -455,8 +459,8 @@ int public_key_verify_signature(const st + crypto_req_done, &cwait); + ret = crypto_wait_req(crypto_akcipher_verify(req), &cwait); + +-error_free_key: +- kfree(key); ++error_free_buf: ++ kfree(buf); + error_free_req: + akcipher_request_free(req); + error_free_tfm: diff --git a/queue-6.1/regmap-account-for-register-length-when-chunking.patch b/queue-6.1/regmap-account-for-register-length-when-chunking.patch new file mode 100644 index 00000000000..28d2c7157a2 --- /dev/null +++ b/queue-6.1/regmap-account-for-register-length-when-chunking.patch @@ -0,0 +1,46 @@ +From 3981514180c987a79ea98f0ae06a7cbf58a9ac0f Mon Sep 17 00:00:00 2001 +From: Jim Wylder +Date: Wed, 17 May 2023 10:20:11 -0500 +Subject: regmap: Account for register length when chunking + +From: Jim Wylder + +commit 3981514180c987a79ea98f0ae06a7cbf58a9ac0f upstream. + +Currently, when regmap_raw_write() splits the data, it uses the +max_raw_write value defined for the bus. For any bus that includes +the target register address in the max_raw_write value, the chunked +transmission will always exceed the maximum transmission length. +To avoid this problem, subtract the length of the register and the +padding from the maximum transmission. + +Signed-off-by: Jim Wylder +--- + drivers/base/regmap/regmap.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +--- a/drivers/base/regmap/regmap.c ++++ b/drivers/base/regmap/regmap.c +@@ -2064,6 +2064,8 @@ int _regmap_raw_write(struct regmap *map + size_t val_count = val_len / val_bytes; + size_t chunk_count, chunk_bytes; + size_t chunk_regs = val_count; ++ size_t max_data = map->max_raw_write - map->format.reg_bytes - ++ map->format.pad_bytes; + int ret, i; + + if (!val_count) +@@ -2071,8 +2073,8 @@ int _regmap_raw_write(struct regmap *map + + if (map->use_single_write) + chunk_regs = 1; +- else if (map->max_raw_write && val_len > map->max_raw_write) +- chunk_regs = map->max_raw_write / val_bytes; ++ else if (map->max_raw_write && val_len > max_data) ++ chunk_regs = max_data / val_bytes; + + chunk_count = val_count / chunk_regs; + chunk_bytes = chunk_regs * val_bytes; diff --git a/queue-6.1/series b/queue-6.1/series index 7916c8200bc..3c630d586e3 100644 --- a/queue-6.1/series +++ b/queue-6.1/series @@ -219,3 +219,6 @@ ksmbd-fix-uaf-issue-from-opinfo-conn.patch ksmbd-fix-incorrect-allocationsize-set-in-smb2_get_info.patch ksmbd-fix-slab-out-of-bounds-read-in-smb2_handle_negotiate.patch ksmbd-fix-multiple-out-of-bounds-read-during-context-decoding.patch +keys-asymmetric-copy-sig-and-digest-in-public_key_verify_signature.patch +fs-ntfs3-validate-mft-flags-before-replaying-logs.patch +regmap-account-for-register-length-when-chunking.patch -- 2.47.3