]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
6.1-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 7 Jun 2023 12:52:41 +0000 (14:52 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 7 Jun 2023 12:52:41 +0000 (14:52 +0200)
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

queue-6.1/fs-ntfs3-validate-mft-flags-before-replaying-logs.patch [new file with mode: 0644]
queue-6.1/keys-asymmetric-copy-sig-and-digest-in-public_key_verify_signature.patch [new file with mode: 0644]
queue-6.1/regmap-account-for-register-length-when-chunking.patch [new file with mode: 0644]
queue-6.1/series

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 (file)
index 0000000..f037792
--- /dev/null
@@ -0,0 +1,137 @@
+From 98bea253aa28ad8be2ce565a9ca21beb4a9419e5 Mon Sep 17 00:00:00 2001
+From: Edward Lo <edward.lo@ambergroup.io>
+Date: Sat, 5 Nov 2022 23:39:44 +0800
+Subject: fs/ntfs3: Validate MFT flags before replaying logs
+
+From: Edward Lo <edward.lo@ambergroup.io>
+
+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]  <TASK>
+[  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]  </TASK>
+[  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 <edward.lo@ambergroup.io>
+Signed-off-by: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
+Cc: Luiz Capitulino <luizcap@amazon.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..d55fe76
--- /dev/null
@@ -0,0 +1,112 @@
+From c3d03e8e35e005e1a614e51bb59053eeb5857f76 Mon Sep 17 00:00:00 2001
+From: Roberto Sassu <roberto.sassu@huawei.com>
+Date: Thu, 8 Dec 2022 10:56:46 +0100
+Subject: KEYS: asymmetric: Copy sig and digest in public_key_verify_signature()
+
+From: Roberto Sassu <roberto.sassu@huawei.com>
+
+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 <ebiggers@kernel.org>
+Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
+Reviewed-by: Eric Biggers <ebiggers@google.com>
+Tested-by: Stefan Berger <stefanb@linux.ibm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..28d2c71
--- /dev/null
@@ -0,0 +1,46 @@
+From 3981514180c987a79ea98f0ae06a7cbf58a9ac0f Mon Sep 17 00:00:00 2001
+From: Jim Wylder <jwylder@google.com>
+Date: Wed, 17 May 2023 10:20:11 -0500
+Subject: regmap: Account for register length when chunking
+
+From: Jim Wylder <jwylder@google.com>
+
+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 <jwylder@google.com
+Link: https://lore.kernel.org/r/20230517152444.3690870-2-jwylder@google.com
+Signed-off-by: Mark Brown <broonie@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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;
index 7916c8200bccfddbc7f61b584a66f117f6de8eb1..3c630d586e3d7b0bb9b8f300e2f3689c229192ee 100644 (file)
@@ -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