Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

rseq: Replace the original debug implementation

Just utilize the new infrastructure and put the original one to rest.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Reviewed-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Link: https://patch.msgid.link/20251027084307.212510692@linutronix.de

authored by

Thomas Gleixner and committed by
Ingo Molnar
f7ee1964 abc850e7

+12 -69
+12 -69
kernel/rseq.c
··· 475 475 476 476 #ifdef CONFIG_DEBUG_RSEQ 477 477 /* 478 - * Unsigned comparison will be true when ip >= start_ip, and when 479 - * ip < start_ip + post_commit_offset. 480 - */ 481 - static bool in_rseq_cs(unsigned long ip, struct rseq_cs *rseq_cs) 482 - { 483 - return ip - rseq_cs->start_ip < rseq_cs->post_commit_offset; 484 - } 485 - 486 - /* 487 - * If the rseq_cs field of 'struct rseq' contains a valid pointer to 488 - * user-space, copy 'struct rseq_cs' from user-space and validate its fields. 489 - */ 490 - static int rseq_get_rseq_cs(struct task_struct *t, struct rseq_cs *rseq_cs) 491 - { 492 - struct rseq __user *urseq = t->rseq.usrptr; 493 - struct rseq_cs __user *urseq_cs; 494 - u32 __user *usig; 495 - u64 ptr; 496 - u32 sig; 497 - int ret; 498 - 499 - if (get_user(ptr, &rseq->rseq_cs)) 500 - return -EFAULT; 501 - 502 - /* If the rseq_cs pointer is NULL, return a cleared struct rseq_cs. */ 503 - if (!ptr) { 504 - memset(rseq_cs, 0, sizeof(*rseq_cs)); 505 - return 0; 506 - } 507 - /* Check that the pointer value fits in the user-space process space. */ 508 - if (ptr >= TASK_SIZE) 509 - return -EINVAL; 510 - urseq_cs = (struct rseq_cs __user *)(unsigned long)ptr; 511 - if (copy_from_user(rseq_cs, urseq_cs, sizeof(*rseq_cs))) 512 - return -EFAULT; 513 - 514 - if (rseq_cs->start_ip >= TASK_SIZE || 515 - rseq_cs->start_ip + rseq_cs->post_commit_offset >= TASK_SIZE || 516 - rseq_cs->abort_ip >= TASK_SIZE || 517 - rseq_cs->version > 0) 518 - return -EINVAL; 519 - /* Check for overflow. */ 520 - if (rseq_cs->start_ip + rseq_cs->post_commit_offset < rseq_cs->start_ip) 521 - return -EINVAL; 522 - /* Ensure that abort_ip is not in the critical section. */ 523 - if (rseq_cs->abort_ip - rseq_cs->start_ip < rseq_cs->post_commit_offset) 524 - return -EINVAL; 525 - 526 - usig = (u32 __user *)(unsigned long)(rseq_cs->abort_ip - sizeof(u32)); 527 - ret = get_user(sig, usig); 528 - if (ret) 529 - return ret; 530 - 531 - if (current->rseq.sig != sig) { 532 - printk_ratelimited(KERN_WARNING 533 - "Possible attack attempt. Unexpected rseq signature 0x%x, expecting 0x%x (pid=%d, addr=%p).\n", 534 - sig, current->rseq.sig, current->pid, usig); 535 - return -EINVAL; 536 - } 537 - return 0; 538 - } 539 - 540 - /* 541 478 * Terminate the process if a syscall is issued within a restartable 542 479 * sequence. 543 480 */ 544 481 void rseq_syscall(struct pt_regs *regs) 545 482 { 546 - unsigned long ip = instruction_pointer(regs); 547 483 struct task_struct *t = current; 548 - struct rseq_cs rseq_cs; 484 + u64 csaddr; 549 485 550 - if (!t->rseq.usrptr) 486 + if (!t->rseq.event.has_rseq) 551 487 return; 552 - if (rseq_get_rseq_cs(t, &rseq_cs) || in_rseq_cs(ip, &rseq_cs)) 553 - force_sig(SIGSEGV); 488 + if (get_user(csaddr, &t->rseq.usrptr->rseq_cs)) 489 + goto fail; 490 + if (likely(!csaddr)) 491 + return; 492 + if (unlikely(csaddr >= TASK_SIZE)) 493 + goto fail; 494 + if (rseq_debug_update_user_cs(t, regs, csaddr)) 495 + return; 496 + fail: 497 + force_sig(SIGSEGV); 554 498 } 555 - 556 499 #endif 557 500 558 501 /*