Skip to content

Commit

Permalink
rust/sim: Remove dependency on nightly Rust
Browse files Browse the repository at this point in the history
Awaiting stabilization in
rust-lang/rust#42839
  • Loading branch information
ThomasHabets committed Aug 8, 2024
1 parent 22037d4 commit 9dd4bb0
Show file tree
Hide file tree
Showing 6 changed files with 71 additions and 6 deletions.
8 changes: 8 additions & 0 deletions rust/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions rust/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ path = "src/bin/sim.rs"
[dependencies]
anyhow = "1.0.86"
clap = { version = "4.5.13", features = ["derive"] }
libc = "0.2.155"
log = "0.4.22"
nix = { version = "0.29.0", features = ["env", "process", "user", "hostname"] }
protobuf = "3.5.0"
Expand All @@ -18,3 +19,4 @@ socket2 = { version = "0.5.7", features = ["all"]}

[build-dependencies]
protobuf-codegen = "3.5.0"
cc = "1.1.8"
4 changes: 1 addition & 3 deletions rust/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ Test implementation of sim in Rust.

## Building

Because of unix socket peer credentials, we currently require nightly.

```
cargo +nightly build --release
cargo build --release
```
3 changes: 3 additions & 0 deletions rust/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,7 @@ fn main() {
.include("src")
.input("src/simproto.proto")
.run_from_script();
cc::Build::new()
.file("src/peer_cred.c")
.compile("get_peer_uid");
}
31 changes: 28 additions & 3 deletions rust/src/bin/sim.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#![feature(peer_credentials_unix_socket)]

use anyhow::Error;
use anyhow::Result;
use clap::Parser;
Expand Down Expand Up @@ -120,12 +118,39 @@ fn make_approve_request(
})
}

// This wrapper is only needed because the std implementation of peer_cred is
// nightly only. https://github.com/rust-lang/rust/issues/42839
#[repr(C)]
#[derive(Debug, Default)]
// WARNING: If this struct changes, it must also change identically in peer_cred.c.
struct UCred {
pid: libc::pid_t,
uid: libc::uid_t,
gid: libc::gid_t,
}
extern "C" {
fn peer_cred_c(sockfd: std::os::fd::RawFd, cred: *mut UCred) -> libc::c_int;
}
fn peer_cred(sock: &std::os::unix::net::UnixStream) -> Result<UCred> {
let mut cred = UCred::default();
use std::os::fd::AsRawFd;
let rc = unsafe { peer_cred_c(sock.as_raw_fd(), &mut cred) };
if rc != 0 {
Err(Error::msg(format!(
"getting peer credentials failed: {}",
std::io::Error::from_raw_os_error(rc)
)))
} else {
Ok(cred)
}
}

fn check_approver(
approver_gid: u32,
mut sock: std::os::unix::net::UnixStream,
req: &simproto::ApproveRequest,
) -> Result<()> {
let peer = sock.peer_cred()?;
let peer = peer_cred(&sock)?;
debug!("sim: Peer creds: {peer:?}");
let group = nix::unistd::Group::from_gid(nix::unistd::Gid::from_raw(peer.gid))?
.ok_or(Error::msg(format!("unknown peer gid {}", peer.gid)))?;
Expand Down
29 changes: 29 additions & 0 deletions rust/src/peer_cred.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// This wrapper is only needed because the std implementation of peer_cred is
// nightly only. https://github.com/rust-lang/rust/issues/42839
#define _GNU_SOURCE
#include <sys/socket.h>

// WARNING: If this struct changes, it must also change identically in sim.rs.
struct UCred {
pid_t pid;
uid_t uid;
gid_t gid;
};

int peer_cred_c(int sockfd, struct UCred* cred)
{
socklen_t len = sizeof(struct ucred);
struct ucred ucred;
cred.pid = -1;
cred.uid = -1;
cred.gid = -1;

if (getsockopt(sockfd, SOL_SOCKET, SO_PEERCRED, &ucred, &len) == -1) {
return errno;
}

cred->pid = ucred.pid;
cred->uid = ucred.uid;
cred->gid = ucred.gid;
return 0;
}

0 comments on commit 9dd4bb0

Please sign in to comment.