]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
xfs: check opcode and iovec count match in xlog_recover_attri_commit_pass2
authorDarrick J. Wong <djwong@kernel.org>
Wed, 30 Apr 2025 21:26:52 +0000 (14:26 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 9 May 2025 07:41:37 +0000 (09:41 +0200)
[ Upstream commit ad206ae50eca62836c5460ab5bbf2a6c59a268e7 ]

Check that the number of recovered log iovecs is what is expected for
the xattri opcode is expecting.

Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Leah Rumancik <leah.rumancik@gmail.com>
Acked-by: "Darrick J. Wong" <djwong@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
fs/xfs/xfs_attr_item.c

index c5bc6b72e0147541e39e9d33cf486ce60f464df9..a8e09ea2622d84ca459fd607f58324cbcc5cb4ed 100644 (file)
@@ -717,6 +717,7 @@ xlog_recover_attri_commit_pass2(
        const void                      *attr_value = NULL;
        const void                      *attr_name;
        size_t                          len;
+       unsigned int                    op;
 
        attri_formatp = item->ri_buf[0].i_addr;
        attr_name = item->ri_buf[1].i_addr;
@@ -735,6 +736,32 @@ xlog_recover_attri_commit_pass2(
                return -EFSCORRUPTED;
        }
 
+       /* Check the number of log iovecs makes sense for the op code. */
+       op = attri_formatp->alfi_op_flags & XFS_ATTRI_OP_FLAGS_TYPE_MASK;
+       switch (op) {
+       case XFS_ATTRI_OP_FLAGS_SET:
+       case XFS_ATTRI_OP_FLAGS_REPLACE:
+               /* Log item, attr name, attr value */
+               if (item->ri_total != 3) {
+                       XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp,
+                                            attri_formatp, len);
+                       return -EFSCORRUPTED;
+               }
+               break;
+       case XFS_ATTRI_OP_FLAGS_REMOVE:
+               /* Log item, attr name */
+               if (item->ri_total != 2) {
+                       XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp,
+                                            attri_formatp, len);
+                       return -EFSCORRUPTED;
+               }
+               break;
+       default:
+               XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp,
+                                    attri_formatp, len);
+               return -EFSCORRUPTED;
+       }
+
        /* Validate the attr name */
        if (item->ri_buf[1].i_len !=
                        xlog_calc_iovec_len(attri_formatp->alfi_name_len)) {