* [PATCH v5] hexdump: fix for non-aligned buffers
@ 2015-07-13 22:23 Horacio Mijail Anton Quiles
2015-07-14 6:37 ` Geert Uytterhoeven
0 siblings, 1 reply; 2+ messages in thread
From: Horacio Mijail Anton Quiles @ 2015-07-13 22:23 UTC (permalink / raw)
To: Andrew Morton, Andy Shevchenko, David Howells, Vivek Goyal,
linux-kernel, trivial, Joe Perches, Geert Uytterhoeven
An hexdump with a buf not aligned to the groupsize causes
non-naturally-aligned memory accesses. This was causing a kernel panic
on the processor BlackFin BF527, when such an unaligned buffer was fed
by the function ubifs_scanned_corruption in fs/ubifs/scan.c .
To fix this, change accesses to the contents of the buffer so they go
through get_unaligned(). This change should be harmless to unaligned-
access-capable architectures, and any performance hit should be anyway
dwarfed by the snprintf() processing time.
Signed-off-by: Horacio Mijail Antón Quiles <hmijail@gmail.com>
---
Changes in v5:
- Instead of trying to detect non-unaligned-capable architectures,
change all accesses to unconditionally use get_unaligned() (per
Andrew Morton's and Geert Uytterhoeven's comments)
Changes in v4:
- Added space before "*/" (per Joe Perches' indication)
Changes in v3:
- Removed trailing whitespace (per Joe Perches' indication)
- Changed mail headers to avoid encoding issues (per Joe Perches' hint)
Changes in v2:
- Changed from ad-hoc calculation to IS_ALIGNED() for readability (per
Joe Perches' indication)
- Made the explanation clearer (aligned vs naturally aligned)
---
lib/hexdump.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/lib/hexdump.c b/lib/hexdump.c
index 7ea0969..e3af13c 100644
--- a/lib/hexdump.c
+++ b/lib/hexdump.c
@@ -11,6 +11,7 @@
#include <linux/ctype.h>
#include <linux/kernel.h>
#include <linux/export.h>
+#include <asm/unaligned.h>
const char hex_asc[] = "0123456789abcdef";
EXPORT_SYMBOL(hex_asc);
@@ -139,7 +140,8 @@ int hex_dump_to_buffer(const void *buf, size_t len, int rowsize, int groupsize,
for (j = 0; j < ngroups; j++) {
ret = snprintf(linebuf + lx, linebuflen - lx,
"%s%16.16llx", j ? " " : "",
- (unsigned long long)*(ptr8 + j));
+ (unsigned long long)
+ get_unaligned(ptr8 + j));
if (ret >= linebuflen - lx)
goto overflow1;
lx += ret;
@@ -150,7 +152,7 @@ int hex_dump_to_buffer(const void *buf, size_t len, int rowsize, int groupsize,
for (j = 0; j < ngroups; j++) {
ret = snprintf(linebuf + lx, linebuflen - lx,
"%s%8.8x", j ? " " : "",
- *(ptr4 + j));
+ get_unaligned(ptr4 + j));
if (ret >= linebuflen - lx)
goto overflow1;
lx += ret;
@@ -161,7 +163,7 @@ int hex_dump_to_buffer(const void *buf, size_t len, int rowsize, int groupsize,
for (j = 0; j < ngroups; j++) {
ret = snprintf(linebuf + lx, linebuflen - lx,
"%s%4.4x", j ? " " : "",
- *(ptr2 + j));
+ get_unaligned(ptr2 + j));
if (ret >= linebuflen - lx)
goto overflow1;
lx += ret;
--
2.1.4
^ permalink raw reply related [flat|nested] 2+ messages in thread* Re: [PATCH v5] hexdump: fix for non-aligned buffers
2015-07-13 22:23 [PATCH v5] hexdump: fix for non-aligned buffers Horacio Mijail Anton Quiles
@ 2015-07-14 6:37 ` Geert Uytterhoeven
0 siblings, 0 replies; 2+ messages in thread
From: Geert Uytterhoeven @ 2015-07-14 6:37 UTC (permalink / raw)
To: Horacio Mijail Anton Quiles
Cc: Andrew Morton, Andy Shevchenko, David Howells, Vivek Goyal,
linux-kernel@vger.kernel.org, Jiri Kosina, Joe Perches
On Tue, Jul 14, 2015 at 12:23 AM, Horacio Mijail Anton Quiles
<hmijail@gmail.com> wrote:
> An hexdump with a buf not aligned to the groupsize causes
> non-naturally-aligned memory accesses. This was causing a kernel panic
> on the processor BlackFin BF527, when such an unaligned buffer was fed
> by the function ubifs_scanned_corruption in fs/ubifs/scan.c .
>
> To fix this, change accesses to the contents of the buffer so they go
> through get_unaligned(). This change should be harmless to unaligned-
> access-capable architectures, and any performance hit should be anyway
> dwarfed by the snprintf() processing time.
>
> Signed-off-by: Horacio Mijail Antón Quiles <hmijail@gmail.com>
Acked-by: Geert Uytterhoeven <geert@linux-m68k.org>
> --- a/lib/hexdump.c
> +++ b/lib/hexdump.c
> @@ -11,6 +11,7 @@
> @@ -139,7 +140,8 @@ int hex_dump_to_buffer(const void *buf, size_t len, int rowsize, int groupsize,
> for (j = 0; j < ngroups; j++) {
> ret = snprintf(linebuf + lx, linebuflen - lx,
> "%s%16.16llx", j ? " " : "",
> - (unsigned long long)*(ptr8 + j));
> + (unsigned long long)
> + get_unaligned(ptr8 + j));
I think the cast to "unsigned long long" dates back to the days u64 was
"unsigned long" on some 64-bit architectures.
As u64 is now "unsigned long long", it can be removed. Would you mind sending
a follow-up patch to just do that?
Thanks!
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2015-07-14 6:37 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-07-13 22:23 [PATCH v5] hexdump: fix for non-aligned buffers Horacio Mijail Anton Quiles
2015-07-14 6:37 ` Geert Uytterhoeven
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox