Skip to content

Commit

Permalink
Prefer to define FFI functions in libc
Browse files Browse the repository at this point in the history
Where possible, use libc's FFI definitions instead of our own.
Also, automatically derive PartialEq.

Partially addresses dlrobertson#18
  • Loading branch information
asomers committed Nov 29, 2022
1 parent 18dd825 commit a486af3
Show file tree
Hide file tree
Showing 4 changed files with 20 additions and 68 deletions.
8 changes: 1 addition & 7 deletions src/fcntl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ impl FcntlsBuilder {
}
}

#[derive(Debug, Default)]
#[derive(Debug, Default, Eq, PartialEq)]
pub struct FcntlRights(u32);

impl FcntlRights {
Expand Down Expand Up @@ -74,12 +74,6 @@ impl CapRights for FcntlRights {
}
}

impl PartialEq for FcntlRights {
fn eq(&self, other: &FcntlRights) -> bool {
self.0 == other.0
}
}

extern "C" {
fn cap_fcntls_limit(fd: i32, fcntlrights: u32) -> i32;
fn cap_fcntls_get(fd: i32, fcntlrightsp: *mut u32) -> i32;
Expand Down
8 changes: 1 addition & 7 deletions src/ioctl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ impl IoctlsBuilder {
}
}

#[derive(Debug, Default)]
#[derive(Debug, Default, Eq, PartialEq)]
pub struct IoctlRights(Vec<u64>);

impl IoctlRights {
Expand Down Expand Up @@ -75,12 +75,6 @@ impl CapRights for IoctlRights {
}
}

impl PartialEq for IoctlRights {
fn eq(&self, other: &IoctlRights) -> bool {
self.0 == other.0
}
}

extern "C" {
fn cap_ioctls_limit(fd: i32, cmds: *const libc::u_long, ncmds: usize) -> i32;
fn cap_ioctls_get(fd: i32, cmds: *mut libc::u_long, maxcmds: usize) -> isize;
Expand Down
6 changes: 2 additions & 4 deletions src/process.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
use std::io;

pub fn enter() -> io::Result<()> {
if unsafe { cap_enter() } < 0 {
if unsafe { libc::cap_enter() } < 0 {
Err(io::Error::last_os_error())
} else {
Ok(())
Expand All @@ -19,15 +19,13 @@ pub fn sandboxed() -> bool {
pub fn get_mode() -> io::Result<usize> {
let mut mode = 0;
unsafe {
if cap_getmode(&mut mode) != 0 {
if libc::cap_getmode(&mut mode) != 0 {
return Err(io::Error::last_os_error());
}
}
Ok(mode as usize)
}

extern "C" {
fn cap_enter() -> i32;
fn cap_sandboxed() -> bool;
fn cap_getmode(modep: *mut u32) -> i32;
}
66 changes: 16 additions & 50 deletions src/right.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@
#![allow(non_camel_case_types)]

use common::{CapErr, CapErrType, CapResult, CapRights};
use libc::cap_rights_t;
use std::io;
use std::mem;
use std::ops::BitAnd;
use std::os::raw::c_char;
use std::os::unix::io::{AsRawFd, RawFd};
Expand Down Expand Up @@ -165,16 +167,14 @@ impl RightsBuilder {
}
}

#[derive(Debug, Default)]
#[derive(Debug, Eq, PartialEq)]
pub struct FileRights(cap_rights_t);

impl FileRights {
pub fn new(raw_rights: u64) -> CapResult<FileRights> {
unsafe {
let mut empty_rights = cap_rights_t {
cr_rights: [0; RIGHTS_VERSION as usize + 2],
};
let rights_ptr = __cap_rights_init(
let mut empty_rights = unsafe { mem::zeroed() };
let rights_ptr = libc::__cap_rights_init(
RIGHTS_VERSION,
&mut empty_rights as *mut cap_rights_t,
raw_rights,
Expand All @@ -195,9 +195,7 @@ impl FileRights {

pub fn from_file<T: AsRawFd>(fd: &T) -> CapResult<FileRights> {
unsafe {
let mut empty_rights = cap_rights_t {
cr_rights: [0; RIGHTS_VERSION as usize + 2],
};
let mut empty_rights = unsafe { mem::zeroed() };
let res = __cap_rights_get(
RIGHTS_VERSION,
fd.as_raw_fd(),
Expand All @@ -217,20 +215,22 @@ impl FileRights {
}

pub fn contains(&self, other: &FileRights) -> bool {
unsafe { cap_rights_contains(&self.0, &other.0) }
unsafe { libc::cap_rights_contains(&self.0, &other.0) }
}

pub fn is_set(&self, raw_rights: Right) -> bool {
unsafe { __cap_rights_is_set(&self.0 as *const cap_rights_t, raw_rights as u64, 0u64) }
unsafe {
libc::__cap_rights_is_set(&self.0 as *const cap_rights_t, raw_rights as u64, 0u64)
}
}

pub fn is_valid(&self) -> bool {
unsafe { cap_rights_is_valid(&self.0) }
unsafe { libc::cap_rights_is_valid(&self.0) }
}

pub fn merge(&mut self, other: &FileRights) -> CapResult<()> {
unsafe {
let result = cap_rights_merge(&mut self.0 as *mut cap_rights_t, &other.0);
let result = libc::cap_rights_merge(&mut self.0 as *mut cap_rights_t, &other.0);
if result.is_null() {
Err(CapErr::from(CapErrType::Merge))
} else {
Expand All @@ -241,7 +241,7 @@ impl FileRights {

pub fn remove(&mut self, other: &FileRights) -> CapResult<()> {
unsafe {
let result = cap_rights_remove(&mut self.0 as *mut cap_rights_t, &other.0);
let result = libc::cap_rights_remove(&mut self.0 as *mut cap_rights_t, &other.0);
if result.is_null() {
Err(CapErr::from(CapErrType::Remove))
} else {
Expand All @@ -253,7 +253,7 @@ impl FileRights {
pub fn set(&mut self, raw_rights: Right) -> CapResult<()> {
unsafe {
let result =
__cap_rights_set(&mut self.0 as *mut cap_rights_t, raw_rights as u64, 0u64);
libc::__cap_rights_set(&mut self.0 as *mut cap_rights_t, raw_rights as u64, 0u64);
if result.is_null() {
Err(CapErr::from(CapErrType::Set))
} else {
Expand All @@ -265,7 +265,7 @@ impl FileRights {
pub fn clear(&mut self, raw_rights: Right) -> CapResult<()> {
unsafe {
let result =
__cap_rights_clear(&mut self.0 as *mut cap_rights_t, raw_rights as u64, 0u64);
libc::__cap_rights_clear(&mut self.0 as *mut cap_rights_t, raw_rights as u64, 0u64);
if result.is_null() {
Err(CapErr::from(CapErrType::Clear))
} else {
Expand All @@ -278,7 +278,7 @@ impl FileRights {
impl CapRights for FileRights {
fn limit<T: AsRawFd>(&self, fd: &T) -> CapResult<()> {
unsafe {
let res = cap_rights_limit(fd.as_raw_fd(), &self.0 as *const cap_rights_t);
let res = libc::cap_rights_limit(fd.as_raw_fd(), &self.0 as *const cap_rights_t);
if res < 0 {
Err(CapErr::from(CapErrType::Limit))
} else {
Expand All @@ -288,41 +288,7 @@ impl CapRights for FileRights {
}
}

impl PartialEq for FileRights {
fn eq(&self, other: &FileRights) -> bool {
self.0.cr_rights == other.0.cr_rights
}
}

#[repr(C)]
#[derive(Debug, Default)]
pub struct cap_rights_t {
cr_rights: [u64; RIGHTS_VERSION as usize + 2],
}

extern "C" {
fn cap_rights_is_valid(rights: *const cap_rights_t) -> bool;
fn cap_rights_merge(dst: *mut cap_rights_t, src: *const cap_rights_t) -> *mut cap_rights_t;
fn cap_rights_remove(dst: *mut cap_rights_t, src: *const cap_rights_t) -> *mut cap_rights_t;
fn cap_rights_contains(big: *const cap_rights_t, little: *const cap_rights_t) -> bool;
fn cap_rights_limit(fd: RawFd, rights: *const cap_rights_t) -> RawFd;
fn __cap_rights_init(
version: i32,
rights: *mut cap_rights_t,
raw_rights: u64,
sentinel: u64,
) -> *mut cap_rights_t;
fn __cap_rights_set(
rights: *mut cap_rights_t,
raw_rights: u64,
sentinel: u64,
) -> *mut cap_rights_t;
fn __cap_rights_clear(
rights: *mut cap_rights_t,
raw_rights: u64,
sentinel: u64,
) -> *mut cap_rights_t;
fn __cap_rights_is_set(rights: *const cap_rights_t, raw_rights: u64, sentinel: u64) -> bool;
fn __cap_rights_get(version: i32, fd: RawFd, rightsp: *mut cap_rights_t) -> RawFd;
}

Expand Down

0 comments on commit a486af3

Please sign in to comment.