2018-12-07 18:39:28 +00:00
// SPDX-License-Identifier: GPL-2.0
2020-10-13 22:24:30 -07:00
# include <linux/compat.h>
2018-12-07 18:39:28 +00:00
# include <linux/errno.h>
# include <linux/prctl.h>
# include <linux/random.h>
# include <linux/sched.h>
# include <asm/cpufeature.h>
# include <asm/pointer_auth.h>
int ptrauth_prctl_reset_keys ( struct task_struct * tsk , unsigned long arg )
{
2020-03-13 14:34:50 +05:30
struct ptrauth_keys_user * keys = & tsk - > thread . keys_user ;
2018-12-07 18:39:28 +00:00
unsigned long addr_key_mask = PR_PAC_APIAKEY | PR_PAC_APIBKEY |
PR_PAC_APDAKEY | PR_PAC_APDBKEY ;
unsigned long key_mask = addr_key_mask | PR_PAC_APGAKEY ;
if ( ! system_supports_address_auth ( ) & & ! system_supports_generic_auth ( ) )
return - EINVAL ;
2020-10-13 22:24:30 -07:00
if ( is_compat_thread ( task_thread_info ( tsk ) ) )
return - EINVAL ;
2018-12-07 18:39:28 +00:00
if ( ! arg ) {
2020-03-13 14:34:50 +05:30
ptrauth_keys_init_user ( keys ) ;
2018-12-07 18:39:28 +00:00
return 0 ;
}
if ( arg & ~ key_mask )
return - EINVAL ;
if ( ( ( arg & addr_key_mask ) & & ! system_supports_address_auth ( ) ) | |
( ( arg & PR_PAC_APGAKEY ) & & ! system_supports_generic_auth ( ) ) )
return - EINVAL ;
if ( arg & PR_PAC_APIAKEY )
get_random_bytes ( & keys - > apia , sizeof ( keys - > apia ) ) ;
if ( arg & PR_PAC_APIBKEY )
get_random_bytes ( & keys - > apib , sizeof ( keys - > apib ) ) ;
if ( arg & PR_PAC_APDAKEY )
get_random_bytes ( & keys - > apda , sizeof ( keys - > apda ) ) ;
if ( arg & PR_PAC_APDBKEY )
get_random_bytes ( & keys - > apdb , sizeof ( keys - > apdb ) ) ;
if ( arg & PR_PAC_APGAKEY )
get_random_bytes ( & keys - > apga , sizeof ( keys - > apga ) ) ;
return 0 ;
}