Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,11 @@ use std::sync::Arc;
use serde::{Serialize, Deserialize};
use serde_json;
use shlex;
mod portalcall;

const BUF_SIZE: usize = 65536;
const CMD_TIMEOUT: Duration = Duration::from_secs(10);

Copilot AI Oct 24, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The INDIV_DEBUG_PORTALCALL_MAGIC constant lacks documentation explaining its purpose and relationship to the indiv_debug.py interface mentioned in the PR description. Consider adding a comment documenting this magic number's meaning.

Suggested change
const CMD_TIMEOUT: Duration = Duration::from_secs(10);
const CMD_TIMEOUT: Duration = Duration::from_secs(10);
/// Magic number used to initialize the portal call interface.
/// This value must match the expected magic in the `indiv_debug.py` interface,
/// and is used to identify and authenticate debug portal calls between Rust and Python.
/// See PR description and `indiv_debug.py` for protocol details.

Copilot uses AI. Check for mistakes.
const INDIV_DEBUG_PORTALCALL_MAGIC: u64 = 0xfeedbeef;

#[derive(Serialize, Deserialize, Debug)]
struct CmdResult {
Expand All @@ -38,6 +40,8 @@ pub struct ListenAddress {
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
env_logger::init();

let _: i64 = portalcall::portal_call1(INDIV_DEBUG_PORTALCALL_MAGIC, 0);
let args = ListenAddress::from_args();
let cid = args.cid.unwrap_or(libc::VMADDR_CID_ANY);
let addr = VsockAddr::new(cid, args.port);
Expand Down
51 changes: 51 additions & 0 deletions src/portalcall.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
use libc::{syscall, SYS_sendto};

Copilot AI Oct 24, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The PORTAL_MAGIC constant lacks documentation explaining its purpose and origin. Consider adding a comment describing what this magic number represents and why it's used for the portal call interface.

Suggested change
// PORTAL_MAGIC is a magic number used to identify portal calls via the syscall interface.
// The value 0xc1d1e1f1 is chosen to be unique and unlikely to conflict with other syscall usages.
// It acts as a signature for the portal call protocol, ensuring that only intended calls are processed.

Copilot uses AI. Check for mistakes.
#[cfg(target_pointer_width = "64")]
const PORTAL_MAGIC: libc::c_ulong = 0xc1d1e1f1;
#[cfg(not(target_pointer_width = "64"))]
const PORTAL_MAGIC: libc::c_uint = 0xc1d1e1f1;

#[inline]
pub fn portal_call(user_magic: u64, argc: i32, args: &[u64]) -> i64 {
unsafe {
syscall(
SYS_sendto,
PORTAL_MAGIC,
user_magic,
argc,
args.as_ptr(),
Comment on lines +9 to +16

Copilot AI Oct 24, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The argc parameter is passed as an i32 but the function doesn't validate that args.len() matches argc. This could lead to buffer overruns or incorrect behavior if the caller passes mismatched values. Consider using args.len() directly or adding validation: assert_eq!(argc as usize, args.len()).

Copilot uses AI. Check for mistakes.
0,
0,
) as i64
}
}

#[inline]
#[allow(dead_code)]
pub fn portal_call1(user_magic: u64, a1: u64) -> i64 {
portal_call(user_magic, 1, &[a1])
}

#[inline]
#[allow(dead_code)]
pub fn portal_call2(user_magic: u64, a1: u64, a2: u64) -> i64 {
portal_call(user_magic, 2, &[a1, a2])
}

#[inline]
#[allow(dead_code)]
pub fn portal_call3(user_magic: u64, a1: u64, a2: u64, a3: u64) -> i64 {
portal_call(user_magic, 3, &[a1, a2, a3])
}

#[inline]
#[allow(dead_code)]
pub fn portal_call4(user_magic: u64, a1: u64, a2: u64, a3: u64, a4: u64) -> i64 {
portal_call(user_magic, 4, &[a1, a2, a3, a4])
}

#[inline]
#[allow(dead_code)]
pub fn portal_call5(user_magic: u64, a1: u64, a2: u64, a3: u64, a4: u64, a5: u64) -> i64 {
portal_call(user_magic, 5, &[a1, a2, a3, a4, a5])
}