Currently the keyctl helper makes silent assumption that either all expected arguments are being provided or otherwise it's somewhat safe to access beyond the actual va arg list. With AAPCS64-cap this will no longer slide through, as reading more arguments than provided will trigger capability bound fault. Empty va_list is another issue there (see KEYCTL_SESSION_TO_PARENT).
Introduce dedicated macro to handle the variadic-ness instead, making sure that at any point all arguments are being provided, whether explicitly or through default values.
Note that depicting number of arguments to be fetched from va_list based on provided command will not solve the problem as some (like KEYCTL_SEARCH) still allow optional ones.
Reported-by: Kevin Brodsky kevin.brodsky@arm.com Suggested-by: Kevin Brodsky kevin.brodsky@arm.com Signed-off-by: Beata Michalska beata.michalska@arm.com --- changes available at: https://git.morello-project.org/Bea/morello-linux-ltp/-/tree/morello/keyctl_...
v2: - define keyctl as macro so that the kectl users can remain unaware of the changes (thanks to @Tudor)
include/lapi/keyctl.h | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-)
diff --git a/include/lapi/keyctl.h b/include/lapi/keyctl.h index 9c847a429..97440e50a 100644 --- a/include/lapi/keyctl.h +++ b/include/lapi/keyctl.h @@ -39,22 +39,19 @@ static inline key_serial_t request_key(const char *type, type, description, callout_info, destringid); }
-static inline long keyctl(int cmd, ...) -{ - va_list va; - uintptr_t arg2, arg3, arg4, arg5; +#define __keyctl(cmd, arg2, arg3, arg4, arg5, ...) \ +({ \ + long result; \ + result = tst_syscall(__NR_keyctl, (cmd), (arg2), (arg3), (arg4), (arg5)); \ + result; \ +})
- va_start(va, cmd); - arg2 = va_arg(va, uintptr_t); - arg3 = va_arg(va, uintptr_t); - arg4 = va_arg(va, uintptr_t); - arg5 = va_arg(va, uintptr_t); - va_end(va); +#define keyctl(cmd, ...) \ + __keyctl((cmd), ##__VA_ARGS__, 0, 0, 0, 0)
- return tst_syscall(__NR_keyctl, cmd, arg2, arg3, arg4, arg5); -}
-static inline key_serial_t keyctl_join_session_keyring(const char *name) { +static inline key_serial_t keyctl_join_session_keyring(const char *name) +{ return keyctl(KEYCTL_JOIN_SESSION_KEYRING, name); }