API Reference

Relevant source files

This page provides a comprehensive reference for the axptr library, which offers safe abstractions for accessing user-space memory from kernel code. The API is designed to prevent memory-related security vulnerabilities and crashes that can occur when kernel code interacts with potentially unsafe user memory.

For architectural concepts and safety mechanisms, refer to Memory Safety Architecture and Safety Mechanisms.

API Components Overview


Sources: src/lib.rs(L119 - L126)  src/lib.rs(L128 - L217)  src/lib.rs(L219 - L303)  src/lib.rs(L18 - L20) 

Core Types

UserPtr

UserPtr<T> is a wrapper around a raw mutable pointer (*mut T) to user-space memory. It provides safe methods to access and manipulate user memory with validation checks.

flowchart TD
A["Kernel Code"]
B["UserPtr"]
C["check_region()"]
D["Access Permission Check"]
E["Alignment Check"]
F["Page Table Population"]
G["User Memory"]

A --> B
B --> C
B --> G
C --> D
C --> E
C --> F

Sources: src/lib.rs(L128 - L217) 

Constants

ConstantTypeDescription
ACCESS_FLAGSMappingFlagsRead and write access flags for the pointer (MappingFlags::READ.union(MappingFlags::WRITE))

Sources: src/lib.rs(L137) 

Methods

MethodSignatureDescription
addressfn address(&self) -> VirtAddrReturns the virtual address of the pointer
as_ptrunsafe fn as_ptr(&self) -> *mut TUnwraps the pointer into a raw pointer (unsafe)
castfn cast(self) -> UserPtrCasts the pointer to a different type
is_nullfn is_null(&self) -> boolChecks if the pointer is null
nullablefn nullable(self) -> OptionConverts the pointer to anOption, returningNoneif null
getfn get(&mut self, aspace: impl AddrSpaceProvider) -> LinuxResult<&mut T>Safely accesses the value, validating the memory region
get_as_slicefn get_as_slice(&mut self, aspace: impl AddrSpaceProvider, length: usize) -> LinuxResult<&mut [T]>Gets the value as a slice of specified length
get_as_null_terminatedfn get_as_null_terminated(&mut self, aspace: impl AddrSpaceProvider) -> LinuxResult<&mut [T]>Gets the value as a slice terminated by a null value

Sources: src/lib.rs(L136 - L169)  src/lib.rs(L171 - L198)  src/lib.rs(L201 - L217) 

UserConstPtr

UserConstPtr<T> is a wrapper around a raw constant pointer (*const T) to user-space memory. It provides similar functionality to UserPtr<T> but for read-only access.

flowchart TD
A["Kernel Code"]
B["UserConstPtr"]
C["check_region()"]
D["Access Permission Check"]
E["Alignment Check"]
F["Page Table Population"]
G["User Memory (read-only)"]

A --> B
B --> C
B --> G
C --> D
C --> E
C --> F

Sources: src/lib.rs(L219 - L303) 

Constants

ConstantTypeDescription
ACCESS_FLAGSMappingFlagsRead-only access flags for the pointer (MappingFlags::READ)

Sources: src/lib.rs(L228) 

Methods

MethodSignatureDescription
addressfn address(&self) -> VirtAddrReturns the virtual address of the pointer
as_ptrunsafe fn as_ptr(&self) -> *const TUnwraps the pointer into a raw pointer (unsafe)
castfn cast(self) -> UserConstPtrCasts the pointer to a different type
is_nullfn is_null(&self) -> boolChecks if the pointer is null
nullablefn nullable(self) -> OptionConverts the pointer to anOption, returningNoneif null
getfn get(&self, aspace: impl AddrSpaceProvider) -> LinuxResult<&T>Safely accesses the value, validating the memory region
get_as_slicefn get_as_slice(&self, aspace: impl AddrSpaceProvider, length: usize) -> LinuxResult<&[T]>Gets the value as a slice of specified length
get_as_null_terminatedfn get_as_null_terminated(&self, aspace: impl AddrSpaceProvider) -> LinuxResult<&[T]>Gets the value as a slice terminated by a null value

Sources: src/lib.rs(L227 - L254)  src/lib.rs(L256 - L278)  src/lib.rs(L280 - L292) 

Special Methods for UserConstPtr<c_char>

UserConstPtr<c_char> has an additional method for working with strings:

MethodSignatureDescription
get_as_strfn get_as_str(&self, aspace: impl AddrSpaceProvider) -> LinuxResult<&'static str>Gets the pointer as a Rust string, validating UTF-8 encoding

Sources: src/lib.rs(L294 - L303) 

AddrSpaceProvider Trait

The AddrSpaceProvider trait is used to abstract the address space operations used by both pointer types. It provides a way to access the underlying address space.


Sources: src/lib.rs(L119 - L126) 

Methods

MethodSignatureDescription
with_addr_spacefn with_addr_space(&mut self, f: impl FnOnce(&mut AddrSpace) -> R) -> RProvides a reference to the address space for use with a callback function

Sources: src/lib.rs(L119 - L121) 

Helper Functions

The axptr library provides utility functions for working with user-space memory:

FunctionSignatureDescription
is_accessing_user_memoryfn is_accessing_user_memory() -> boolChecks if we are currently accessing user memory, used for page fault handling
access_user_memoryfn access_user_memory(f: impl FnOnce() -> R) -> RInternal function to set a flag during user memory access

Sources: src/lib.rs(L11 - L29) 

Memory Access Process

The diagram below illustrates the process that occurs when kernel code attempts to access user memory through the axptr API:

sequenceDiagram
    participant KernelCode as Kernel Code
    participant UserPtrUserConstPtr as UserPtr/UserConstPtr
    participant check_region as check_region()
    participant AddrSpace as AddrSpace
    participant UserMemory as User Memory

    KernelCode ->> UserPtrUserConstPtr: get(...)/get_as_slice(...)/etc.
    UserPtrUserConstPtr ->> check_region: check_region_with(...)
    check_region ->> AddrSpace: check_region_access
    check_region ->> AddrSpace: populate_area
    alt Region is valid
        AddrSpace -->> check_region: Ok(())
        check_region -->> UserPtrUserConstPtr: Ok(())
        UserPtrUserConstPtr ->> UserPtrUserConstPtr: access_user_memory(...)
        UserPtrUserConstPtr ->> UserMemory: Safe memory access
        UserMemory -->> UserPtrUserConstPtr: Data
        UserPtrUserConstPtr -->> KernelCode: Return reference/slice
    else Region is invalid or inaccessible
        AddrSpace -->> check_region: Err(EFAULT)
        check_region -->> UserPtrUserConstPtr: Err(EFAULT)
        UserPtrUserConstPtr -->> KernelCode: Return error
    end

Sources: src/lib.rs(L31 - L54)  src/lib.rs(L109 - L117)  src/lib.rs(L22 - L29) 

Type Conversion and Construction

Both UserPtr<T> and UserConstPtr<T> implement From<usize> for convenient construction from raw addresses:

flowchart TD
A["usize (memory address)"]
B["UserPtr"]
C["UserConstPtr"]

A --> B
A --> C

Sources: src/lib.rs(L130 - L134)  src/lib.rs(L221 - L225) 

Null-Terminated Data Handling

The library provides special handling for null-terminated data structures like C strings:

flowchart TD
A["UserPtr/UserConstPtr"]
B["get_as_null_terminated()"]
C["check_null_terminated()"]
D["traverse memory safely"]
E["find null terminator"]
F["return slice up to terminator"]
G["UserConstPtr"]
H["get_as_str()"]
I["get_as_null_terminated()"]
J["validate UTF-8"]
K["return &str"]

A --> B
B --> C
C --> D
D --> E
E --> F
G --> H
H --> I
I --> J
J --> K

Sources: src/lib.rs(L56 - L107)  src/lib.rs(L201 - L217)  src/lib.rs(L280 - L292)  src/lib.rs(L294 - L303)