Skip to content

Commit

Permalink
Merge #1331
Browse files Browse the repository at this point in the history
1331: feat(sys): High-level personality(2) wrappers r=asomers a=woodruffw

Adds a high level `Persona` bitflags enum, as well as `personality::get()` and `personality::set()` for interacting with `libc::personality()`.

Closes #1330.

See also rust-lang/libc#1974.

Co-authored-by: William Woodruff <william@trailofbits.com>
  • Loading branch information
bors[bot] and woodruffw committed Dec 19, 2020
2 parents b53a08e + 2359b0e commit e65db13
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 1 deletion.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Expand Up @@ -7,6 +7,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
### Added
- Added `mremap` (#[1306](https://github.com/nix-rust/nix/pull/1306))

- Added `personality` (#[1331](https://github.com/nix-rust/nix/pull/1331))
### Fixed
### Changed

Expand Down Expand Up @@ -70,7 +71,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
- Derived `Ord`, `PartialOrd` for `unistd::Pid` (#[1189](https://github.com/nix-rust/nix/pull/1189))
- Added `select::FdSet::fds` method to iterate over file descriptors in a set.
([#1207](https://github.com/nix-rust/nix/pull/1207))
- Added support for UDP generic segmentation offload (GSO) and generic
- Added support for UDP generic segmentation offload (GSO) and generic
receive offload (GRO) ([#1209](https://github.com/nix-rust/nix/pull/1209))
- Added support for `sendmmsg` and `recvmmsg` calls
(#[1208](https://github.com/nix-rust/nix/pull/1208))
Expand Down
3 changes: 3 additions & 0 deletions src/sys/mod.rs
Expand Up @@ -38,6 +38,9 @@ pub mod memfd;
#[cfg(not(target_os = "redox"))]
pub mod mman;

#[cfg(target_os = "linux")]
pub mod personality;

pub mod pthread;

#[cfg(any(target_os = "android",
Expand Down
70 changes: 70 additions & 0 deletions src/sys/personality.rs
@@ -0,0 +1,70 @@
use crate::Result;
use crate::errno::Errno;

use libc::{self, c_int, c_ulong};

libc_bitflags! {
/// Flags used and returned by [`get()`](fn.get.html) and
/// [`set()`](fn.set.html).
pub struct Persona: c_int {
ADDR_COMPAT_LAYOUT;
ADDR_NO_RANDOMIZE;
ADDR_LIMIT_32BIT;
ADDR_LIMIT_3GB;
#[cfg(not(target_env = "musl"))]
FDPIC_FUNCPTRS;
MMAP_PAGE_ZERO;
READ_IMPLIES_EXEC;
SHORT_INODE;
STICKY_TIMEOUTS;
#[cfg(not(target_env = "musl"))]
UNAME26;
WHOLE_SECONDS;
}
}

/// Retrieve the current process personality.
///
/// Returns a Result containing a Persona instance.
///
/// Example:
///
/// ```
/// # use nix::sys::personality::{self, Persona};
/// let pers = personality::get().unwrap();
/// assert!(!pers.contains(Persona::WHOLE_SECONDS));
/// ```
pub fn get() -> Result<Persona> {
let res = unsafe {
libc::personality(0xFFFFFFFF)
};

Errno::result(res).map(|r| Persona::from_bits_truncate(r))
}

/// Set the current process personality.
///
/// Returns a Result containing the *previous* personality for the
/// process, as a Persona.
///
/// For more information, see [personality(2)](https://man7.org/linux/man-pages/man2/personality.2.html)
///
/// **NOTE**: This call **replaces** the current personality entirely.
/// To **update** the personality, first call `get()` and then `set()`
/// with the modified persona.
///
/// Example:
///
/// ```
/// # use nix::sys::personality::{self, Persona};
/// let mut pers = personality::get().unwrap();
/// assert!(!pers.contains(Persona::ADDR_NO_RANDOMIZE));
/// personality::set(pers | Persona::ADDR_NO_RANDOMIZE);
/// ```
pub fn set(persona: Persona) -> Result<Persona> {
let res = unsafe {
libc::personality(persona.bits() as c_ulong)
};

Errno::result(res).map(|r| Persona::from_bits_truncate(r))
}

0 comments on commit e65db13

Please sign in to comment.