public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [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