Commit 2ab2ba49 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'parisc-for-6.2-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/deller/parisc-linux

Pull parisc architecture fixes from Helge Deller:

 - Fix PTRACE_GETREGS/PTRACE_SETREGS for 32-bit userspace on a 64-bit
   kernel

 - pdc_iodc_print() dropped chars for newline in strings

 - Drop constants in favour of PRIV_USER

 - use safer strscpy() function in pdc_stable driver

* tag 'parisc-for-6.2-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/deller/parisc-linux:
  parisc: Wire up PTRACE_GETREGS/PTRACE_SETREGS for compat case
  parisc: Replace hardcoded value with PRIV_USER constant in ptrace.c
  parisc: Fix return code of pdc_iodc_print()
  parisc: pdc_stable: use strscpy() to instead of strncpy()
parents 583472ef 316f1f42
...@@ -1303,7 +1303,7 @@ static char iodc_dbuf[4096] __page_aligned_bss; ...@@ -1303,7 +1303,7 @@ static char iodc_dbuf[4096] __page_aligned_bss;
*/ */
int pdc_iodc_print(const unsigned char *str, unsigned count) int pdc_iodc_print(const unsigned char *str, unsigned count)
{ {
unsigned int i; unsigned int i, found = 0;
unsigned long flags; unsigned long flags;
count = min_t(unsigned int, count, sizeof(iodc_dbuf)); count = min_t(unsigned int, count, sizeof(iodc_dbuf));
...@@ -1315,6 +1315,7 @@ int pdc_iodc_print(const unsigned char *str, unsigned count) ...@@ -1315,6 +1315,7 @@ int pdc_iodc_print(const unsigned char *str, unsigned count)
iodc_dbuf[i+0] = '\r'; iodc_dbuf[i+0] = '\r';
iodc_dbuf[i+1] = '\n'; iodc_dbuf[i+1] = '\n';
i += 2; i += 2;
found = 1;
goto print; goto print;
default: default:
iodc_dbuf[i] = str[i]; iodc_dbuf[i] = str[i];
...@@ -1330,7 +1331,7 @@ int pdc_iodc_print(const unsigned char *str, unsigned count) ...@@ -1330,7 +1331,7 @@ int pdc_iodc_print(const unsigned char *str, unsigned count)
__pa(pdc_result), 0, __pa(iodc_dbuf), i, 0); __pa(pdc_result), 0, __pa(iodc_dbuf), i, 0);
spin_unlock_irqrestore(&pdc_lock, flags); spin_unlock_irqrestore(&pdc_lock, flags);
return i; return i - found;
} }
#if !defined(BOOTLOADER) #if !defined(BOOTLOADER)
......
...@@ -126,6 +126,12 @@ long arch_ptrace(struct task_struct *child, long request, ...@@ -126,6 +126,12 @@ long arch_ptrace(struct task_struct *child, long request,
unsigned long tmp; unsigned long tmp;
long ret = -EIO; long ret = -EIO;
unsigned long user_regs_struct_size = sizeof(struct user_regs_struct);
#ifdef CONFIG_64BIT
if (is_compat_task())
user_regs_struct_size /= 2;
#endif
switch (request) { switch (request) {
/* Read the word at location addr in the USER area. For ptraced /* Read the word at location addr in the USER area. For ptraced
...@@ -166,7 +172,7 @@ long arch_ptrace(struct task_struct *child, long request, ...@@ -166,7 +172,7 @@ long arch_ptrace(struct task_struct *child, long request,
addr >= sizeof(struct pt_regs)) addr >= sizeof(struct pt_regs))
break; break;
if (addr == PT_IAOQ0 || addr == PT_IAOQ1) { if (addr == PT_IAOQ0 || addr == PT_IAOQ1) {
data |= 3; /* ensure userspace privilege */ data |= PRIV_USER; /* ensure userspace privilege */
} }
if ((addr >= PT_GR1 && addr <= PT_GR31) || if ((addr >= PT_GR1 && addr <= PT_GR31) ||
addr == PT_IAOQ0 || addr == PT_IAOQ1 || addr == PT_IAOQ0 || addr == PT_IAOQ1 ||
...@@ -181,14 +187,14 @@ long arch_ptrace(struct task_struct *child, long request, ...@@ -181,14 +187,14 @@ long arch_ptrace(struct task_struct *child, long request,
return copy_regset_to_user(child, return copy_regset_to_user(child,
task_user_regset_view(current), task_user_regset_view(current),
REGSET_GENERAL, REGSET_GENERAL,
0, sizeof(struct user_regs_struct), 0, user_regs_struct_size,
datap); datap);
case PTRACE_SETREGS: /* Set all gp regs in the child. */ case PTRACE_SETREGS: /* Set all gp regs in the child. */
return copy_regset_from_user(child, return copy_regset_from_user(child,
task_user_regset_view(current), task_user_regset_view(current),
REGSET_GENERAL, REGSET_GENERAL,
0, sizeof(struct user_regs_struct), 0, user_regs_struct_size,
datap); datap);
case PTRACE_GETFPREGS: /* Get the child FPU state. */ case PTRACE_GETFPREGS: /* Get the child FPU state. */
...@@ -285,7 +291,7 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request, ...@@ -285,7 +291,7 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
if (addr >= sizeof(struct pt_regs)) if (addr >= sizeof(struct pt_regs))
break; break;
if (addr == PT_IAOQ0+4 || addr == PT_IAOQ1+4) { if (addr == PT_IAOQ0+4 || addr == PT_IAOQ1+4) {
data |= 3; /* ensure userspace privilege */ data |= PRIV_USER; /* ensure userspace privilege */
} }
if (addr >= PT_FR0 && addr <= PT_FR31 + 4) { if (addr >= PT_FR0 && addr <= PT_FR31 + 4) {
/* Special case, fp regs are 64 bits anyway */ /* Special case, fp regs are 64 bits anyway */
...@@ -302,6 +308,11 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request, ...@@ -302,6 +308,11 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
} }
} }
break; break;
case PTRACE_GETREGS:
case PTRACE_SETREGS:
case PTRACE_GETFPREGS:
case PTRACE_SETFPREGS:
return arch_ptrace(child, request, addr, data);
default: default:
ret = compat_ptrace_request(child, request, addr, data); ret = compat_ptrace_request(child, request, addr, data);
...@@ -484,7 +495,7 @@ static void set_reg(struct pt_regs *regs, int num, unsigned long val) ...@@ -484,7 +495,7 @@ static void set_reg(struct pt_regs *regs, int num, unsigned long val)
case RI(iaoq[0]): case RI(iaoq[0]):
case RI(iaoq[1]): case RI(iaoq[1]):
/* set 2 lowest bits to ensure userspace privilege: */ /* set 2 lowest bits to ensure userspace privilege: */
regs->iaoq[num - RI(iaoq[0])] = val | 3; regs->iaoq[num - RI(iaoq[0])] = val | PRIV_USER;
return; return;
case RI(sar): regs->sar = val; case RI(sar): regs->sar = val;
return; return;
......
...@@ -274,8 +274,7 @@ pdcspath_hwpath_write(struct pdcspath_entry *entry, const char *buf, size_t coun ...@@ -274,8 +274,7 @@ pdcspath_hwpath_write(struct pdcspath_entry *entry, const char *buf, size_t coun
/* We'll use a local copy of buf */ /* We'll use a local copy of buf */
count = min_t(size_t, count, sizeof(in)-1); count = min_t(size_t, count, sizeof(in)-1);
strncpy(in, buf, count); strscpy(in, buf, count + 1);
in[count] = '\0';
/* Let's clean up the target. 0xff is a blank pattern */ /* Let's clean up the target. 0xff is a blank pattern */
memset(&hwpath, 0xff, sizeof(hwpath)); memset(&hwpath, 0xff, sizeof(hwpath));
...@@ -388,8 +387,7 @@ pdcspath_layer_write(struct pdcspath_entry *entry, const char *buf, size_t count ...@@ -388,8 +387,7 @@ pdcspath_layer_write(struct pdcspath_entry *entry, const char *buf, size_t count
/* We'll use a local copy of buf */ /* We'll use a local copy of buf */
count = min_t(size_t, count, sizeof(in)-1); count = min_t(size_t, count, sizeof(in)-1);
strncpy(in, buf, count); strscpy(in, buf, count + 1);
in[count] = '\0';
/* Let's clean up the target. 0 is a blank pattern */ /* Let's clean up the target. 0 is a blank pattern */
memset(&layers, 0, sizeof(layers)); memset(&layers, 0, sizeof(layers));
...@@ -756,8 +754,7 @@ static ssize_t pdcs_auto_write(struct kobject *kobj, ...@@ -756,8 +754,7 @@ static ssize_t pdcs_auto_write(struct kobject *kobj,
/* We'll use a local copy of buf */ /* We'll use a local copy of buf */
count = min_t(size_t, count, sizeof(in)-1); count = min_t(size_t, count, sizeof(in)-1);
strncpy(in, buf, count); strscpy(in, buf, count + 1);
in[count] = '\0';
/* Current flags are stored in primary boot path entry */ /* Current flags are stored in primary boot path entry */
pathentry = &pdcspath_entry_primary; pathentry = &pdcspath_entry_primary;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment