I received a bug report about the ruby test-suite failing on AArch64 when attempting to pass MAX_ARG_STRLEN sized args to execv[1]. It was expecting an E2BIG returned, but instead was receiving ENOMEM, and concatenating the argument strings in funky ways.
The problem appeared to be in __strnlen_user on arm64, as when instrumenting fs/exec.c to compare the results of the asm-generic strnlen_user, I noticed an off-by-one on the result: long-param-test: optimized strnlen_user (131072) and naive (131073) disagree! As a result, fix strnlen_user to match expected behaviour as documented in lib/strnlen_user.c, and return count+1 when count would be exceeded. I didn't feel comfortable prodding the assembler, so I just worked around it in the wrapper. Signed-off-by: Kyle McMartin <k...@redhat.com> 1. https://bugzilla.redhat.com/show_bug.cgi?id=1038676 --- I tested that this behaves the same as the lib/strnlen_user.c version with some hacked together code here: http://kyle.fedorapeople.org/strnlen_user-test.tar.xz {master}kmcmarti ~/strnlen_user-test $ ./test === count = 0 === strnlen_user = 0 __strnlen_user = 0 fixed__strnlen_user = 0 === count < strlen === strnlen_user = 7 __strnlen_user = 6 fixed__strnlen_user = 7 === count = strlen === strnlen_user = 13 __strnlen_user = 12 fixed__strnlen_user = 13 === count > strlen === strnlen_user = 13 __strnlen_user = 13 fixed__strnlen_user = 13 --- a/arch/arm64/include/asm/uaccess.h +++ b/arch/arm64/include/asm/uaccess.h @@ -290,9 +290,15 @@ static inline long __must_check strnlen_user(const char __user *s, long n) { unsigned long res = 0; + if (unlikely(n <= 0)) + return 0; + if (__addr_ok(s)) res = __strnlen_user(s, n); + if (unlikely(res >= n)) + return n + 1; + return res; } -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/