Skip to content

Commit

Permalink
x86: __memcpy_flushcache: fix wrong alignment if size > 2^32
Browse files Browse the repository at this point in the history
[ Upstream commit a6823e4 ]

The first "if" condition in __memcpy_flushcache is supposed to align the
"dest" variable to 8 bytes and copy data up to this alignment.  However,
this condition may misbehave if "size" is greater than 4GiB.

The statement min_t(unsigned, size, ALIGN(dest, 8) - dest); casts both
arguments to unsigned int and selects the smaller one.  However, the
cast truncates high bits in "size" and it results in misbehavior.

For example:

	suppose that size == 0x100000001, dest == 0x200000002
	min_t(unsigned, size, ALIGN(dest, 8) - dest) == min_t(0x1, 0xe) == 0x1;
	...
	dest += 0x1;

so we copy just one byte "and" dest remains unaligned.

This patch fixes the bug by replacing unsigned with size_t.

Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
  • Loading branch information
Mikulas Patocka authored and gregkh committed May 9, 2022
1 parent 4d9d808 commit 96e4f14
Showing 1 changed file with 1 addition and 1 deletion.
2 changes: 1 addition & 1 deletion arch/x86/lib/usercopy_64.c
Expand Up @@ -119,7 +119,7 @@ void __memcpy_flushcache(void *_dst, const void *_src, size_t size)

/* cache copy and flush to align dest */
if (!IS_ALIGNED(dest, 8)) {
unsigned len = min_t(unsigned, size, ALIGN(dest, 8) - dest);
size_t len = min_t(size_t, size, ALIGN(dest, 8) - dest);

memcpy((void *) dest, (void *) source, len);
clean_cache_range((void *) dest, len);
Expand Down

0 comments on commit 96e4f14

Please sign in to comment.