Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3895e51f authored by Dave Chinner's avatar Dave Chinner Committed by Dave Chinner
Browse files

xfs: ensure correct log item buffer alignment



On 32 bit platforms, the log item vector headers are not 64 bit
aligned or sized. hence if we don't take care to align them
correctly or pad the buffer appropriately for 8 byte alignment, we
can end up with alignment issues when accessing the user buffer
directly as a structure.

To solve this, simply pad the buffer headers to 64 bit offset so
that the data section is always 8 byte aligned.

Signed-off-by: default avatarDave Chinner <dchinner@redhat.com>
Reported-by: default avatarMichael L. Semon <mlsemon35@gmail.com>
Tested-by: default avatarMichael L. Semon <mlsemon35@gmail.com>
Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
Signed-off-by: default avatarDave Chinner <david@fromorbit.com>
parent fe60a8a0
Loading
Loading
Loading
Loading
+15 −4
Original line number Original line Diff line number Diff line
@@ -205,16 +205,25 @@ xlog_cil_insert_format_items(
		/*
		/*
		 * We 64-bit align the length of each iovec so that the start
		 * We 64-bit align the length of each iovec so that the start
		 * of the next one is naturally aligned.  We'll need to
		 * of the next one is naturally aligned.  We'll need to
		 * account for that slack space here.
		 * account for that slack space here. Then round nbytes up
		 * to 64-bit alignment so that the initial buffer alignment is
		 * easy to calculate and verify.
		 */
		 */
		nbytes += niovecs * sizeof(uint64_t);
		nbytes += niovecs * sizeof(uint64_t);
		nbytes = round_up(nbytes, sizeof(uint64_t));


		/* grab the old item if it exists for reservation accounting */
		/* grab the old item if it exists for reservation accounting */
		old_lv = lip->li_lv;
		old_lv = lip->li_lv;


		/* calc buffer size */
		/*
		buf_size = sizeof(struct xfs_log_vec) + nbytes +
		 * The data buffer needs to start 64-bit aligned, so round up
				niovecs * sizeof(struct xfs_log_iovec);
		 * that space to ensure we can align it appropriately and not
		 * overrun the buffer.
		 */
		buf_size = nbytes +
			   round_up((sizeof(struct xfs_log_vec) +
				     niovecs * sizeof(struct xfs_log_iovec)),
				    sizeof(uint64_t));


		/* compare to existing item size */
		/* compare to existing item size */
		if (lip->li_lv && buf_size <= lip->li_lv->lv_size) {
		if (lip->li_lv && buf_size <= lip->li_lv->lv_size) {
@@ -251,6 +260,8 @@ xlog_cil_insert_format_items(
		/* The allocated data region lies beyond the iovec region */
		/* The allocated data region lies beyond the iovec region */
		lv->lv_buf_len = 0;
		lv->lv_buf_len = 0;
		lv->lv_buf = (char *)lv + buf_size - nbytes;
		lv->lv_buf = (char *)lv + buf_size - nbytes;
		ASSERT(IS_ALIGNED((unsigned long)lv->lv_buf, sizeof(uint64_t)));

		lip->li_ops->iop_format(lip, lv);
		lip->li_ops->iop_format(lip, lv);
insert:
insert:
		ASSERT(lv->lv_buf_len <= nbytes);
		ASSERT(lv->lv_buf_len <= nbytes);