| From foo@baz Wed Nov 21 19:20:53 CET 2018 |
| From: David Long <dave.long@linaro.org> |
| Date: Wed, 7 Nov 2018 11:43:59 -0500 |
| Subject: ARM: oabi-compat: copy semops using __copy_from_user() |
| To: stable@vger.kernel.org, Russell King - ARM Linux <linux@armlinux.org.uk>, Florian Fainelli <f.fainelli@gmail.com>, Tony Lindgren <tony@atomide.com>, Marc Zyngier <marc.zyngier@arm.com>, Mark Rutland <mark.rutland@arm.com> |
| Cc: Greg KH <gregkh@linuxfoundation.org>, Mark Brown <broonie@kernel.org> |
| Message-ID: <20181107164402.9380-22-dave.long@linaro.org> |
| |
| From: Russell King <rmk+kernel@armlinux.org.uk> |
| |
| Commit 8c8484a1c18e3231648f5ba7cc5ffb7fd70b3ca4 upstream. |
| |
| __get_user_error() is used as a fast accessor to make copying structure |
| members as efficient as possible. However, with software PAN and the |
| recent Spectre variant 1, the efficiency is reduced as these are no |
| longer fast accessors. |
| |
| In the case of software PAN, it has to switch the domain register around |
| each access, and with Spectre variant 1, it would have to repeat the |
| access_ok() check for each access. |
| |
| Rather than using __get_user_error() to copy each semops element member, |
| copy each semops element in full using __copy_from_user(). |
| |
| Acked-by: Mark Rutland <mark.rutland@arm.com> |
| Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> |
| Signed-off-by: David A. Long <dave.long@linaro.org> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| arch/arm/kernel/sys_oabi-compat.c | 8 +++++--- |
| 1 file changed, 5 insertions(+), 3 deletions(-) |
| |
| --- a/arch/arm/kernel/sys_oabi-compat.c |
| +++ b/arch/arm/kernel/sys_oabi-compat.c |
| @@ -328,9 +328,11 @@ asmlinkage long sys_oabi_semtimedop(int |
| return -ENOMEM; |
| err = 0; |
| for (i = 0; i < nsops; i++) { |
| - __get_user_error(sops[i].sem_num, &tsops->sem_num, err); |
| - __get_user_error(sops[i].sem_op, &tsops->sem_op, err); |
| - __get_user_error(sops[i].sem_flg, &tsops->sem_flg, err); |
| + struct oabi_sembuf osb; |
| + err |= __copy_from_user(&osb, tsops, sizeof(osb)); |
| + sops[i].sem_num = osb.sem_num; |
| + sops[i].sem_op = osb.sem_op; |
| + sops[i].sem_flg = osb.sem_flg; |
| tsops++; |
| } |
| if (timeout) { |