summaryrefslogtreecommitdiff
path: root/arch/parisc/kernel/ptrace.c
diff options
context:
space:
mode:
authorMarcel Ziswiler <marcel.ziswiler@toradex.com>2020-05-19 23:01:26 +0200
committerMarcel Ziswiler <marcel.ziswiler@toradex.com>2020-05-19 23:37:01 +0200
commit2ae782ca839e0ee07de37122ddea362adff2e975 (patch)
treedf6b1a190760f51465122ca4c13492d5ac5984c6 /arch/parisc/kernel/ptrace.c
parent0a8ab17689e628c84a666195bfc6ab85d11cf057 (diff)
parent0661b3d6cfd774e28a2e2ba90a3d87479e5c399b (diff)
Merge tag 'v4.9.220' into 4.9-2.3.x-imx
This is the 4.9.220 stable release Conflicts: arch/arm/Kconfig.debug arch/arm/boot/dts/imx7s.dtsi arch/arm/mach-imx/common.h arch/arm/mach-imx/cpuidle-imx6q.c arch/arm/mach-imx/cpuidle-imx6sx.c arch/arm/mach-imx/suspend-imx6.S block/blk-core.c drivers/crypto/caam/caamalg.c drivers/crypto/mxs-dcp.c drivers/dma/imx-sdma.c drivers/gpu/drm/bridge/adv7511/adv7511_drv.c drivers/input/keyboard/imx_keypad.c drivers/input/keyboard/snvs_pwrkey.c drivers/mmc/host/sdhci.c drivers/net/can/flexcan.c drivers/net/ethernet/freescale/fec_main.c drivers/net/phy/phy_device.c drivers/net/wireless/ath/ath10k/pci.c drivers/tty/serial/imx.c drivers/usb/dwc3/gadget.c drivers/usb/host/xhci.c include/linux/blkdev.h include/linux/cpu.h include/linux/platform_data/dma-imx-sdma.h kernel/cpu.c net/wireless/util.c sound/soc/fsl/Kconfig sound/soc/fsl/fsl_esai.c sound/soc/fsl/fsl_sai.c sound/soc/fsl/imx-sgtl5000.c
Diffstat (limited to 'arch/parisc/kernel/ptrace.c')
-rw-r--r--arch/parisc/kernel/ptrace.c31
1 files changed, 20 insertions, 11 deletions
diff --git a/arch/parisc/kernel/ptrace.c b/arch/parisc/kernel/ptrace.c
index 0780c375fe2e..e204fc49517d 100644
--- a/arch/parisc/kernel/ptrace.c
+++ b/arch/parisc/kernel/ptrace.c
@@ -170,6 +170,9 @@ long arch_ptrace(struct task_struct *child, long request,
if ((addr & (sizeof(unsigned long)-1)) ||
addr >= sizeof(struct pt_regs))
break;
+ if (addr == PT_IAOQ0 || addr == PT_IAOQ1) {
+ data |= 3; /* ensure userspace privilege */
+ }
if ((addr >= PT_GR1 && addr <= PT_GR31) ||
addr == PT_IAOQ0 || addr == PT_IAOQ1 ||
(addr >= PT_FR0 && addr <= PT_FR31 + 4) ||
@@ -231,16 +234,18 @@ long arch_ptrace(struct task_struct *child, long request,
static compat_ulong_t translate_usr_offset(compat_ulong_t offset)
{
- if (offset < 0)
- return sizeof(struct pt_regs);
- else if (offset <= 32*4) /* gr[0..31] */
- return offset * 2 + 4;
- else if (offset <= 32*4+32*8) /* gr[0..31] + fr[0..31] */
- return offset + 32*4;
- else if (offset < sizeof(struct pt_regs)/2 + 32*4)
- return offset * 2 + 4 - 32*8;
+ compat_ulong_t pos;
+
+ if (offset < 32*4) /* gr[0..31] */
+ pos = offset * 2 + 4;
+ else if (offset < 32*4+32*8) /* fr[0] ... fr[31] */
+ pos = (offset - 32*4) + PT_FR0;
+ else if (offset < sizeof(struct pt_regs)/2 + 32*4) /* sr[0] ... ipsw */
+ pos = (offset - 32*4 - 32*8) * 2 + PT_SR0 + 4;
else
- return sizeof(struct pt_regs);
+ pos = sizeof(struct pt_regs);
+
+ return pos;
}
long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
@@ -284,9 +289,12 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
addr = translate_usr_offset(addr);
if (addr >= sizeof(struct pt_regs))
break;
+ if (addr == PT_IAOQ0+4 || addr == PT_IAOQ1+4) {
+ data |= 3; /* ensure userspace privilege */
+ }
if (addr >= PT_FR0 && addr <= PT_FR31 + 4) {
/* Special case, fp regs are 64 bits anyway */
- *(__u64 *) ((char *) task_regs(child) + addr) = data;
+ *(__u32 *) ((char *) task_regs(child) + addr) = data;
ret = 0;
}
else if ((addr >= PT_GR1+4 && addr <= PT_GR31+4) ||
@@ -499,7 +507,8 @@ static void set_reg(struct pt_regs *regs, int num, unsigned long val)
return;
case RI(iaoq[0]):
case RI(iaoq[1]):
- regs->iaoq[num - RI(iaoq[0])] = val;
+ /* set 2 lowest bits to ensure userspace privilege: */
+ regs->iaoq[num - RI(iaoq[0])] = val | 3;
return;
case RI(sar): regs->sar = val;
return;