Skip to content

Commit 6f7630b

Browse files
committed
fortify: Capture __bos() results in const temp vars
In two recent run-time memcpy() bound checking bug reports (NFS[1] and JFS[2]), the _detection_ was working correctly (in the sense that the requested copy size was larger than the destination field size), but the _warning text_ was showing the destination field size as SIZE_MAX ("unknown size"). This should be impossible, since the detection function will explicitly give up if the destination field size is unknown. For example, the JFS warning was: memcpy: detected field-spanning write (size 132) of single field "ip->i_link" at fs/jfs/namei.c:950 (size 18446744073709551615) Other cases of this warning (e.g.[3]) have reported correctly, and the reproducer only happens under GCC (at least 10.2 and 12.1), so this currently appears to be a GCC bug. Explicitly capturing the __builtin_object_size() results in const temporary variables fixes the report. For example, the JFS reproducer now correctly reports the field size (128): memcpy: detected field-spanning write (size 132) of single field "ip->i_link" at fs/jfs/namei.c:950 (size 128) Examination of the .text delta (which is otherwise identical), shows the literal value used in the report changing: - mov $0xffffffffffffffff,%rcx + mov $0x80,%ecx [1] https://lore.kernel.org/lkml/Y0zEzZwhOxTDcBTB@codemonkey.org.uk/ [2] https://syzkaller.appspot.com/bug?id=23d613df5259b977dac1696bec77f61a85890e3d [3] https://lore.kernel.org/all/202210110948.26b43120-yujie.liu@intel.com/ Cc: "Dr. David Alan Gilbert" <linux@treblig.org> Cc: llvm@lists.linux.dev Cc: linux-hardening@vger.kernel.org Signed-off-by: Kees Cook <keescook@chromium.org>
1 parent 72c3ebe commit 6f7630b

File tree

1 file changed

+9
-4
lines changed

1 file changed

+9
-4
lines changed

include/linux/fortify-string.h

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -441,13 +441,18 @@ __FORTIFY_INLINE bool fortify_memcpy_chk(__kernel_size_t size,
441441

442442
#define __fortify_memcpy_chk(p, q, size, p_size, q_size, \
443443
p_size_field, q_size_field, op) ({ \
444-
size_t __fortify_size = (size_t)(size); \
445-
WARN_ONCE(fortify_memcpy_chk(__fortify_size, p_size, q_size, \
446-
p_size_field, q_size_field, #op), \
444+
const size_t __fortify_size = (size_t)(size); \
445+
const size_t __p_size = (p_size); \
446+
const size_t __q_size = (q_size); \
447+
const size_t __p_size_field = (p_size_field); \
448+
const size_t __q_size_field = (q_size_field); \
449+
WARN_ONCE(fortify_memcpy_chk(__fortify_size, __p_size, \
450+
__q_size, __p_size_field, \
451+
__q_size_field, #op), \
447452
#op ": detected field-spanning write (size %zu) of single %s (size %zu)\n", \
448453
__fortify_size, \
449454
"field \"" #p "\" at " __FILE__ ":" __stringify(__LINE__), \
450-
p_size_field); \
455+
__p_size_field); \
451456
__underlying_##op(p, q, __fortify_size); \
452457
})
453458

0 commit comments

Comments
 (0)