Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions capi/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
Unreleased
----------
- Added `kaslr_offset` member to `blaze_symbolize_src_kernel`


0.1.8
-----
- Added `blaze_symbolizer_opts::process_dispatch` providing process
Expand Down
19 changes: 18 additions & 1 deletion capi/include/blazesym.h
Original file line number Diff line number Diff line change
Expand Up @@ -1002,7 +1002,24 @@ typedef struct blaze_symbolize_src_kernel {
* Unused member available for future expansion. Must be initialized
* to zero.
*/
uint8_t reserved[23];
uint8_t _reserved1[7];
/**
* The KASLR offset to use.
*
* When `NULL`, the library will attempt to deduce the offset
* itself. Otherwise, the value pointed to is taken as the offset
* verbatim.
*
* Note that this value only has relevance when a `vmlinux` file is
* used for symbolization, because `kallsyms` based data already
* includes randomization adjusted addresses.
*/
const uint64_t *kaslr_offset;
/**
* Unused member available for future expansion. Must be initialized
* to zero.
*/
uint8_t reserved[8];
} blaze_symbolize_src_kernel;

/**
Expand Down
76 changes: 72 additions & 4 deletions capi/src/symbolize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,20 @@ pub struct blaze_symbolize_src_kernel {
pub debug_syms: bool,
/// Unused member available for future expansion. Must be initialized
/// to zero.
pub reserved: [u8; 23],
pub _reserved1: [u8; 7],
/// The KASLR offset to use.
///
/// When `NULL`, the library will attempt to deduce the offset
/// itself. Otherwise, the value pointed to is taken as the offset
/// verbatim.
///
/// Note that this value only has relevance when a `vmlinux` file is
/// used for symbolization, because `kallsyms` based data already
/// includes randomization adjusted addresses.
pub kaslr_offset: *const u64,
/// Unused member available for future expansion. Must be initialized
/// to zero.
pub reserved: [u8; 8],
}

impl Default for blaze_symbolize_src_kernel {
Expand All @@ -251,7 +264,9 @@ impl Default for blaze_symbolize_src_kernel {
kallsyms: ptr::null(),
vmlinux: ptr::null(),
debug_syms: false,
reserved: [0; 23],
_reserved1: [0; 7],
kaslr_offset: ptr::null(),
reserved: [0; 8],
}
}
}
Expand All @@ -276,12 +291,19 @@ impl From<blaze_symbolize_src_kernel> for Kernel {
kallsyms,
vmlinux,
debug_syms,
_reserved1: _,
kaslr_offset,
reserved: _,
} = kernel;
let kaslr_offset = if kaslr_offset.is_null() {
None
} else {
Some(unsafe { *kaslr_offset })
};
Self {
kallsyms: to_maybe_path(kallsyms),
vmlinux: to_maybe_path(vmlinux),
kaslr_offset: None,
kaslr_offset,
debug_syms,
_non_exhaustive: (),
}
Expand Down Expand Up @@ -1467,7 +1489,7 @@ mod tests {
};
assert_eq!(
format!("{kernel:?}"),
"blaze_symbolize_src_kernel { type_size: 32, kallsyms: 0x0, vmlinux: 0x0, debug_syms: true, reserved: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] }"
"blaze_symbolize_src_kernel { type_size: 32, kallsyms: 0x0, vmlinux: 0x0, debug_syms: true, _reserved1: [0, 0, 0, 0, 0, 0, 0], kaslr_offset: 0x0, reserved: [0, 0, 0, 0, 0, 0, 0, 0] }"
);

let process = blaze_symbolize_src_process {
Expand Down Expand Up @@ -1593,6 +1615,7 @@ mod tests {
let kernel = Kernel::from(kernel);
assert_eq!(kernel.kallsyms, MaybeDefault::Default);
assert_eq!(kernel.vmlinux, MaybeDefault::Default);
assert_eq!(kernel.kaslr_offset, None);

let kernel = blaze_symbolize_src_kernel {
kallsyms: b"\0" as *const _ as *const c_char,
Expand All @@ -1619,6 +1642,14 @@ mod tests {
kernel.vmlinux,
MaybeDefault::Some(PathBuf::from("/boot/vmlinux"))
);

let offset = 0x1234u64;
let kernel = blaze_symbolize_src_kernel {
kaslr_offset: &offset,
..Default::default()
};
let kernel = Kernel::from(kernel);
assert_eq!(kernel.kaslr_offset, Some(0x1234));
}

/// Check that we can convert a [`blaze_cache_src_process`] into a
Expand Down Expand Up @@ -2253,6 +2284,43 @@ mod tests {
let () = unsafe { blaze_symbolizer_free(symbolizer) };
}

/// Check that a user-provided KASLR offset is plumbed through to
/// `vmlinux` based symbolization.
#[test]
fn symbolize_in_kernel_with_kaslr_offset() {
let path = Path::new(&env!("CARGO_MANIFEST_DIR"))
.join("..")
.join("data")
.join("test-stable-addrs.bin");
let path_c = CString::new(path.to_str().unwrap()).unwrap();
let factorial_addr = 0x2000200u64;
let kaslr_offset = 0x1000u64;
let src = blaze_symbolize_src_kernel {
kallsyms: b"\0" as *const _ as *const c_char,
vmlinux: path_c.as_ptr(),
kaslr_offset: &kaslr_offset,
..Default::default()
};

let symbolizer = blaze_symbolizer_new();
let addrs = [factorial_addr + kaslr_offset];
let result = unsafe {
blaze_symbolize_kernel_abs_addrs(symbolizer, &src, addrs.as_ptr(), addrs.len())
};
assert!(!result.is_null());

let syms = unsafe { &*result };
assert_eq!(syms.cnt, 1);
let sym = unsafe { &*syms.syms.as_ptr() };
assert_eq!(
unsafe { CStr::from_ptr(sym.name) },
CStr::from_bytes_with_nul(b"factorial\0").unwrap()
);

let () = unsafe { blaze_syms_free(result) };
let () = unsafe { blaze_symbolizer_free(symbolizer) };
}

/// Check that we report the expected error when attempting to
/// symbolize data using a non-existent source.
#[test]
Expand Down
Loading