Subject: bug#74501: Problem confirmed

From: "Danny Milosavljevic" <[email-masked]>
Date: Sun, 15 Dec 2024 01:52:46 +0100 (CET)

Hi,

I also have this problem on x86_64 znver3.

I disassembled my "Code:" block and I get:

8b 04 25 28 00 00 00    mov    eax, DWORD PTR ds:0x28
48 89 44 24 08          mov    QWORD PTR [rsp+0x8], rax
31 c0                   xor    eax, eax
e8 dc 2d f9 ff          call   <relative_address>
44 8b 28                mov    r13d, DWORD PTR [rax]
48 89 c5                mov    rbp, rax
e8 61 9e ff ff          call   <relative_address>
49 89 c4                mov    r12, rax
48 85 db                test   rbx, rbx
0f 84 e5 00 00 00       je     <forward_jump>
<44> 0f b7 0b           movzx  r9d, WORD PTR [rbx]         ; <-- This is where <44> is
66 41 83 f9 02          cmp    r9w, 0x2
0f 84 f6 00 00 00       je     <forward_jump>
66 41 83 f9 0a          cmp    r9w, 0xa
74 57                   je     <forward_jump>

The 0x44 byte in this instruction is part of the REX prefix that indicates the use of an extended register (r9d in this case).

The error code is a combination of several error bits defined in fault.c in the Linux kernel:

/*
 * Page fault error code bits:
 *
 *   bit 0 ==    0: no page found       1: protection fault
 *   bit 1 ==    0: read access         1: write access
 *   bit 2 ==    0: kernel-mode access  1: user-mode access
 *   bit 3 ==                           1: use of reserved bit detected
 *   bit 4 ==                           1: fault was an instruction fetch
 *   bit 5 ==                           1: protection keys block access
 *   bit 6 ==                           1: shadow stack access fault
 *   bit 15 =                           1: SGX MMU page-fault
 */
enum x86_pf_error_code {
        X86_PF_PROT     =               1 << 0,
        X86_PF_WRITE    =               1 << 1,
        X86_PF_USER     =               1 << 2,
        X86_PF_RSVD     =               1 << 3,
        X86_PF_INSTR    =               1 << 4,
        X86_PF_PK       =               1 << 5,
        X86_PF_SHSTK    =               1 << 6,
        X86_PF_SGX      =               1 << 15,
};

Since ntpd is a user-mode program, X86_PF_USER is set and the error code is at least 4.

If the error code is 4, then the faulty memory access is a read from user space.

In total:

- User-mode access.
- Read access.
- No page found.