diff --git a/CHANGELOG.md b/CHANGELOG.md index 9e6787ab..80800d90 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,8 @@ # Upcoming Release +## Added +- Support for loongarch64 is added + # v0.5.0 ## Added diff --git a/README.md b/README.md index 937c4659..1056fd5c 100644 --- a/README.md +++ b/README.md @@ -21,6 +21,7 @@ Supported host architectures: - Little-endian x86_64 - Little-endian aarch64 - Little-endian riscv64 +- Little-endian loongarch64 ## Short seccomp tutorial diff --git a/src/backend/bpf.rs b/src/backend/bpf.rs index 6a102a93..e46902af 100644 --- a/src/backend/bpf.rs +++ b/src/backend/bpf.rs @@ -128,6 +128,11 @@ pub const AUDIT_ARCH_AARCH64: u32 = 183 | 0x8000_0000 | 0x4000_0000; // `#define AUDIT_ARCH_RISCV64 (EM_RISCV|__AUDIT_ARCH_64BIT|__AUDIT_ARCH_LE)` pub const AUDIT_ARCH_RISCV64: u32 = 243 | 0x8000_0000 | 0x4000_0000; +// Architecture identifier for loongarch64 LE. +// Defined as: +// `#define AUDIT_ARCH_LOONGARCH64 (EM_LOONGARCH|__AUDIT_ARCH_64BIT|__AUDIT_ARCH_LE)` +pub const AUDIT_ARCH_LOONGARCH64: u32 = 258 | 0x8000_0000 | 0x4000_0000; + /// BPF instruction structure definition. // See /usr/include/linux/filter.h . // We cannot use the `libc::sock_filter` definition since it doesn't implement `Debug` and diff --git a/src/backend/mod.rs b/src/backend/mod.rs index e5730ce7..b990669b 100644 --- a/src/backend/mod.rs +++ b/src/backend/mod.rs @@ -25,7 +25,7 @@ use libc::{ SECCOMP_RET_KILL_THREAD, SECCOMP_RET_LOG, SECCOMP_RET_TRACE, SECCOMP_RET_TRAP, }; -use bpf::{ARG_NUMBER_MAX, AUDIT_ARCH_AARCH64, AUDIT_ARCH_RISCV64, AUDIT_ARCH_X86_64, BPF_MAX_LEN}; +use bpf::{ARG_NUMBER_MAX, AUDIT_ARCH_AARCH64, AUDIT_ARCH_LOONGARCH64, AUDIT_ARCH_RISCV64, AUDIT_ARCH_X86_64, BPF_MAX_LEN}; pub use bpf::{sock_filter, BpfProgram, BpfProgramRef}; @@ -85,6 +85,8 @@ pub enum TargetArch { aarch64, /// riscv64 arch riscv64, + /// loongarch64 arch + loongarch64, } impl TargetArch { @@ -94,6 +96,7 @@ impl TargetArch { TargetArch::x86_64 => AUDIT_ARCH_X86_64, TargetArch::aarch64 => AUDIT_ARCH_AARCH64, TargetArch::riscv64 => AUDIT_ARCH_RISCV64, + TargetArch::loongarch64 => AUDIT_ARCH_LOONGARCH64, } } } @@ -105,6 +108,7 @@ impl TryFrom<&str> for TargetArch { "x86_64" => Ok(TargetArch::x86_64), "aarch64" => Ok(TargetArch::aarch64), "riscv64" => Ok(TargetArch::riscv64), + "loongarch64" => Ok(TargetArch::loongarch64), _ => Err(Error::InvalidTargetArch(input.to_string())), } } @@ -218,5 +222,14 @@ mod tests { TargetArch::try_from("RiScV64").unwrap(), TargetArch::riscv64 ); + + assert_eq!( + TargetArch::try_from("loongarch64").unwrap(), + TargetArch::loongarch64 + ); + assert_eq!( + TargetArch::try_from("LoOnGaRch64").unwrap(), + TargetArch::loongarch64 + ); } } diff --git a/src/lib.rs b/src/lib.rs index ca9d8c23..e8917dab 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -35,6 +35,7 @@ //! - Little-endian x86_64 //! - Little-endian aarch64 //! - Little-endian riscv64 +//! - Little-endian loongarch64 //! //! # Terminology //! diff --git a/src/syscall_table/loongarch64.rs b/src/syscall_table/loongarch64.rs new file mode 100644 index 00000000..376cc3a3 --- /dev/null +++ b/src/syscall_table/loongarch64.rs @@ -0,0 +1,330 @@ +// Copyright 2025 Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 OR BSD-3-Clause + +// This file is auto-generated by `tools/generate_syscall_tables`. +// Do NOT manually edit! +// Generated on: Wed Sep 24 15:44:19 MSK 2025 +// Kernel version: 6.12 + +use std::collections::HashMap; + +pub(crate) fn make_syscall_table() -> HashMap<&'static str, i64> { + vec![ + ("accept", 202), + ("accept4", 242), + ("acct", 89), + ("add_key", 217), + ("adjtimex", 171), + ("bind", 200), + ("bpf", 280), + ("brk", 214), + ("cachestat", 451), + ("capget", 90), + ("capset", 91), + ("chdir", 49), + ("chroot", 51), + ("clock_adjtime", 266), + ("clock_getres", 114), + ("clock_gettime", 113), + ("clock_nanosleep", 115), + ("clock_settime", 112), + ("clone", 220), + ("clone3", 435), + ("close", 57), + ("close_range", 436), + ("connect", 203), + ("copy_file_range", 285), + ("delete_module", 106), + ("dup", 23), + ("dup3", 24), + ("epoll_create1", 20), + ("epoll_ctl", 21), + ("epoll_pwait", 22), + ("epoll_pwait2", 441), + ("eventfd2", 19), + ("execve", 221), + ("execveat", 281), + ("exit", 93), + ("exit_group", 94), + ("faccessat", 48), + ("faccessat2", 439), + ("fadvise64", 223), + ("fallocate", 47), + ("fanotify_init", 262), + ("fanotify_mark", 263), + ("fchdir", 50), + ("fchmod", 52), + ("fchmodat", 53), + ("fchmodat2", 452), + ("fchown", 55), + ("fchownat", 54), + ("fcntl", 25), + ("fdatasync", 83), + ("fgetxattr", 10), + ("finit_module", 273), + ("flistxattr", 13), + ("flock", 32), + ("fremovexattr", 16), + ("fsconfig", 431), + ("fsetxattr", 7), + ("fsmount", 432), + ("fsopen", 430), + ("fspick", 433), + ("fstat", 80), + ("fstatfs", 44), + ("fsync", 82), + ("ftruncate", 46), + ("futex", 98), + ("futex_requeue", 456), + ("futex_wait", 455), + ("futex_waitv", 449), + ("futex_wake", 454), + ("getcpu", 168), + ("getcwd", 17), + ("getdents64", 61), + ("getegid", 177), + ("geteuid", 175), + ("getgid", 176), + ("getgroups", 158), + ("getitimer", 102), + ("get_mempolicy", 236), + ("getpeername", 205), + ("getpgid", 155), + ("getpid", 172), + ("getppid", 173), + ("getpriority", 141), + ("getrandom", 278), + ("getresgid", 150), + ("getresuid", 148), + ("get_robust_list", 100), + ("getrusage", 165), + ("getsid", 156), + ("getsockname", 204), + ("getsockopt", 209), + ("gettid", 178), + ("gettimeofday", 169), + ("getuid", 174), + ("getxattr", 8), + ("init_module", 105), + ("inotify_add_watch", 27), + ("inotify_init1", 26), + ("inotify_rm_watch", 28), + ("io_cancel", 3), + ("ioctl", 29), + ("io_destroy", 1), + ("io_getevents", 4), + ("io_pgetevents", 292), + ("ioprio_get", 31), + ("ioprio_set", 30), + ("io_setup", 0), + ("io_submit", 2), + ("io_uring_enter", 426), + ("io_uring_register", 427), + ("io_uring_setup", 425), + ("kcmp", 272), + ("kexec_file_load", 294), + ("kexec_load", 104), + ("keyctl", 219), + ("kill", 129), + ("landlock_add_rule", 445), + ("landlock_create_ruleset", 444), + ("landlock_restrict_self", 446), + ("lgetxattr", 9), + ("linkat", 37), + ("listen", 201), + ("listmount", 458), + ("listxattr", 11), + ("llistxattr", 12), + ("lookup_dcookie", 18), + ("lremovexattr", 15), + ("lseek", 62), + ("lsetxattr", 6), + ("lsm_get_self_attr", 459), + ("lsm_list_modules", 461), + ("lsm_set_self_attr", 460), + ("madvise", 233), + ("map_shadow_stack", 453), + ("mbind", 235), + ("membarrier", 283), + ("memfd_create", 279), + ("migrate_pages", 238), + ("mincore", 232), + ("mkdirat", 34), + ("mknodat", 33), + ("mlock", 228), + ("mlock2", 284), + ("mlockall", 230), + ("mmap", 222), + ("mount", 40), + ("mount_setattr", 442), + ("move_mount", 429), + ("move_pages", 239), + ("mprotect", 226), + ("mq_getsetattr", 185), + ("mq_notify", 184), + ("mq_open", 180), + ("mq_timedreceive", 183), + ("mq_timedsend", 182), + ("mq_unlink", 181), + ("mremap", 216), + ("mseal", 462), + ("msgctl", 187), + ("msgget", 186), + ("msgrcv", 188), + ("msgsnd", 189), + ("msync", 227), + ("munlock", 229), + ("munlockall", 231), + ("munmap", 215), + ("name_to_handle_at", 264), + ("nanosleep", 101), + ("newfstatat", 79), + ("nfsservctl", 42), + ("openat", 56), + ("openat2", 437), + ("open_by_handle_at", 265), + ("open_tree", 428), + ("perf_event_open", 241), + ("personality", 92), + ("pidfd_getfd", 438), + ("pidfd_open", 434), + ("pidfd_send_signal", 424), + ("pipe2", 59), + ("pivot_root", 41), + ("pkey_alloc", 289), + ("pkey_free", 290), + ("pkey_mprotect", 288), + ("ppoll", 73), + ("prctl", 167), + ("pread64", 67), + ("preadv", 69), + ("preadv2", 286), + ("prlimit64", 261), + ("process_madvise", 440), + ("process_mrelease", 448), + ("process_vm_readv", 270), + ("process_vm_writev", 271), + ("pselect6", 72), + ("ptrace", 117), + ("pwrite64", 68), + ("pwritev", 70), + ("pwritev2", 287), + ("quotactl", 60), + ("quotactl_fd", 443), + ("read", 63), + ("readahead", 213), + ("readlinkat", 78), + ("readv", 65), + ("reboot", 142), + ("recvfrom", 207), + ("recvmmsg", 243), + ("recvmsg", 212), + ("remap_file_pages", 234), + ("removexattr", 14), + ("renameat2", 276), + ("request_key", 218), + ("restart_syscall", 128), + ("rseq", 293), + ("rt_sigaction", 134), + ("rt_sigpending", 136), + ("rt_sigprocmask", 135), + ("rt_sigqueueinfo", 138), + ("rt_sigreturn", 139), + ("rt_sigsuspend", 133), + ("rt_sigtimedwait", 137), + ("rt_tgsigqueueinfo", 240), + ("sched_getaffinity", 123), + ("sched_getattr", 275), + ("sched_getparam", 121), + ("sched_get_priority_max", 125), + ("sched_get_priority_min", 126), + ("sched_getscheduler", 120), + ("sched_rr_get_interval", 127), + ("sched_setaffinity", 122), + ("sched_setattr", 274), + ("sched_setparam", 118), + ("sched_setscheduler", 119), + ("sched_yield", 124), + ("seccomp", 277), + ("semctl", 191), + ("semget", 190), + ("semop", 193), + ("semtimedop", 192), + ("sendfile", 71), + ("sendmmsg", 269), + ("sendmsg", 211), + ("sendto", 206), + ("setdomainname", 162), + ("setfsgid", 152), + ("setfsuid", 151), + ("setgid", 144), + ("setgroups", 159), + ("sethostname", 161), + ("setitimer", 103), + ("set_mempolicy", 237), + ("set_mempolicy_home_node", 450), + ("setns", 268), + ("setpgid", 154), + ("setpriority", 140), + ("setregid", 143), + ("setresgid", 149), + ("setresuid", 147), + ("setreuid", 145), + ("set_robust_list", 99), + ("setsid", 157), + ("setsockopt", 208), + ("set_tid_address", 96), + ("settimeofday", 170), + ("setuid", 146), + ("setxattr", 5), + ("shmat", 196), + ("shmctl", 195), + ("shmdt", 197), + ("shmget", 194), + ("shutdown", 210), + ("sigaltstack", 132), + ("signalfd4", 74), + ("socket", 198), + ("socketpair", 199), + ("splice", 76), + ("statfs", 43), + ("statmount", 457), + ("statx", 291), + ("swapoff", 225), + ("swapon", 224), + ("symlinkat", 36), + ("sync", 81), + ("sync_file_range", 84), + ("syncfs", 267), + ("sysinfo", 179), + ("syslog", 116), + ("tee", 77), + ("tgkill", 131), + ("timer_create", 107), + ("timer_delete", 111), + ("timerfd_create", 85), + ("timerfd_gettime", 87), + ("timerfd_settime", 86), + ("timer_getoverrun", 109), + ("timer_gettime", 108), + ("timer_settime", 110), + ("times", 153), + ("tkill", 130), + ("truncate", 45), + ("umask", 166), + ("umount2", 39), + ("uname", 160), + ("unlinkat", 35), + ("unshare", 97), + ("userfaultfd", 282), + ("utimensat", 88), + ("vhangup", 58), + ("vmsplice", 75), + ("wait4", 260), + ("waitid", 95), + ("write", 64), + ("writev", 66), + ] + .into_iter() + .collect() +} diff --git a/src/syscall_table/mod.rs b/src/syscall_table/mod.rs index f47fc3ca..f3439a82 100644 --- a/src/syscall_table/mod.rs +++ b/src/syscall_table/mod.rs @@ -2,6 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 OR BSD-3-Clause mod aarch64; +mod loongarch64; mod riscv64; mod x86_64; @@ -21,6 +22,7 @@ impl SyscallTable { TargetArch::aarch64 => aarch64::make_syscall_table(), TargetArch::x86_64 => x86_64::make_syscall_table(), TargetArch::riscv64 => riscv64::make_syscall_table(), + TargetArch::loongarch64 => loongarch64::make_syscall_table(), }, } } @@ -42,14 +44,17 @@ mod tests { let instance_x86_64 = SyscallTable::new(TargetArch::x86_64); let instance_aarch64 = SyscallTable::new(TargetArch::aarch64); let instance_riscv64 = SyscallTable::new(TargetArch::riscv64); + let instance_loongarch64 = SyscallTable::new(TargetArch::loongarch64); assert_eq!(instance_x86_64.get_syscall_nr("close").unwrap(), 3); assert_eq!(instance_aarch64.get_syscall_nr("close").unwrap(), 57); assert_eq!(instance_riscv64.get_syscall_nr("close").unwrap(), 57); + assert_eq!(instance_loongarch64.get_syscall_nr("close").unwrap(), 57); // invalid syscall name assert!(instance_x86_64.get_syscall_nr("nosyscall").is_none()); assert!(instance_aarch64.get_syscall_nr("nosyscall").is_none()); assert!(instance_riscv64.get_syscall_nr("nosyscall").is_none()); + assert!(instance_loongarch64.get_syscall_nr("nosyscall").is_none()); } } diff --git a/tools/generate_syscall_tables.sh b/tools/generate_syscall_tables.sh index ce1bd307..779d7177 100755 --- a/tools/generate_syscall_tables.sh +++ b/tools/generate_syscall_tables.sh @@ -20,10 +20,12 @@ test_mode=0 PATH_TO_X86_TABLE="$ROOT_DIR/src/syscall_table/x86_64.rs" PATH_TO_AARCH64_TABLE="$ROOT_DIR/src/syscall_table/aarch64.rs" PATH_TO_RISCV64_TABLE="$ROOT_DIR/src/syscall_table/riscv64.rs" +PATH_TO_LOONGARCH64_TABLE="$ROOT_DIR/src/syscall_table/loongarch64.rs" PATH_TO_X86_TEST_TABLE="$ROOT_DIR/src/syscall_table/test_x86_64.rs" PATH_TO_AARCH64_TEST_TABLE="$ROOT_DIR/src/syscall_table/test_aarch64.rs" PATH_TO_RISCV64_TEST_TABLE="$ROOT_DIR/src/syscall_table/test_riscv64.rs" +PATH_TO_LOONGARCH64_TEST_TABLE="$ROOT_DIR/src/syscall_table/test_loongarch64.rs" install_header() { make -C "$KERNEL_DIR/linux" ARCH="$1" INSTALL_HDR_PATH="$1-headers" headers_install &>/dev/null @@ -48,6 +50,8 @@ write_rust_syscall_table() { syscall_list=$(generate_syscall_list arm64) elif [ "$platform" == "riscv64" ]; then syscall_list=$(generate_syscall_list riscv) + elif [ "$platform" == "loongarch64" ]; then + syscall_list=$(generate_syscall_list loongarch) else die "Invalid platform" fi @@ -128,6 +132,9 @@ run_validation() { elif [[ $arch == "riscv64" ]]; then path_to_table=$PATH_TO_RISCV64_TABLE path_to_test_table=$PATH_TO_RISCV64_TEST_TABLE + elif [[ $arch == "loongarch64" ]]; then + path_to_table=$PATH_TO_LOONGARCH64_TABLE + path_to_test_table=$PATH_TO_LOONGARCH64_TEST_TABLE else die "Invalid platform" fi @@ -190,6 +197,7 @@ cleanup () { rm -rf $PATH_TO_X86_TEST_TABLE rm -rf $PATH_TO_AARCH64_TEST_TABLE rm -rf $PATH_TO_RISCV64_TEST_TABLE + rm -rf $PATH_TO_LOONGARCH64_TEST_TABLE fi } @@ -235,6 +243,16 @@ test() { validate_kernel_version "$kernel_version_riscv64" run_validation "riscv64" "$kernel_version_riscv64" + + # Run the validation for loongarch64 + echo "Validating table for loongarch64..." + + kernel_version_loongarch64=$(cat $PATH_TO_LOONGARCH64_TABLE | \ + awk -F '// Kernel version:' '{print $2}' | xargs) + + validate_kernel_version "$kernel_version_loongarch64" + + run_validation "loongarch64" "$kernel_version_loongarch64" } main() { @@ -262,6 +280,11 @@ main() { echo "Generating table for riscv64..." write_rust_syscall_table \ "$kernel_version" "riscv64" "$PATH_TO_RISCV64_TABLE" + + # generate syscall table for loongarch64 + echo "Generating table for loongarch64..." + write_rust_syscall_table \ + "$kernel_version" "loongarch64" "$PATH_TO_LOONGARCH64_TABLE" fi }