Skip to content

Fix suseconds_t type signedness for Linux ABI compatibility #608

@wdcui

Description

@wdcui

Summary

The suseconds_t type is defined as unsigned (u32/u64) but should be signed (i32/i64) per Linux kernel ABI.

Location

litebox_common_linux/src/lib.rs lines 771-781:

cfg_if::cfg_if! {
    if #[cfg(all(target_arch = "x86"))] {
        pub type time_t = i32;
        pub type suseconds_t = u32;  // <-- Should be i32
    } else if #[cfg(all(target_arch = "x86_64"))] {
        pub type time_t = i64;
        pub type suseconds_t = u64;  // <-- Should be i64
    } else {
        compile_error!("Unsupported architecture");
    }
}

Expected Behavior

Per Linux kernel (include/uapi/asm-generic/posix_types.h):

typedef __kernel_long_t    __kernel_suseconds_t;

Where __kernel_long_t is long (signed). So:

  • On x86 (32-bit): suseconds_t should be i32
  • On x86_64 (64-bit): suseconds_t should be i64

Impact

This affects the TimeVal struct which is used in:

  • Rusage.ru_utime and Rusage.ru_stime (getrusage syscall)
  • ItimerVal (setitimer/getitimer syscalls)
  • Any other syscalls using TimeVal

Current impact is minimal since:

  1. suseconds_t values are typically non-negative microseconds (0-999999)
  2. Current implementations return zeroed values

However, for strict ABI compatibility and future implementations that populate real time values, this should be fixed.

Suggested Fix

cfg_if::cfg_if! {
    if #[cfg(all(target_arch = "x86"))] {
        pub type time_t = i32;
        pub type suseconds_t = i32;  // Changed from u32
    } else if #[cfg(all(target_arch = "x86_64"))] {
        pub type time_t = i64;
        pub type suseconds_t = i64;  // Changed from u64
    } else {
        compile_error!("Unsupported architecture");
    }
}

Additional Consideration

Consider adding compile-time size assertions for structs that depend on these types:

#[cfg(target_arch = "x86_64")]
const _: () = assert!(core::mem::size_of::<TimeVal>() == 16);
#[cfg(target_arch = "x86")]
const _: () = assert!(core::mem::size_of::<TimeVal>() == 8);

Found During

Code review of PR #606 (getrusage syscall implementation).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions