summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWilliam Woodruff <william@trailofbits.com>2020-11-10 13:57:40 -0500
committerWilliam Woodruff <william@yossarian.net>2020-12-15 03:04:00 -0500
commit2359b0e9a0916f4df5a65200b0f0fa194df4ac63 (patch)
tree6a98004c6a3d3a14d9c97190ad8a4c965bd84598
parent0fd17fc4e574c1b245c95c2fb878785e94316591 (diff)
downloadnix-2359b0e9a0916f4df5a65200b0f0fa194df4ac63.zip
feat(sys): High-level personality(2) wrappers
Adds a high level `Persona` bitflags enum, as well as `personality::get()` and `personality::set()` for interacting with `libc::personality()`.
-rw-r--r--CHANGELOG.md3
-rw-r--r--src/sys/mod.rs3
-rw-r--r--src/sys/personality.rs70
3 files changed, 75 insertions, 1 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 719d84dc..473ff454 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -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
@@ -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))
diff --git a/src/sys/mod.rs b/src/sys/mod.rs
index bf7f5412..438fb4fd 100644
--- a/src/sys/mod.rs
+++ b/src/sys/mod.rs
@@ -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",
diff --git a/src/sys/personality.rs b/src/sys/personality.rs
new file mode 100644
index 00000000..6548b654
--- /dev/null
+++ b/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))
+}