diff options
| author | Greg Kroah-Hartman <gregkh@google.com> | 2020-06-20 12:42:13 +0200 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@google.com> | 2020-06-20 12:42:13 +0200 |
| commit | 3cca95bd3790d6311b73b0b9af00d63c420f7041 (patch) | |
| tree | a0fbfca1975df344b0e2d41ad6c2b326916fb698 /arch/sparc | |
| parent | 21371e32fdb92398492f146e115b728eeb45beaf (diff) | |
| parent | ddb4a7b3a08a9a2867d9ca9d22f12d28e72b5075 (diff) | |
Merge 4.4.228 into android-4.4-p
Changes in 4.4.228
ipv6: fix IPV6_ADDRFORM operation logic
vxlan: Avoid infinite loop when suppressing NS messages with invalid options
scsi: return correct blkprep status code in case scsi_init_io() fails.
net: phy: marvell: Limit 88m1101 autoneg errata to 88E1145 as well.
pwm: fsl-ftm: Use flat regmap cache
igb: improve handling of disconnected adapters
ARM: 8977/1: ptrace: Fix mask for thumb breakpoint hook
sched/fair: Don't NUMA balance for kthreads
ath9k_htc: Silence undersized packet warnings
x86_64: Fix jiffies ODR violation
x86/speculation: Prevent rogue cross-process SSBD shutdown
x86/reboot/quirks: Add MacBook6,1 reboot quirk
efi/efivars: Add missing kobject_put() in sysfs entry creation error path
ALSA: es1688: Add the missed snd_card_free()
ALSA: usb-audio: Fix inconsistent card PM state after resume
ACPI: sysfs: Fix reference count leak in acpi_sysfs_add_hotplug_profile()
ACPI: PM: Avoid using power resources if there are none for D0
cgroup, blkcg: Prepare some symbols for module and !CONFIG_CGROUP usages
nilfs2: fix null pointer dereference at nilfs_segctor_do_construct()
spi: bcm2835aux: Fix controller unregister order
ALSA: pcm: disallow linking stream to itself
x86/speculation: Change misspelled STIPB to STIBP
x86/speculation: Add support for STIBP always-on preferred mode
x86/speculation: Avoid force-disabling IBPB based on STIBP and enhanced IBRS.
x86/speculation: PR_SPEC_FORCE_DISABLE enforcement for indirect branches.
spi: dw: fix possible race condition
spi: dw: Fix controller unregister order
spi: No need to assign dummy value in spi_unregister_controller()
spi: Fix controller unregister order
spi: pxa2xx: Fix controller unregister order
spi: bcm2835: Fix controller unregister order
ovl: initialize error in ovl_copy_xattr
proc: Use new_inode not new_inode_pseudo
video: fbdev: w100fb: Fix a potential double free.
KVM: nSVM: leave ASID aside in copy_vmcb_control_area
KVM: nVMX: Consult only the "basic" exit reason when routing nested exit
KVM: arm64: Make vcpu_cp1x() work on Big Endian hosts
ath9k: Fix use-after-free Read in ath9k_wmi_ctrl_rx
ath9k: Fix use-after-free Write in ath9k_htc_rx_msg
ath9x: Fix stack-out-of-bounds Write in ath9k_hif_usb_rx_cb
ath9k: Fix general protection fault in ath9k_hif_usb_rx_cb
Smack: slab-out-of-bounds in vsscanf
mm/slub: fix a memory leak in sysfs_slab_add()
fat: don't allow to mount if the FAT length == 0
can: kvaser_usb: kvaser_usb_leaf: Fix some info-leaks to USB devices
spi: dw: Zero DMA Tx and Rx configurations on stack
Bluetooth: Add SCO fallback for invalid LMP parameters error
kgdb: Prevent infinite recursive entries to the debugger
spi: dw: Enable interrupts in accordance with DMA xfer mode
clocksource: dw_apb_timer_of: Fix missing clockevent timers
btrfs: do not ignore error from btrfs_next_leaf() when inserting checksums
ARM: 8978/1: mm: make act_mm() respect THREAD_SIZE
net: vmxnet3: fix possible buffer overflow caused by bad DMA value in vmxnet3_get_rss()
staging: android: ion: use vmap instead of vm_map_ram
e1000: Distribute switch variables for initialization
media: dvb: return -EREMOTEIO on i2c transfer failure.
MIPS: Make sparse_init() using top-down allocation
netfilter: nft_nat: return EOPNOTSUPP if type or flags are not supported
lib/mpi: Fix 64-bit MIPS build with Clang
net: lpc-enet: fix error return code in lpc_mii_init()
net: allwinner: Fix use correct return type for ndo_start_xmit()
powerpc/spufs: fix copy_to_user while atomic
mips: cm: Fix an invalid error code of INTVN_*_ERR
kgdb: Fix spurious true from in_dbg_master()
md: don't flush workqueue unconditionally in md_open
mwifiex: Fix memory corruption in dump_station
mips: Add udelay lpj numbers adjustment
x86/mm: Stop printing BRK addresses
m68k: mac: Don't call via_flush_cache() on Mac IIfx
macvlan: Skip loopback packets in RX handler
PCI: Don't disable decoding when mmio_always_on is set
MIPS: Fix IRQ tracing when call handle_fpe() and handle_msa_fpe()
ixgbe: fix signed-integer-overflow warning
spi: dw: Return any value retrieved from the dma_transfer callback
cpuidle: Fix three reference count leaks
ima: Fix ima digest hash table key calculation
ext4: fix EXT_MAX_EXTENT/INDEX to check for zeroed eh_max
Btrfs: fix unreplayable log after snapshot delete + parent dir fsync
btrfs: send: emit file capabilities after chown
btrfs: fix error handling when submitting direct I/O bio
ima: Directly assign the ima_default_policy pointer to ima_rules
PCI: Program MPS for RCiEP devices
e1000e: Relax condition to trigger reset for ME workaround
carl9170: remove P2P_GO support
media: go7007: fix a miss of snd_card_free
b43legacy: Fix case where channel status is corrupted
b43: Fix connection problem with WPA3
b43_legacy: Fix connection problem with WPA3
igb: Report speed and duplex as unknown when device is runtime suspended
power: vexpress: add suppress_bind_attrs to true
pinctrl: samsung: Save/restore eint_mask over suspend for EINT_TYPE GPIOs
sparc32: fix register window handling in genregs32_[gs]et()
kernel/cpu_pm: Fix uninitted local in cpu_pm
ARM: tegra: Correct PL310 Auxiliary Control Register initialization
drivers/macintosh: Fix memleak in windfarm_pm112 driver
kbuild: force to build vmlinux if CONFIG_MODVERSION=y
sunrpc: svcauth_gss_register_pseudoflavor must reject duplicate registrations.
sunrpc: clean up properly in gss_mech_unregister()
w1: omap-hdq: cleanup to add missing newline for some dev_dbg
perf probe: Do not show the skipped events
perf symbols: Fix debuginfo search for Ubuntu
Linux 4.4.228
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
Change-Id: Ice915aaa684101ec7e774ccf43bfb533f84b4740
Diffstat (limited to 'arch/sparc')
| -rw-r--r-- | arch/sparc/kernel/ptrace_32.c | 228 |
1 files changed, 98 insertions, 130 deletions
diff --git a/arch/sparc/kernel/ptrace_32.c b/arch/sparc/kernel/ptrace_32.c index a331fdc11a2c..396dbdea0cfa 100644 --- a/arch/sparc/kernel/ptrace_32.c +++ b/arch/sparc/kernel/ptrace_32.c @@ -45,82 +45,79 @@ enum sparc_regset { REGSET_FP, }; +static int regwindow32_get(struct task_struct *target, + const struct pt_regs *regs, + u32 *uregs) +{ + unsigned long reg_window = regs->u_regs[UREG_I6]; + int size = 16 * sizeof(u32); + + if (target == current) { + if (copy_from_user(uregs, (void __user *)reg_window, size)) + return -EFAULT; + } else { + if (access_process_vm(target, reg_window, uregs, size, + FOLL_FORCE) != size) + return -EFAULT; + } + return 0; +} + +static int regwindow32_set(struct task_struct *target, + const struct pt_regs *regs, + u32 *uregs) +{ + unsigned long reg_window = regs->u_regs[UREG_I6]; + int size = 16 * sizeof(u32); + + if (target == current) { + if (copy_to_user((void __user *)reg_window, uregs, size)) + return -EFAULT; + } else { + if (access_process_vm(target, reg_window, uregs, size, + FOLL_FORCE | FOLL_WRITE) != size) + return -EFAULT; + } + return 0; +} + static int genregs32_get(struct task_struct *target, const struct user_regset *regset, unsigned int pos, unsigned int count, void *kbuf, void __user *ubuf) { const struct pt_regs *regs = target->thread.kregs; - unsigned long __user *reg_window; - unsigned long *k = kbuf; - unsigned long __user *u = ubuf; - unsigned long reg; + u32 uregs[16]; + int ret; if (target == current) flush_user_windows(); - pos /= sizeof(reg); - count /= sizeof(reg); - - if (kbuf) { - for (; count > 0 && pos < 16; count--) - *k++ = regs->u_regs[pos++]; - - reg_window = (unsigned long __user *) regs->u_regs[UREG_I6]; - reg_window -= 16; - for (; count > 0 && pos < 32; count--) { - if (get_user(*k++, ®_window[pos++])) - return -EFAULT; - } - } else { - for (; count > 0 && pos < 16; count--) { - if (put_user(regs->u_regs[pos++], u++)) - return -EFAULT; - } - - reg_window = (unsigned long __user *) regs->u_regs[UREG_I6]; - reg_window -= 16; - for (; count > 0 && pos < 32; count--) { - if (get_user(reg, ®_window[pos++]) || - put_user(reg, u++)) - return -EFAULT; - } - } - while (count > 0) { - switch (pos) { - case 32: /* PSR */ - reg = regs->psr; - break; - case 33: /* PC */ - reg = regs->pc; - break; - case 34: /* NPC */ - reg = regs->npc; - break; - case 35: /* Y */ - reg = regs->y; - break; - case 36: /* WIM */ - case 37: /* TBR */ - reg = 0; - break; - default: - goto finish; - } + ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, + regs->u_regs, + 0, 16 * sizeof(u32)); + if (ret || !count) + return ret; - if (kbuf) - *k++ = reg; - else if (put_user(reg, u++)) + if (pos < 32 * sizeof(u32)) { + if (regwindow32_get(target, regs, uregs)) return -EFAULT; - pos++; - count--; + ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, + uregs, + 16 * sizeof(u32), 32 * sizeof(u32)); + if (ret || !count) + return ret; } -finish: - pos *= sizeof(reg); - count *= sizeof(reg); - return user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf, - 38 * sizeof(reg), -1); + uregs[0] = regs->psr; + uregs[1] = regs->pc; + uregs[2] = regs->npc; + uregs[3] = regs->y; + uregs[4] = 0; /* WIM */ + uregs[5] = 0; /* TBR */ + return user_regset_copyout(&pos, &count, &kbuf, &ubuf, + uregs, + 32 * sizeof(u32), 38 * sizeof(u32)); } static int genregs32_set(struct task_struct *target, @@ -129,82 +126,53 @@ static int genregs32_set(struct task_struct *target, const void *kbuf, const void __user *ubuf) { struct pt_regs *regs = target->thread.kregs; - unsigned long __user *reg_window; - const unsigned long *k = kbuf; - const unsigned long __user *u = ubuf; - unsigned long reg; + u32 uregs[16]; + u32 psr; + int ret; if (target == current) flush_user_windows(); - pos /= sizeof(reg); - count /= sizeof(reg); - - if (kbuf) { - for (; count > 0 && pos < 16; count--) - regs->u_regs[pos++] = *k++; - - reg_window = (unsigned long __user *) regs->u_regs[UREG_I6]; - reg_window -= 16; - for (; count > 0 && pos < 32; count--) { - if (put_user(*k++, ®_window[pos++])) - return -EFAULT; - } - } else { - for (; count > 0 && pos < 16; count--) { - if (get_user(reg, u++)) - return -EFAULT; - regs->u_regs[pos++] = reg; - } - - reg_window = (unsigned long __user *) regs->u_regs[UREG_I6]; - reg_window -= 16; - for (; count > 0 && pos < 32; count--) { - if (get_user(reg, u++) || - put_user(reg, ®_window[pos++])) - return -EFAULT; - } - } - while (count > 0) { - unsigned long psr; + ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, + regs->u_regs, + 0, 16 * sizeof(u32)); + if (ret || !count) + return ret; - if (kbuf) - reg = *k++; - else if (get_user(reg, u++)) + if (pos < 32 * sizeof(u32)) { + if (regwindow32_get(target, regs, uregs)) return -EFAULT; - - switch (pos) { - case 32: /* PSR */ - psr = regs->psr; - psr &= ~(PSR_ICC | PSR_SYSCALL); - psr |= (reg & (PSR_ICC | PSR_SYSCALL)); - regs->psr = psr; - break; - case 33: /* PC */ - regs->pc = reg; - break; - case 34: /* NPC */ - regs->npc = reg; - break; - case 35: /* Y */ - regs->y = reg; - break; - case 36: /* WIM */ - case 37: /* TBR */ - break; - default: - goto finish; - } - - pos++; - count--; + ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, + uregs, + 16 * sizeof(u32), 32 * sizeof(u32)); + if (ret) + return ret; + if (regwindow32_set(target, regs, uregs)) + return -EFAULT; + if (!count) + return 0; } -finish: - pos *= sizeof(reg); - count *= sizeof(reg); - + ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, + &psr, + 32 * sizeof(u32), 33 * sizeof(u32)); + if (ret) + return ret; + regs->psr = (regs->psr & ~(PSR_ICC | PSR_SYSCALL)) | + (psr & (PSR_ICC | PSR_SYSCALL)); + if (!count) + return 0; + ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, + ®s->pc, + 33 * sizeof(u32), 34 * sizeof(u32)); + if (ret || !count) + return ret; + ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, + ®s->y, + 34 * sizeof(u32), 35 * sizeof(u32)); + if (ret || !count) + return ret; return user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf, - 38 * sizeof(reg), -1); + 35 * sizeof(u32), 38 * sizeof(u32)); } static int fpregs32_get(struct task_struct *target, |
