lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [day] [month] [year] [list]
Date:	Sat, 26 Sep 2015 14:21:05 +0200
From:	Sedat Dilek <sedat.dilek@...il.com>
To:	PaX Team <pageexec@...email.hu>, Vivek Goyal <vgoyal@...hat.com>,
	"H. Peter Anvin" <hpa@...ux.intel.com>,
	Andrey Ryabinin <ryabinin.a.a@...il.com>
Cc:	Denys Vlasenko <dvlasenk@...hat.com>,
	Andy Lutomirski <luto@...nel.org>,
	Ingo Molnar <mingo@...nel.org>,
	Linus Torvalds <torvalds@...ux-foundation.org>,
	LKML <linux-kernel@...r.kernel.org>,
	"the arch/x86 maintainers" <x86@...nel.org>
Subject: arch/x86: memcpy() "confusion"

Hi,

while still playing with llvmlinux patches against Linux v4.3-rc2+ I
wondered about the diverse usage of memcpy() in several string*.[c,h]
files below x86 arch.

Just FYI: I am here on Ubuntu/precise AMD64.

The background is my build breaks again due to commit (see [1])...
     "x86, efi, kasan: #undef memset/memcpy/memmove per arch"
...with its undefs especially for memcpy.
( I have reverted it for now. )

There exists a LLVM PR18415 (see [2]) and llvmlinux has a workaround
(see [3]) for this issue.
I have attached an older alternative patch [4] from PaX Team.

So let's look at my build-log when building with CLANG v3.7...
...
  CC      arch/x86/kernel/setup.o
...
In file included from arch/x86/kernel/setup.c:96:
./arch/x86/include/asm/desc.h:121:2: error: implicit declaration of
function 'memcpy' [-Werror,-Wimplicit-function-declaration]
        memcpy(&idt[entry], gate, sizeof(*gate));
        ^
1 error generated.
...

Investigating the source-code...

[ arch/x86/kernel/setup.c:96 ]
#include <asm/desc.h>

[ arch/x86/include/asm/desc.h:121 ]
static inline void native_write_idt_entry(gate_desc *idt, int entry,
const gate_desc *gate)
{
memcpy(&idt[entry], gate, sizeof(*gate)); <--- XXX: Line #121
}

Checking the includes...

$ grep ^#include arch/x86/kernel/setup.c | egrep 'efi|string'
#include <linux/efi.h>
#include <asm/efi.h> <--- XXX: undefs of commit 769a8089c1fd moved here

Furthermore Andrey comments in his patch...
[ arch/x86/include/asm/efi.h ]
...
+/*
+ * CONFIG_KASAN may redefine memset to __memset. __memset function is present
+ * only in kernel binary. Since the EFI stub linked into a separate binary it
+ * doesn't have __memset(). So we should use standard memset from
+ * arch/x86/boot/compressed/string.c. The same applies to memcpy and memmove.
+ */
+#undef memcpy
+#undef memset
+#undef memmove
...

This statement is confirmed in...

[ arch/x86/boot/string.h ]
...
/* Undef any of these macros coming from string_32.h. */
#undef memcpy
#undef memset
#undef memcmp
...
/*
 * Access builtin version by default. If one needs to use optimized version,
 * do "undef memcpy" in .c file and link against right string.c
 */
#define memcpy(d,s,l) __builtin_memcpy(d,s,l)
#define memset(d,c,l) __builtin_memset(d,c,l)
#define memcmp  __builtin_memcmp
...

More confirmation when looking at patch...
     "x86, boot: Move optimized memcpy() 32/64 bit versions to
compressed/string.c"

My 1st question...
Is "arch/x86/boot/compressed/string.c" file the central place for
memcpy() or only for the "optimized" version?
BTW, why a c-file and not a h-file like arch/x86/boot/compressed/string.h ?

2nd question...
When thinking of an alternative implementation like in [4] - which
file is predestinated?

Why do we have in arch/x86...
    __builtin_memcpy() |  __inline_memcpy() | __memcpy() |  memcpy() ?
Some comments say "faster implementation".

Just curious...
Isn't that crying for a "simplification" or "centralization" of
memcpy() | memset() | memcmp() ?

More enlightenment! Thoughts?

Thanks in advance.

Hopes to get less confused,
- Sedat -

[1] http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=769a8089c1fd2fe94c13e66fe6e03d7820953ee3
[2] https://llvm.org/bugs/show_bug.cgi?id=18415
[3] http://git.linuxfoundation.org/?p=llvmlinux.git;a=blob_plain;f=arch/x86_64/patches/boot-workaround-PR18415.patch
[4] http://git.linuxfoundation.org/?p=llvmlinux.git;a=blob_plain;f=arch/x86_64/patches/ARCHIVE/0026-Add-own-versions-of-memcpy-and-memset-for-compilatio.patch
[5] http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/arch/x86/kernel/setup.c#n96
[6] http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/arch/x86/include/asm/desc.h#n121
[7] http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=820e8feca06ff744f60e5036c3178dde40b91afc

[ INVESTIGATIONS ]

$ cd arch/x86/

$ for p in __builtin_memcpy __inline_memcpy __memcpy memcpy ; do echo
[ $p ] ; LC_ALL=C grep $p -nr ./ | grep -v "Binary file" | grep string
| sort ; echo "" ; done

[ __builtin_memcpy ]
./boot/string.h:19:#define memcpy(d,s,l) __builtin_memcpy(d,s,l)
./include/asm/string_32.h:182:#define memcpy(t, f, n) __builtin_memcpy(t, f, n)
./include/asm/string_64.h:43:           __ret =
__builtin_memcpy((dst), (src), __len);  \

[ __inline_memcpy ]
./include/asm/string_64.h:52:#define memcpy(dst, src, len)
__inline_memcpy((dst), (src), (len))
./include/asm/string_64.h:9:static __always_inline void
*__inline_memcpy(void *to, const void *from, size_t n)

[ __memcpy ]
./include/asm/string_32.h:161:static inline void *__memcpy3d(void *to,
const void *from, size_t len)
./include/asm/string_32.h:164:          return __memcpy(to, from, len);
./include/asm/string_32.h:171:   : __memcpy3d((t), (f), (n)))
./include/asm/string_32.h:187:   : __memcpy((t), (f), (n)))
./include/asm/string_32.h:194:#define memcpy(t, f, n) __memcpy((t), (f), (n))
./include/asm/string_32.h:32:static __always_inline void
*__memcpy(void *to, const void *from, size_t n)
./include/asm/string_64.h:30:extern void *__memcpy(void *to, const
void *from, size_t len);
./include/asm/string_64.h:41:           __ret = __memcpy((dst), (src),
__len);          \
./include/asm/string_64.h:77:#define memcpy(dst, src, len)
__memcpy(dst, src, len)

[ memcpy ]
./boot/compressed/string.c:19:static inline void *memcpy(void *dest,
const void *src, size_t n)
./boot/compressed/string.c:29:void *memcpy(void *dest, const void
*src, size_t n)
./boot/compressed/string.c:4:void *memcpy(void *dest, const void *src, size_t n)
./boot/string.h:15: * do "undef memcpy" in .c file and link against
right string.c
./boot/string.h:19:#define memcpy(d,s,l) __builtin_memcpy(d,s,l)
./boot/string.h:5:#undef memcpy
./boot/string.h:9:void *memcpy(void *dst, const void *src, size_t len);
./include/asm/string_32.h:154:static inline void
*__constant_memcpy3d(void *to, const void *from, size_t len)
./include/asm/string_32.h:157:          return __constant_memcpy(to, from, len);
./include/asm/string_32.h:158:  return _mmx_memcpy(to, from, len);
./include/asm/string_32.h:161:static inline void *__memcpy3d(void *to,
const void *from, size_t len)
./include/asm/string_32.h:164:          return __memcpy(to, from, len);
./include/asm/string_32.h:165:  return _mmx_memcpy(to, from, len);
./include/asm/string_32.h:168:#define memcpy(t, f, n)
         \
./include/asm/string_32.h:170:   ? __constant_memcpy3d((t), (f), (n))   \
./include/asm/string_32.h:171:   : __memcpy3d((t), (f), (n)))
./include/asm/string_32.h:182:#define memcpy(t, f, n) __builtin_memcpy(t, f, n)
./include/asm/string_32.h:184:#define memcpy(t, f, n)
         \
./include/asm/string_32.h:186:   ? __constant_memcpy((t), (f), (n))     \
./include/asm/string_32.h:187:   : __memcpy((t), (f), (n)))
./include/asm/string_32.h:194:#define memcpy(t, f, n) __memcpy((t), (f), (n))
./include/asm/string_32.h:32:static __always_inline void
*__memcpy(void *to, const void *from, size_t n)
./include/asm/string_32.h:51:static __always_inline void
*__constant_memcpy(void *to, const void *from,
./include/asm/string_64.h:30:extern void *__memcpy(void *to, const
void *from, size_t len);
./include/asm/string_64.h:34:extern void *memcpy(void *to, const void
*from, size_t len);
./include/asm/string_64.h:36:#define memcpy(dst, src, len)
                         \
./include/asm/string_64.h:41:           __ret = __memcpy((dst), (src),
__len);          \
./include/asm/string_64.h:43:           __ret =
__builtin_memcpy((dst), (src), __len);  \
./include/asm/string_64.h:52:#define memcpy(dst, src, len)
__inline_memcpy((dst), (src), (len))
./include/asm/string_64.h:76:#undef memcpy
./include/asm/string_64.h:77:#define memcpy(dst, src, len)
__memcpy(dst, src, len)
./include/asm/string_64.h:9:static __always_inline void
*__inline_memcpy(void *to, const void *from, size_t n)
./lib/memcpy_64.S:44: * memcpy_erms() - enhanced fast string memcpy.
This is faster and

$ grep ^#undef -nr arch/x86 | egrep 'memcpy|memcmp|memset' | sort
arch/x86/boot/compressed/misc.c:101:#undef memcpy
arch/x86/boot/compressed/misc.c:108:#undef memset
arch/x86/boot/string.h:5:#undef memcpy
arch/x86/boot/string.h:6:#undef memset
arch/x86/boot/string.h:7:#undef memcmp
arch/x86/include/asm/string_64.h:76:#undef memcpy
arch/x86/kernel/x8664_ksyms_64.c:49:#undef memcpy
arch/x86/kernel/x8664_ksyms_64.c:50:#undef memset
arch/x86/lib/memcpy_32.c:4:#undef memcpy
arch/x86/lib/memcpy_32.c:5:#undef memset

[ / INVESTIGATIONS ]

View attachment "0026-Add-own-versions-of-memcpy-and-memset-for-compilatio.patch" of type "text/x-patch" (5364 bytes)

Powered by blists - more mailing lists