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()
Unified · Split
| @@ -1303,7 +1303,7 @@ static char iodc_dbuf[4096] __page_aligned_bss; · 1302 unmodified lines | |||
| 1303 | */ | 1303 | */ |
| 1304 | int pdc_iodc_print(const unsigned char *str, unsigned count) | 1304 | int pdc_iodc_print(const unsigned char *str, unsigned count) |
| 1305 | { | 1305 | { |
| 1306 | unsigned int i; | 1306 | unsigned int i, found = 0; |
| 1307 | unsigned long flags; | 1307 | unsigned long flags; |
| 1308 | 1308 | ||
| 1309 | count = min_t(unsigned int, count, sizeof(iodc_dbuf)); | 1309 | count = min_t(unsigned int, count, sizeof(iodc_dbuf)); |
| @@ -1315,6 +1315,7 @@ int pdc_iodc_print(const unsigned char *str, unsigned count) · 5 unmodified lines | |||
| 1315 | iodc_dbuf[i+0] = '\r'; | 1315 | iodc_dbuf[i+0] = '\r'; |
| 1316 | iodc_dbuf[i+1] = '\n'; | 1316 | iodc_dbuf[i+1] = '\n'; |
| 1317 | i += 2; | 1317 | i += 2; |
| 1318 | found = 1; | ||
| 1318 | goto print; | 1319 | goto print; |
| 1319 | default: | 1320 | default: |
| 1320 | iodc_dbuf[i] = str[i]; | 1321 | iodc_dbuf[i] = str[i]; |
| @@ -1330,7 +1331,7 @@ print: · 9 unmodified lines | |||
| 1330 | __pa(pdc_result), 0, __pa(iodc_dbuf), i, 0); | 1331 | __pa(pdc_result), 0, __pa(iodc_dbuf), i, 0); |
| 1331 | spin_unlock_irqrestore(&pdc_lock, flags); | 1332 | spin_unlock_irqrestore(&pdc_lock, flags); |
| 1332 | 1333 | ||
| 1333 | return i; | 1334 | return i - found; |
| 1334 | } | 1335 | } |
| 1335 | 1336 | ||
| 1336 | #if !defined(BOOTLOADER) | 1337 | #if !defined(BOOTLOADER) |
| @@ -126,6 +126,12 @@ long arch_ptrace(struct task_struct *child, long request, · 125 unmodified lines | |||
| 126 | unsigned long tmp; | 126 | unsigned long tmp; |
| 127 | long ret = -EIO; | 127 | long ret = -EIO; |
| 128 | 128 | ||
| 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 | |||
| 129 | switch (request) { | 135 | switch (request) { |
| 130 | 136 | ||
| 131 | /* Read the word at location addr in the USER area. For ptraced | 137 | /* 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, · 34 unmodified lines | |||
| 166 | addr >= sizeof(struct pt_regs)) | 172 | addr >= sizeof(struct pt_regs)) |
| 167 | break; | 173 | break; |
| 168 | if (addr == PT_IAOQ0 || addr == PT_IAOQ1) { | 174 | if (addr == PT_IAOQ0 || addr == PT_IAOQ1) { |
| 169 | data |= 3; /* ensure userspace privilege */ | 175 | data |= PRIV_USER; /* ensure userspace privilege */ |
| 170 | } | 176 | } |
| 171 | if ((addr >= PT_GR1 && addr <= PT_GR31) || | 177 | if ((addr >= PT_GR1 && addr <= PT_GR31) || |
| 172 | addr == PT_IAOQ0 || addr == PT_IAOQ1 || | 178 | addr == PT_IAOQ0 || addr == PT_IAOQ1 || |
| @@ -181,14 +187,14 @@ long arch_ptrace(struct task_struct *child, long request, · 8 unmodified lines | |||
| 181 | return copy_regset_to_user(child, | 187 | return copy_regset_to_user(child, |
| 182 | task_user_regset_view(current), | 188 | task_user_regset_view(current), |
| 183 | REGSET_GENERAL, | 189 | REGSET_GENERAL, |
| 184 | 0, sizeof(struct user_regs_struct), | 190 | 0, user_regs_struct_size, |
| 185 | datap); | 191 | datap); |
| 186 | 192 | ||
| 187 | case PTRACE_SETREGS: /* Set all gp regs in the child. */ | 193 | case PTRACE_SETREGS: /* Set all gp regs in the child. */ |
| 188 | return copy_regset_from_user(child, | 194 | return copy_regset_from_user(child, |
| 189 | task_user_regset_view(current), | 195 | task_user_regset_view(current), |
| 190 | REGSET_GENERAL, | 196 | REGSET_GENERAL, |
| 191 | 0, sizeof(struct user_regs_struct), | 197 | 0, user_regs_struct_size, |
| 192 | datap); | 198 | datap); |
| 193 | 199 | ||
| 194 | case PTRACE_GETFPREGS: /* Get the child FPU state. */ | 200 | case PTRACE_GETFPREGS: /* Get the child FPU state. */ |
| @@ -285,7 +291,7 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request, · 90 unmodified lines | |||
| 285 | if (addr >= sizeof(struct pt_regs)) | 291 | if (addr >= sizeof(struct pt_regs)) |
| 286 | break; | 292 | break; |
| 287 | if (addr == PT_IAOQ0+4 || addr == PT_IAOQ1+4) { | 293 | if (addr == PT_IAOQ0+4 || addr == PT_IAOQ1+4) { |
| 288 | data |= 3; /* ensure userspace privilege */ | 294 | data |= PRIV_USER; /* ensure userspace privilege */ |
| 289 | } | 295 | } |
| 290 | if (addr >= PT_FR0 && addr <= PT_FR31 + 4) { | 296 | if (addr >= PT_FR0 && addr <= PT_FR31 + 4) { |
| 291 | /* Special case, fp regs are 64 bits anyway */ | 297 | /* Special case, fp regs are 64 bits anyway */ |
| @@ -302,6 +308,11 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request, · 10 unmodified lines | |||
| 302 | } | 308 | } |
| 303 | } | 309 | } |
| 304 | break; | 310 | 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); | ||
| 305 | 316 | ||
| 306 | default: | 317 | default: |
| 307 | ret = compat_ptrace_request(child, request, addr, data); | 318 | 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) · 176 unmodified lines | |||
| 484 | case RI(iaoq[0]): | 495 | case RI(iaoq[0]): |
| 485 | case RI(iaoq[1]): | 496 | case RI(iaoq[1]): |
| 486 | /* set 2 lowest bits to ensure userspace privilege: */ | 497 | /* 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; |
| 488 | return; | 499 | return; |
| 489 | case RI(sar): regs->sar = val; | 500 | case RI(sar): regs->sar = val; |
| 490 | return; | 501 | return; |
| @@ -274,8 +274,7 @@ pdcspath_hwpath_write(struct pdcspath_entry *entry, const char *buf, size_t coun · 273 unmodified lines | |||
| 274 | 274 | ||
| 275 | /* We'll use a local copy of buf */ | 275 | /* We'll use a local copy of buf */ |
| 276 | count = min_t(size_t, count, sizeof(in)-1); | 276 | count = min_t(size_t, count, sizeof(in)-1); |
| 277 | strncpy(in, buf, count); | 277 | strscpy(in, buf, count + 1); |
| 278 | in[count] = '\0'; | ||
| 279 | 278 | ||
| 280 | /* Let's clean up the target. 0xff is a blank pattern */ | 279 | /* Let's clean up the target. 0xff is a blank pattern */ |
| 281 | memset(&hwpath, 0xff, sizeof(hwpath)); | 280 | memset(&hwpath, 0xff, sizeof(hwpath)); |
| @@ -388,8 +387,7 @@ pdcspath_layer_write(struct pdcspath_entry *entry, const char *buf, size_t count · 106 unmodified lines | |||
| 388 | 387 | ||
| 389 | /* We'll use a local copy of buf */ | 388 | /* We'll use a local copy of buf */ |
| 390 | count = min_t(size_t, count, sizeof(in)-1); | 389 | count = min_t(size_t, count, sizeof(in)-1); |
| 391 | strncpy(in, buf, count); | 390 | strscpy(in, buf, count + 1); |
| 392 | in[count] = '\0'; | ||
| 393 | 391 | ||
| 394 | /* Let's clean up the target. 0 is a blank pattern */ | 392 | /* Let's clean up the target. 0 is a blank pattern */ |
| 395 | memset(&layers, 0, sizeof(layers)); | 393 | memset(&layers, 0, sizeof(layers)); |
| @@ -756,8 +754,7 @@ static ssize_t pdcs_auto_write(struct kobject *kobj, · 360 unmodified lines | |||
| 756 | 754 | ||
| 757 | /* We'll use a local copy of buf */ | 755 | /* We'll use a local copy of buf */ |
| 758 | count = min_t(size_t, count, sizeof(in)-1); | 756 | count = min_t(size_t, count, sizeof(in)-1); |
| 759 | strncpy(in, buf, count); | 757 | strscpy(in, buf, count + 1); |
| 760 | in[count] = '\0'; | ||
| 761 | 758 | ||
| 762 | /* Current flags are stored in primary boot path entry */ | 759 | /* Current flags are stored in primary boot path entry */ |
| 763 | pathentry = &pdcspath_entry_primary; | 760 | pathentry = &pdcspath_entry_primary; |