Skip to content

Commit 2ab2ba4

Browse files
committed
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()
2 parents 583472e + 316f1f4 commit 2ab2ba4

File tree

3 files changed

+22
-13
lines changed

3 files changed

+22
-13
lines changed

arch/parisc/kernel/firmware.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1303,7 +1303,7 @@ static char iodc_dbuf[4096] __page_aligned_bss;
13031303
*/
13041304
int pdc_iodc_print(const unsigned char *str, unsigned count)
13051305
{
1306-
unsigned int i;
1306+
unsigned int i, found = 0;
13071307
unsigned long flags;
13081308

13091309
count = min_t(unsigned int, count, sizeof(iodc_dbuf));
@@ -1315,6 +1315,7 @@ int pdc_iodc_print(const unsigned char *str, unsigned count)
13151315
iodc_dbuf[i+0] = '\r';
13161316
iodc_dbuf[i+1] = '\n';
13171317
i += 2;
1318+
found = 1;
13181319
goto print;
13191320
default:
13201321
iodc_dbuf[i] = str[i];
@@ -1330,7 +1331,7 @@ int pdc_iodc_print(const unsigned char *str, unsigned count)
13301331
__pa(pdc_result), 0, __pa(iodc_dbuf), i, 0);
13311332
spin_unlock_irqrestore(&pdc_lock, flags);
13321333

1333-
return i;
1334+
return i - found;
13341335
}
13351336

13361337
#if !defined(BOOTLOADER)

arch/parisc/kernel/ptrace.c

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,12 @@ long arch_ptrace(struct task_struct *child, long request,
126126
unsigned long tmp;
127127
long ret = -EIO;
128128

129+
unsigned long user_regs_struct_size = sizeof(struct user_regs_struct);
130+
#ifdef CONFIG_64BIT
131+
if (is_compat_task())
132+
user_regs_struct_size /= 2;
133+
#endif
134+
129135
switch (request) {
130136

131137
/* 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,
166172
addr >= sizeof(struct pt_regs))
167173
break;
168174
if (addr == PT_IAOQ0 || addr == PT_IAOQ1) {
169-
data |= 3; /* ensure userspace privilege */
175+
data |= PRIV_USER; /* ensure userspace privilege */
170176
}
171177
if ((addr >= PT_GR1 && addr <= PT_GR31) ||
172178
addr == PT_IAOQ0 || addr == PT_IAOQ1 ||
@@ -181,14 +187,14 @@ long arch_ptrace(struct task_struct *child, long request,
181187
return copy_regset_to_user(child,
182188
task_user_regset_view(current),
183189
REGSET_GENERAL,
184-
0, sizeof(struct user_regs_struct),
190+
0, user_regs_struct_size,
185191
datap);
186192

187193
case PTRACE_SETREGS: /* Set all gp regs in the child. */
188194
return copy_regset_from_user(child,
189195
task_user_regset_view(current),
190196
REGSET_GENERAL,
191-
0, sizeof(struct user_regs_struct),
197+
0, user_regs_struct_size,
192198
datap);
193199

194200
case PTRACE_GETFPREGS: /* Get the child FPU state. */
@@ -285,7 +291,7 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
285291
if (addr >= sizeof(struct pt_regs))
286292
break;
287293
if (addr == PT_IAOQ0+4 || addr == PT_IAOQ1+4) {
288-
data |= 3; /* ensure userspace privilege */
294+
data |= PRIV_USER; /* ensure userspace privilege */
289295
}
290296
if (addr >= PT_FR0 && addr <= PT_FR31 + 4) {
291297
/* Special case, fp regs are 64 bits anyway */
@@ -302,6 +308,11 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
302308
}
303309
}
304310
break;
311+
case PTRACE_GETREGS:
312+
case PTRACE_SETREGS:
313+
case PTRACE_GETFPREGS:
314+
case PTRACE_SETFPREGS:
315+
return arch_ptrace(child, request, addr, data);
305316

306317
default:
307318
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)
484495
case RI(iaoq[0]):
485496
case RI(iaoq[1]):
486497
/* set 2 lowest bits to ensure userspace privilege: */
487-
regs->iaoq[num - RI(iaoq[0])] = val | 3;
498+
regs->iaoq[num - RI(iaoq[0])] = val | PRIV_USER;
488499
return;
489500
case RI(sar): regs->sar = val;
490501
return;

drivers/parisc/pdc_stable.c

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -274,8 +274,7 @@ pdcspath_hwpath_write(struct pdcspath_entry *entry, const char *buf, size_t coun
274274

275275
/* We'll use a local copy of buf */
276276
count = min_t(size_t, count, sizeof(in)-1);
277-
strncpy(in, buf, count);
278-
in[count] = '\0';
277+
strscpy(in, buf, count + 1);
279278

280279
/* Let's clean up the target. 0xff is a blank pattern */
281280
memset(&hwpath, 0xff, sizeof(hwpath));
@@ -388,8 +387,7 @@ pdcspath_layer_write(struct pdcspath_entry *entry, const char *buf, size_t count
388387

389388
/* We'll use a local copy of buf */
390389
count = min_t(size_t, count, sizeof(in)-1);
391-
strncpy(in, buf, count);
392-
in[count] = '\0';
390+
strscpy(in, buf, count + 1);
393391

394392
/* Let's clean up the target. 0 is a blank pattern */
395393
memset(&layers, 0, sizeof(layers));
@@ -756,8 +754,7 @@ static ssize_t pdcs_auto_write(struct kobject *kobj,
756754

757755
/* We'll use a local copy of buf */
758756
count = min_t(size_t, count, sizeof(in)-1);
759-
strncpy(in, buf, count);
760-
in[count] = '\0';
757+
strscpy(in, buf, count + 1);
761758

762759
/* Current flags are stored in primary boot path entry */
763760
pathentry = &pdcspath_entry_primary;

0 commit comments

Comments
 (0)