diff options
Diffstat (limited to 'kernel/sys.c')
| -rw-r--r-- | kernel/sys.c | 28 | 
1 files changed, 28 insertions, 0 deletions
diff --git a/kernel/sys.c b/kernel/sys.c index ad692183dfe9..d1b2b8d934bb 100644 --- a/kernel/sys.c +++ b/kernel/sys.c @@ -61,6 +61,8 @@  #include <linux/uidgid.h>  #include <linux/cred.h> +#include <linux/nospec.h> +  #include <linux/kmsg_dump.h>  /* Move somewhere else to avoid recompiling? */  #include <generated/utsrelease.h> @@ -69,6 +71,9 @@  #include <asm/io.h>  #include <asm/unistd.h> +/* Hardening for Spectre-v1 */ +#include <linux/nospec.h> +  #include "uid16.h"  #ifndef SET_UNALIGN_CTL @@ -1451,6 +1456,7 @@ SYSCALL_DEFINE2(old_getrlimit, unsigned int, resource,  	if (resource >= RLIM_NLIMITS)  		return -EINVAL; +	resource = array_index_nospec(resource, RLIM_NLIMITS);  	task_lock(current->group_leader);  	x = current->signal->rlim[resource];  	task_unlock(current->group_leader); @@ -1470,6 +1476,7 @@ COMPAT_SYSCALL_DEFINE2(old_getrlimit, unsigned int, resource,  	if (resource >= RLIM_NLIMITS)  		return -EINVAL; +	resource = array_index_nospec(resource, RLIM_NLIMITS);  	task_lock(current->group_leader);  	r = current->signal->rlim[resource];  	task_unlock(current->group_leader); @@ -2242,6 +2249,17 @@ static int propagate_has_child_subreaper(struct task_struct *p, void *data)  	return 1;  } +int __weak arch_prctl_spec_ctrl_get(struct task_struct *t, unsigned long which) +{ +	return -EINVAL; +} + +int __weak arch_prctl_spec_ctrl_set(struct task_struct *t, unsigned long which, +				    unsigned long ctrl) +{ +	return -EINVAL; +} +  SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3,  		unsigned long, arg4, unsigned long, arg5)  { @@ -2450,6 +2468,16 @@ SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3,  	case PR_SVE_GET_VL:  		error = SVE_GET_VL();  		break; +	case PR_GET_SPECULATION_CTRL: +		if (arg3 || arg4 || arg5) +			return -EINVAL; +		error = arch_prctl_spec_ctrl_get(me, arg2); +		break; +	case PR_SET_SPECULATION_CTRL: +		if (arg4 || arg5) +			return -EINVAL; +		error = arch_prctl_spec_ctrl_set(me, arg2, arg3); +		break;  	default:  		error = -EINVAL;  		break;  | 
