Enum AuxVar

Source
pub enum AuxVar<'a> {
Show 34 variants Null, Ignore(usize), ExecFd(usize), Phdr(*const u8), Phent(usize), Phnum(usize), Pagesz(usize), Base(*const u8), Flags(AuxVarFlags), Entry(*const u8), NotElf(bool), Uid(usize), EUid(usize), Gid(usize), EGid(usize), Platform(&'a str), HwCap(usize), Clktck(usize), Secure(bool), BasePlatform(&'a str), Random([u8; 16]), HwCap2(usize), ExecFn(&'a str), Sysinfo(*const u8), SysinfoEhdr(*const u8), L1iCacheSize(usize), L1iCacheGeometry(usize), L1dCacheSize(usize), L1dCacheGeometry(usize), L2CacheSize(usize), L2CacheGeometry(usize), L3CacheSize(usize), L3CacheGeometry(usize), MinSigStkSz(usize),
}
Expand description

High-level version of the serialized form of an auxiliary vector entry. It is used to construct the auxiliary vector in crate::InitialLinuxLibcStackLayoutBuilder and returned when a data structure is parsed with crate::InitialLinuxLibcStackLayout.

Variants§

§

Null

Entry with payload for type AuxVarType::Null.

§

Ignore(usize)

Entry with payload for type AuxVarType::Ignore.

§

ExecFd(usize)

Entry with payload for type AuxVarType::ExecFd.

§

Phdr(*const u8)

Entry with payload for type AuxVarType::Phdr.

§

Phent(usize)

Entry with payload for type AuxVarType::Phent.

§

Phnum(usize)

Entry with payload for type AuxVarType::Phnum.

§

Pagesz(usize)

Entry with payload for type AuxVarType::Pagesz.

§

Base(*const u8)

Entry with payload for type AuxVarType::Base.

§

Flags(AuxVarFlags)

Entry with payload for type AuxVarType::Flags.

§

Entry(*const u8)

Entry with payload for type AuxVarType::Entry.

§

NotElf(bool)

Entry with payload for type AuxVarType::NotElf.

§

Uid(usize)

Entry with payload for type AuxVarType::Uid.

§

EUid(usize)

Entry with payload for type AuxVarType::EUid.

§

Gid(usize)

Entry with payload for type AuxVarType::Gid.

§

EGid(usize)

Entry with payload for type AuxVarType::EGid.

§

Platform(&'a str)

Entry with payload for type AuxVarType::Platform.

§

HwCap(usize)

Entry with payload for type AuxVarType::HwCap.

§

Clktck(usize)

Entry with payload for type AuxVarType::Clktck.

§

Secure(bool)

Entry with payload for type AuxVarType::Secure.

§

BasePlatform(&'a str)

Entry with payload for type AuxVarType::BasePlatform.

§

Random([u8; 16])

Entry with payload for type AuxVarType::Random. This data owns the bytes rather than referencing to it, because the operation is cheap anyway but it also simplified parsing. Otherwise, I had to create a &'a [u8; 16] from a &'a [u8], which is hard without hacky tricks.

§

HwCap2(usize)

Entry with payload for type AuxVarType::HwCap2.

§

ExecFn(&'a str)

Entry with payload for type AuxVarType::ExecFn.

§

Sysinfo(*const u8)

Entry with payload for type AuxVarType::Sysinfo.

§

SysinfoEhdr(*const u8)

Entry with payload for type AuxVarType::SysinfoEhdr.

§

L1iCacheSize(usize)

Entry with payload for type AuxVarType::L1iCacheSize.

§

L1iCacheGeometry(usize)

Entry with payload for type AuxVarType::L1iCacheGeometry.

§

L1dCacheSize(usize)

Entry with payload for type AuxVarType::L1dCacheSize.

§

L1dCacheGeometry(usize)

Entry with payload for type AuxVarType::L1dCacheGeometry.

§

L2CacheSize(usize)

Entry with payload for type AuxVarType::L2CacheSize.

§

L2CacheGeometry(usize)

Entry with payload for type AuxVarType::L2CacheGeometry.

§

L3CacheSize(usize)

Entry with payload for type AuxVarType::L3CacheSize.

§

L3CacheGeometry(usize)

Entry with payload for type AuxVarType::L3CacheGeometry.

§

MinSigStkSz(usize)

Entry with payload for type AuxVarType::MinSigStkSz.

Implementations§

Source§

impl<'a> AuxVar<'a>

Source

pub const fn key(&self) -> AuxVarType

Returns the AuxVarType this aux var corresponds to.

Examples found in repository?
examples/build_and_parse.rs (line 135)
116unsafe fn parse_memory_unsafe(parsed: &InitialLinuxLibcStackLayout) {
117    println!("  argv");
118    // ptr iter is safe for other address spaces; the other only because here user_addr == write_addr
119    for (i, arg) in parsed.argv_iter().enumerate() {
120        println!("    [{}] {}", i, arg);
121    }
122
123    println!("  envp");
124    // ptr iter is safe for other address spaces; the other only because here user_addr == write_addr
125    for (i, env) in parsed.envv_iter().enumerate() {
126        println!("    [{}] {}", i, env);
127    }
128
129    println!("  aux");
130    for aux in parsed.aux_var_iter() {
131        // currently: Only AT_RANDOM
132        if let Some(bytes) = aux.value_payload_bytes() {
133            println!(
134                "    {:>12?} => @ {:?}: {:?}",
135                aux.key(),
136                aux.value_raw() as *const u8,
137                bytes,
138            );
139        } else if let Some(cstr) = aux.value_payload_cstr() {
140            println!(
141                "    {:>12?} => @ {:?}: {:?}",
142                aux.key(),
143                aux.value_raw() as *const u8,
144                cstr,
145            );
146        } else if let Some(flags) = aux.value_flags() {
147            println!("    {:>12?} => {:?}", aux.key(), flags,);
148        } else if let Some(boolean) = aux.value_boolean() {
149            println!("    {:>12?} => {:?}", aux.key(), boolean,);
150        } else if let Some(ptr) = aux.value_ptr() {
151            println!("    {:>12?} => {:?}", aux.key(), ptr,);
152        } else {
153            println!("    {:>12?} => {}", aux.key(), aux.value_raw());
154        }
155    }
156}
Source

pub fn value_raw(&self) -> usize

Transforms any inner value into it’s corresponding usize value. This is similar to the data that is serialized in the data structure on the stack, i.e. the value of the auxiliary vector entry.

Examples found in repository?
examples/build_and_parse.rs (line 136)
116unsafe fn parse_memory_unsafe(parsed: &InitialLinuxLibcStackLayout) {
117    println!("  argv");
118    // ptr iter is safe for other address spaces; the other only because here user_addr == write_addr
119    for (i, arg) in parsed.argv_iter().enumerate() {
120        println!("    [{}] {}", i, arg);
121    }
122
123    println!("  envp");
124    // ptr iter is safe for other address spaces; the other only because here user_addr == write_addr
125    for (i, env) in parsed.envv_iter().enumerate() {
126        println!("    [{}] {}", i, env);
127    }
128
129    println!("  aux");
130    for aux in parsed.aux_var_iter() {
131        // currently: Only AT_RANDOM
132        if let Some(bytes) = aux.value_payload_bytes() {
133            println!(
134                "    {:>12?} => @ {:?}: {:?}",
135                aux.key(),
136                aux.value_raw() as *const u8,
137                bytes,
138            );
139        } else if let Some(cstr) = aux.value_payload_cstr() {
140            println!(
141                "    {:>12?} => @ {:?}: {:?}",
142                aux.key(),
143                aux.value_raw() as *const u8,
144                cstr,
145            );
146        } else if let Some(flags) = aux.value_flags() {
147            println!("    {:>12?} => {:?}", aux.key(), flags,);
148        } else if let Some(boolean) = aux.value_boolean() {
149            println!("    {:>12?} => {:?}", aux.key(), boolean,);
150        } else if let Some(ptr) = aux.value_ptr() {
151            println!("    {:>12?} => {:?}", aux.key(), ptr,);
152        } else {
153            println!("    {:>12?} => {}", aux.key(), aux.value_raw());
154        }
155    }
156}
Source

pub const fn value_integer(&self) -> Option<usize>

Returns a value, if the corresponding auxiliary vector entry corresponds to a basic value/integer, and not a pointer, flags, or a boolean.

Source

pub const fn value_flags(&self) -> Option<AuxVarFlags>

Returns a value, if the corresponding auxiliary vector entry is of type AuxVarType::Flags.

Examples found in repository?
examples/build_and_parse.rs (line 146)
116unsafe fn parse_memory_unsafe(parsed: &InitialLinuxLibcStackLayout) {
117    println!("  argv");
118    // ptr iter is safe for other address spaces; the other only because here user_addr == write_addr
119    for (i, arg) in parsed.argv_iter().enumerate() {
120        println!("    [{}] {}", i, arg);
121    }
122
123    println!("  envp");
124    // ptr iter is safe for other address spaces; the other only because here user_addr == write_addr
125    for (i, env) in parsed.envv_iter().enumerate() {
126        println!("    [{}] {}", i, env);
127    }
128
129    println!("  aux");
130    for aux in parsed.aux_var_iter() {
131        // currently: Only AT_RANDOM
132        if let Some(bytes) = aux.value_payload_bytes() {
133            println!(
134                "    {:>12?} => @ {:?}: {:?}",
135                aux.key(),
136                aux.value_raw() as *const u8,
137                bytes,
138            );
139        } else if let Some(cstr) = aux.value_payload_cstr() {
140            println!(
141                "    {:>12?} => @ {:?}: {:?}",
142                aux.key(),
143                aux.value_raw() as *const u8,
144                cstr,
145            );
146        } else if let Some(flags) = aux.value_flags() {
147            println!("    {:>12?} => {:?}", aux.key(), flags,);
148        } else if let Some(boolean) = aux.value_boolean() {
149            println!("    {:>12?} => {:?}", aux.key(), boolean,);
150        } else if let Some(ptr) = aux.value_ptr() {
151            println!("    {:>12?} => {:?}", aux.key(), ptr,);
152        } else {
153            println!("    {:>12?} => {}", aux.key(), aux.value_raw());
154        }
155    }
156}
Source

pub const fn value_boolean(&self) -> Option<bool>

Returns a value, if the corresponding auxiliary vector entry corresponds to a boolean, and not a pointer, flags, or a basic value/integer.

Examples found in repository?
examples/build_and_parse.rs (line 148)
116unsafe fn parse_memory_unsafe(parsed: &InitialLinuxLibcStackLayout) {
117    println!("  argv");
118    // ptr iter is safe for other address spaces; the other only because here user_addr == write_addr
119    for (i, arg) in parsed.argv_iter().enumerate() {
120        println!("    [{}] {}", i, arg);
121    }
122
123    println!("  envp");
124    // ptr iter is safe for other address spaces; the other only because here user_addr == write_addr
125    for (i, env) in parsed.envv_iter().enumerate() {
126        println!("    [{}] {}", i, env);
127    }
128
129    println!("  aux");
130    for aux in parsed.aux_var_iter() {
131        // currently: Only AT_RANDOM
132        if let Some(bytes) = aux.value_payload_bytes() {
133            println!(
134                "    {:>12?} => @ {:?}: {:?}",
135                aux.key(),
136                aux.value_raw() as *const u8,
137                bytes,
138            );
139        } else if let Some(cstr) = aux.value_payload_cstr() {
140            println!(
141                "    {:>12?} => @ {:?}: {:?}",
142                aux.key(),
143                aux.value_raw() as *const u8,
144                cstr,
145            );
146        } else if let Some(flags) = aux.value_flags() {
147            println!("    {:>12?} => {:?}", aux.key(), flags,);
148        } else if let Some(boolean) = aux.value_boolean() {
149            println!("    {:>12?} => {:?}", aux.key(), boolean,);
150        } else if let Some(ptr) = aux.value_ptr() {
151            println!("    {:>12?} => {:?}", aux.key(), ptr,);
152        } else {
153            println!("    {:>12?} => {}", aux.key(), aux.value_raw());
154        }
155    }
156}
Source

pub const fn value_ptr(&self) -> Option<*const u8>

Returns a value, if the corresponding auxiliary vector entry corresponds to a pointer, and not a boolean, flags, or a basic value/integer. This only affects entries, that point to memory outside of the initial stack layout, i.e. the aux vector data area.

Examples found in repository?
examples/build_and_parse.rs (line 150)
116unsafe fn parse_memory_unsafe(parsed: &InitialLinuxLibcStackLayout) {
117    println!("  argv");
118    // ptr iter is safe for other address spaces; the other only because here user_addr == write_addr
119    for (i, arg) in parsed.argv_iter().enumerate() {
120        println!("    [{}] {}", i, arg);
121    }
122
123    println!("  envp");
124    // ptr iter is safe for other address spaces; the other only because here user_addr == write_addr
125    for (i, env) in parsed.envv_iter().enumerate() {
126        println!("    [{}] {}", i, env);
127    }
128
129    println!("  aux");
130    for aux in parsed.aux_var_iter() {
131        // currently: Only AT_RANDOM
132        if let Some(bytes) = aux.value_payload_bytes() {
133            println!(
134                "    {:>12?} => @ {:?}: {:?}",
135                aux.key(),
136                aux.value_raw() as *const u8,
137                bytes,
138            );
139        } else if let Some(cstr) = aux.value_payload_cstr() {
140            println!(
141                "    {:>12?} => @ {:?}: {:?}",
142                aux.key(),
143                aux.value_raw() as *const u8,
144                cstr,
145            );
146        } else if let Some(flags) = aux.value_flags() {
147            println!("    {:>12?} => {:?}", aux.key(), flags,);
148        } else if let Some(boolean) = aux.value_boolean() {
149            println!("    {:>12?} => {:?}", aux.key(), boolean,);
150        } else if let Some(ptr) = aux.value_ptr() {
151            println!("    {:>12?} => {:?}", aux.key(), ptr,);
152        } else {
153            println!("    {:>12?} => {}", aux.key(), aux.value_raw());
154        }
155    }
156}
Source

pub fn value_payload_bytes(&'a self) -> Option<&'a [u8]>

Returns a value, if the corresponding auxiliary vector entry references data in the auxiliary vector data area of the data structure. This returns only something for AuxVarType::Random.

This function is safe, because the creation during parsing already guarantee memory safety (the addresses are accessed).

Examples found in repository?
examples/build_and_parse.rs (line 132)
116unsafe fn parse_memory_unsafe(parsed: &InitialLinuxLibcStackLayout) {
117    println!("  argv");
118    // ptr iter is safe for other address spaces; the other only because here user_addr == write_addr
119    for (i, arg) in parsed.argv_iter().enumerate() {
120        println!("    [{}] {}", i, arg);
121    }
122
123    println!("  envp");
124    // ptr iter is safe for other address spaces; the other only because here user_addr == write_addr
125    for (i, env) in parsed.envv_iter().enumerate() {
126        println!("    [{}] {}", i, env);
127    }
128
129    println!("  aux");
130    for aux in parsed.aux_var_iter() {
131        // currently: Only AT_RANDOM
132        if let Some(bytes) = aux.value_payload_bytes() {
133            println!(
134                "    {:>12?} => @ {:?}: {:?}",
135                aux.key(),
136                aux.value_raw() as *const u8,
137                bytes,
138            );
139        } else if let Some(cstr) = aux.value_payload_cstr() {
140            println!(
141                "    {:>12?} => @ {:?}: {:?}",
142                aux.key(),
143                aux.value_raw() as *const u8,
144                cstr,
145            );
146        } else if let Some(flags) = aux.value_flags() {
147            println!("    {:>12?} => {:?}", aux.key(), flags,);
148        } else if let Some(boolean) = aux.value_boolean() {
149            println!("    {:>12?} => {:?}", aux.key(), boolean,);
150        } else if let Some(ptr) = aux.value_ptr() {
151            println!("    {:>12?} => {:?}", aux.key(), ptr,);
152        } else {
153            println!("    {:>12?} => {}", aux.key(), aux.value_raw());
154        }
155    }
156}
Source

pub const fn value_payload_cstr(&'a self) -> Option<&'a str>

Returns a value, if the corresponding auxiliary vector entry references data in the auxiliary vector data area of the data structure. This returns only something for AuxVarType::Random.

This function is safe, because the creation during parsing already guarantee memory safety (the addresses are accessed).

Examples found in repository?
examples/build_and_parse.rs (line 139)
116unsafe fn parse_memory_unsafe(parsed: &InitialLinuxLibcStackLayout) {
117    println!("  argv");
118    // ptr iter is safe for other address spaces; the other only because here user_addr == write_addr
119    for (i, arg) in parsed.argv_iter().enumerate() {
120        println!("    [{}] {}", i, arg);
121    }
122
123    println!("  envp");
124    // ptr iter is safe for other address spaces; the other only because here user_addr == write_addr
125    for (i, env) in parsed.envv_iter().enumerate() {
126        println!("    [{}] {}", i, env);
127    }
128
129    println!("  aux");
130    for aux in parsed.aux_var_iter() {
131        // currently: Only AT_RANDOM
132        if let Some(bytes) = aux.value_payload_bytes() {
133            println!(
134                "    {:>12?} => @ {:?}: {:?}",
135                aux.key(),
136                aux.value_raw() as *const u8,
137                bytes,
138            );
139        } else if let Some(cstr) = aux.value_payload_cstr() {
140            println!(
141                "    {:>12?} => @ {:?}: {:?}",
142                aux.key(),
143                aux.value_raw() as *const u8,
144                cstr,
145            );
146        } else if let Some(flags) = aux.value_flags() {
147            println!("    {:>12?} => {:?}", aux.key(), flags,);
148        } else if let Some(boolean) = aux.value_boolean() {
149            println!("    {:>12?} => {:?}", aux.key(), boolean,);
150        } else if let Some(ptr) = aux.value_ptr() {
151            println!("    {:>12?} => {:?}", aux.key(), ptr,);
152        } else {
153            println!("    {:>12?} => {}", aux.key(), aux.value_raw());
154        }
155    }
156}

Trait Implementations§

Source§

impl<'a> Debug for AuxVar<'a>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<'a> Ord for AuxVar<'a>

Source§

fn cmp(&self, other: &Self) -> Ordering

This method returns an Ordering between self and other. Read more
1.21.0 · Source§

fn max(self, other: Self) -> Self
where Self: Sized,

Compares and returns the maximum of two values. Read more
1.21.0 · Source§

fn min(self, other: Self) -> Self
where Self: Sized,

Compares and returns the minimum of two values. Read more
1.50.0 · Source§

fn clamp(self, min: Self, max: Self) -> Self
where Self: Sized,

Restrict a value to a certain interval. Read more
Source§

impl<'a> PartialEq for AuxVar<'a>

Source§

fn eq(&self, other: &Self) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl<'a> PartialOrd for AuxVar<'a>

Source§

fn partial_cmp(&self, other: &Self) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · Source§

fn lt(&self, other: &Rhs) -> bool

Tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · Source§

fn le(&self, other: &Rhs) -> bool

Tests less than or equal to (for self and other) and is used by the <= operator. Read more
1.0.0 · Source§

fn gt(&self, other: &Rhs) -> bool

Tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · Source§

fn ge(&self, other: &Rhs) -> bool

Tests greater than or equal to (for self and other) and is used by the >= operator. Read more
Source§

impl<'a> Eq for AuxVar<'a>

Auto Trait Implementations§

§

impl<'a> Freeze for AuxVar<'a>

§

impl<'a> RefUnwindSafe for AuxVar<'a>

§

impl<'a> !Send for AuxVar<'a>

§

impl<'a> !Sync for AuxVar<'a>

§

impl<'a> Unpin for AuxVar<'a>

§

impl<'a> UnwindSafe for AuxVar<'a>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.