Skip to content

Commit 7797d17

Browse files
wildea01ctmarinas
authored andcommitted
arm64: ptrace: make structure padding explicit for debug registers
The user_hwdebug_state structure contains implicit padding to conform to the alignment requirements of the AArch64 ABI (namely that aggregates must be aligned to their most aligned member). This patch fixes the ptrace functions operating on struct user_hwdebug_state so that the padding is handled correctly. Signed-off-by: Will Deacon <will.deacon@arm.com> Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
1 parent 16dd46b commit 7797d17

File tree

2 files changed

+32
-7
lines changed

2 files changed

+32
-7
lines changed

arch/arm64/include/uapi/asm/ptrace.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,13 +79,14 @@ struct user_fpsimd_state {
7979

8080
struct user_hwdebug_state {
8181
__u32 dbg_info;
82+
__u32 pad;
8283
struct {
8384
__u64 addr;
8485
__u32 ctrl;
86+
__u32 pad;
8587
} dbg_regs[16];
8688
};
8789

88-
8990
#endif /* __ASSEMBLY__ */
9091

9192
#endif /* _UAPI__ASM_PTRACE_H */

arch/arm64/kernel/ptrace.c

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -372,15 +372,15 @@ static int ptrace_hbp_set_addr(unsigned int note_type,
372372

373373
#define PTRACE_HBP_ADDR_SZ sizeof(u64)
374374
#define PTRACE_HBP_CTRL_SZ sizeof(u32)
375-
#define PTRACE_HBP_REG_OFF sizeof(u32)
375+
#define PTRACE_HBP_PAD_SZ sizeof(u32)
376376

377377
static int hw_break_get(struct task_struct *target,
378378
const struct user_regset *regset,
379379
unsigned int pos, unsigned int count,
380380
void *kbuf, void __user *ubuf)
381381
{
382382
unsigned int note_type = regset->core_note_type;
383-
int ret, idx = 0, offset = PTRACE_HBP_REG_OFF, limit;
383+
int ret, idx = 0, offset, limit;
384384
u32 info, ctrl;
385385
u64 addr;
386386

@@ -389,11 +389,20 @@ static int hw_break_get(struct task_struct *target,
389389
if (ret)
390390
return ret;
391391

392-
ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, &info, 0, 4);
392+
ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, &info, 0,
393+
sizeof(info));
394+
if (ret)
395+
return ret;
396+
397+
/* Pad */
398+
offset = offsetof(struct user_hwdebug_state, pad);
399+
ret = user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf, offset,
400+
offset + PTRACE_HBP_PAD_SZ);
393401
if (ret)
394402
return ret;
395403

396404
/* (address, ctrl) registers */
405+
offset = offsetof(struct user_hwdebug_state, dbg_regs);
397406
limit = regset->n * regset->size;
398407
while (count && offset < limit) {
399408
ret = ptrace_hbp_get_addr(note_type, target, idx, &addr);
@@ -413,6 +422,13 @@ static int hw_break_get(struct task_struct *target,
413422
if (ret)
414423
return ret;
415424
offset += PTRACE_HBP_CTRL_SZ;
425+
426+
ret = user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf,
427+
offset,
428+
offset + PTRACE_HBP_PAD_SZ);
429+
if (ret)
430+
return ret;
431+
offset += PTRACE_HBP_PAD_SZ;
416432
idx++;
417433
}
418434

@@ -425,12 +441,13 @@ static int hw_break_set(struct task_struct *target,
425441
const void *kbuf, const void __user *ubuf)
426442
{
427443
unsigned int note_type = regset->core_note_type;
428-
int ret, idx = 0, offset = PTRACE_HBP_REG_OFF, limit;
444+
int ret, idx = 0, offset, limit;
429445
u32 ctrl;
430446
u64 addr;
431447

432-
/* Resource info */
433-
ret = user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf, 0, 4);
448+
/* Resource info and pad */
449+
offset = offsetof(struct user_hwdebug_state, dbg_regs);
450+
ret = user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf, 0, offset);
434451
if (ret)
435452
return ret;
436453

@@ -454,6 +471,13 @@ static int hw_break_set(struct task_struct *target,
454471
if (ret)
455472
return ret;
456473
offset += PTRACE_HBP_CTRL_SZ;
474+
475+
ret = user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf,
476+
offset,
477+
offset + PTRACE_HBP_PAD_SZ);
478+
if (ret)
479+
return ret;
480+
offset += PTRACE_HBP_PAD_SZ;
457481
idx++;
458482
}
459483

0 commit comments

Comments
 (0)