Seccomp Filtering in Java: Comprehensive Security Sandboxing

Seccomp (Secure Computing Mode) is a Linux kernel feature that restricts the system calls available to a process. This guide covers Java-based Seccomp integration, policy management, and comprehensive application sandboxing.


Dependencies and Setup

1. Maven Dependencies
<properties>
<jnr-unixsocket.version>0.38.19</jnr-unixsocket.version>
<jna.version>5.13.0</jna.version>
<jackson.version>2.15.2</jackson.version>
</properties>
<dependencies>
<!-- JNR for native system calls -->
<dependency>
<groupId>com.github.jnr</groupId>
<artifactId>jnr-unixsocket</artifactId>
<version>${jnr-unixsocket.version}</version>
</dependency>
<!-- JNA for native access -->
<dependency>
<groupId>net.java.dev.jna</groupId>
<artifactId>jna</artifactId>
<version>${jna.version}</version>
</dependency>
<!-- JSON Processing -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
</dependency>
<!-- YAML Processing -->
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-yaml</artifactId>
<version>${jackson.version}</version>
</dependency>
<!-- Logging -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>2.0.7</version>
</dependency>
</dependencies>

Core Seccomp Integration

1. Native Seccomp Interface
package com.example.seccomp.native;
import com.sun.jna.*;
import com.sun.jna.ptr.PointerByReference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public interface SeccompLib extends Library {
SeccompLib INSTANCE = Native.load("seccomp", SeccompLib.class);
// Seccomp actions
int SCMP_ACT_KILL = 0x00000000;
int SCMP_ACT_TRAP = 0x00030000;
int SCMP_ACT_ERRNO(int errno) {
return 0x00050000 | (errno & 0x0000FFFF);
}
int SCMP_ACT_TRACE(int msg) {
return 0x7FF00000 | (msg & 0x0000FFFF);
}
int SCMP_ACT_ALLOW = 0x7FFF0000;
int SCMP_ACT_LOG = 0x7FFC0000;
// Filter attributes
int SCMP_FLTATR_ACT_DEFAULT = 0;
int SCMP_FLTATR_ACT_BADARCH = 1;
int SCMP_FLTATR_CTL_NNP = 2;
int SCMP_FLTATR_CTL_TSYNC = 3;
int SCMP_FLTATR_API_SYSRAWRC = 4;
// Architecture definitions
int SCMP_ARCH_NATIVE = 0;
int SCMP_ARCH_X86 = 3;
int SCMP_ARCH_X86_64 = 4;
int SCMP_ARCH_ARM = 1;
int SCMP_ARCH_AARCH64 = 2;
int SCMP_ARCH_MIPS = 5;
int SCMP_ARCH_MIPS64 = 6;
int SCMP_ARCH_MIPS64N32 = 7;
int SCMP_ARCH_MIPSEL = 8;
int SCMP_ARCH_MIPSEL64 = 9;
int SCMP_ARCH_MIPSEL64N32 = 10;
int SCMP_ARCH_PPC = 11;
int SCMP_ARCH_PPC64 = 12;
int SCMP_ARCH_PPC64LE = 13;
int SCMP_ARCH_S390 = 14;
int SCMP_ARCH_S390X = 15;
// Comparison operators
int SCMP_CMP_NE = 1;
int SCMP_CMP_LT = 2;
int SCMP_CMP_LE = 3;
int SCMP_CMP_EQ = 4;
int SCMP_CMP_GE = 5;
int SCMP_CMP_GT = 6;
int SCMP_CMP_MASKED_EQ = 7;
// Functions
int seccomp_init(int def_action);
int seccomp_reset(Pointer ctx, int def_action);
int seccomp_rule_add(Pointer ctx, int action, int syscall, int arg_cnt, Object... args);
int seccomp_rule_add_exact(Pointer ctx, int action, int syscall, int arg_cnt, Object... args);
int seccomp_rule_add_array(Pointer ctx, int action, int syscall, int arg_cnt, Pointer rule_arr);
int seccomp_syscall_resolve_name(Pointer ctx, String name);
int seccomp_syscall_resolve_name_arch(int arch_token, String name);
int seccomp_syscall_resolve_num_arch(int arch_token, int num);
int seccomp_arch_add(Pointer ctx, int arch_token);
int seccomp_arch_remove(Pointer ctx, int arch_token);
int seccomp_arch_exist(Pointer ctx, int arch_token);
int seccomp_attr_set(Pointer ctx, int attr, int value);
int seccomp_attr_get(Pointer ctx, int attr, IntByReference value);
int seccomp_load(Pointer ctx);
void seccomp_release(Pointer ctx);
String seccomp_version();
int seccomp_export_bpf(Pointer ctx, int fd);
int seccomp_export_pfc(Pointer ctx, int fd);
}
2. Java Seccomp Wrapper
package com.example.seccomp.core;
import com.example.seccomp.native.SeccompLib;
import com.sun.jna.Pointer;
import com.sun.jna.ptr.IntByReference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.FileDescriptor;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.*;
public class SeccompFilter {
private static final Logger logger = LoggerFactory.getLogger(SeccompFilter.class);
private final Pointer ctx;
private final Map<String, Integer> syscallCache;
private boolean loaded = false;
public SeccompFilter(int defaultAction) {
this.ctx = SeccompLib.INSTANCE.seccomp_init(defaultAction);
if (ctx == null) {
throw new SeccompException("Failed to initialize seccomp context");
}
this.syscallCache = new HashMap<>();
logger.debug("Initialized seccomp filter with default action: 0x{}", 
Integer.toHexString(defaultAction));
}
public SeccompFilter() {
this(SeccompLib.INSTANCE.SCMP_ACT_ALLOW); // Default: allow all
}
public void addRule(String syscallName, int action, SeccompArg... args) {
int syscall = resolveSyscall(syscallName);
if (syscall < 0) {
logger.warn("Unknown syscall: {}", syscallName);
return;
}
int result;
if (args == null || args.length == 0) {
result = SeccompLib.INSTANCE.seccomp_rule_add(ctx, action, syscall, 0);
} else {
// Convert args to native format
List<Object> nativeArgs = new ArrayList<>();
for (SeccompArg arg : args) {
nativeArgs.add(arg.toNative());
}
result = SeccompLib.INSTANCE.seccomp_rule_add(ctx, action, syscall, args.length, 
nativeArgs.toArray());
}
if (result < 0) {
throw new SeccompException("Failed to add rule for syscall: " + syscallName + 
", error: " + result);
}
logger.debug("Added rule: {} -> 0x{}", syscallName, Integer.toHexString(action));
}
public void addExactRule(String syscallName, int action, SeccompArg... args) {
int syscall = resolveSyscall(syscallName);
if (syscall < 0) {
logger.warn("Unknown syscall: {}", syscallName);
return;
}
int result;
if (args == null || args.length == 0) {
result = SeccompLib.INSTANCE.seccomp_rule_add_exact(ctx, action, syscall, 0);
} else {
List<Object> nativeArgs = new ArrayList<>();
for (SeccompArg arg : args) {
nativeArgs.add(arg.toNative());
}
result = SeccompLib.INSTANCE.seccomp_rule_add_exact(ctx, action, syscall, 
args.length, nativeArgs.toArray());
}
if (result < 0) {
throw new SeccompException("Failed to add exact rule for syscall: " + syscallName);
}
logger.debug("Added exact rule: {} -> 0x{}", syscallName, Integer.toHexString(action));
}
public void allowSyscall(String syscallName) {
addRule(syscallName, SeccompLib.INSTANCE.SCMP_ACT_ALLOW);
}
public void killSyscall(String syscallName) {
addRule(syscallName, SeccompLib.INSTANCE.SCMP_ACT_KILL);
}
public void trapSyscall(String syscallName) {
addRule(syscallName, SeccompLib.INSTANCE.SCMP_ACT_TRAP);
}
public void errnoSyscall(String syscallName, int errno) {
addRule(syscallName, SeccompLib.INSTANCE.SCMP_ACT_ERRNO(errno));
}
public void logSyscall(String syscallName) {
addRule(syscallName, SeccompLib.INSTANCE.SCMP_ACT_LOG);
}
public void addArchitecture(int arch) {
int result = SeccompLib.INSTANCE.seccomp_arch_add(ctx, arch);
if (result < 0) {
throw new SeccompException("Failed to add architecture: " + arch);
}
logger.debug("Added architecture: {}", arch);
}
public void removeArchitecture(int arch) {
int result = SeccompLib.INSTANCE.seccomp_arch_remove(ctx, arch);
if (result < 0) {
throw new SeccompException("Failed to remove architecture: " + arch);
}
logger.debug("Removed architecture: {}", arch);
}
public boolean hasArchitecture(int arch) {
int result = SeccompLib.INSTANCE.seccomp_arch_exist(ctx, arch);
return result == 0;
}
public void setAttribute(int attribute, int value) {
int result = SeccompLib.INSTANCE.seccomp_attr_set(ctx, attribute, value);
if (result < 0) {
throw new SeccompException("Failed to set attribute: " + attribute + " = " + value);
}
logger.debug("Set attribute {} = {}", attribute, value);
}
public int getAttribute(int attribute) {
IntByReference value = new IntByReference();
int result = SeccompLib.INSTANCE.seccomp_attr_get(ctx, attribute, value);
if (result < 0) {
throw new SeccompException("Failed to get attribute: " + attribute);
}
return value.getValue();
}
public void load() {
if (loaded) {
throw new IllegalStateException("Seccomp filter already loaded");
}
int result = SeccompLib.INSTANCE.seccomp_load(ctx);
if (result < 0) {
throw new SeccompException("Failed to load seccomp filter, error: " + result);
}
loaded = true;
logger.info("Seccomp filter loaded successfully");
}
public void exportBpf(FileOutputStream fos) throws IOException {
FileDescriptor fd = fos.getFD();
int result = SeccompLib.INSTANCE.seccomp_export_bpf(ctx, getFdInt(fd));
if (result < 0) {
throw new SeccompException("Failed to export BPF, error: " + result);
}
logger.debug("Exported BPF to file descriptor: {}", getFdInt(fd));
}
public void exportPfc(FileOutputStream fos) throws IOException {
FileDescriptor fd = fos.getFD();
int result = SeccompLib.INSTANCE.seccomp_export_pfc(ctx, getFdInt(fd));
if (result < 0) {
throw new SeccompException("Failed to export PFC, error: " + result);
}
logger.debug("Exported PFC to file descriptor: {}", getFdInt(fd));
}
public String getVersion() {
return SeccompLib.INSTANCE.seccomp_version();
}
public void reset(int defaultAction) {
int result = SeccompLib.INSTANCE.seccomp_reset(ctx, defaultAction);
if (result < 0) {
throw new SeccompException("Failed to reset seccomp filter");
}
syscallCache.clear();
loaded = false;
logger.debug("Reset seccomp filter with default action: 0x{}", 
Integer.toHexString(defaultAction));
}
public void release() {
if (ctx != null) {
SeccompLib.INSTANCE.seccomp_release(ctx);
logger.debug("Released seccomp context");
}
}
private int resolveSyscall(String syscallName) {
return syscallCache.computeIfAbsent(syscallName, name -> {
int syscall = SeccompLib.INSTANCE.seccomp_syscall_resolve_name(ctx, name);
if (syscall < 0) {
logger.warn("Failed to resolve syscall: {}", name);
}
return syscall;
});
}
private int getFdInt(FileDescriptor fd) {
try {
return (int) FileDescriptor.class.getDeclaredField("fd").get(fd);
} catch (Exception e) {
throw new SeccompException("Failed to get file descriptor integer", e);
}
}
public boolean isLoaded() {
return loaded;
}
@Override
protected void finalize() throws Throwable {
try {
release();
} finally {
super.finalize();
}
}
}
package com.example.seccomp.core;
import com.sun.jna.Structure;
@Structure.FieldOrder({"k", "op", "datum_a", "datum_b"})
public class SeccompArg extends Structure {
public int k;
public int op;
public long datum_a;
public long datum_b;
public SeccompArg(int argIndex, int operator, long valueA, long valueB) {
this.k = argIndex;
this.op = operator;
this.datum_a = valueA;
this.datum_b = valueB;
}
public static SeccompArg eq(int argIndex, long value) {
return new SeccompArg(argIndex, 4, value, 0); // SCMP_CMP_EQ = 4
}
public static SeccompArg ne(int argIndex, long value) {
return new SeccompArg(argIndex, 1, value, 0); // SCMP_CMP_NE = 1
}
public static SeccompArg lt(int argIndex, long value) {
return new SeccompArg(argIndex, 2, value, 0); // SCMP_CMP_LT = 2
}
public static SeccompArg le(int argIndex, long value) {
return new SeccompArg(argIndex, 3, value, 0); // SCMP_CMP_LE = 3
}
public static SeccompArg ge(int argIndex, long value) {
return new SeccompArg(argIndex, 5, value, 0); // SCMP_CMP_GE = 5
}
public static SeccompArg gt(int argIndex, long value) {
return new SeccompArg(argIndex, 6, value, 0); // SCMP_CMP_GT = 6
}
public static SeccompArg maskedEq(int argIndex, long mask, long value) {
return new SeccompArg(argIndex, 7, value, mask); // SCMP_CMP_MASKED_EQ = 7
}
public Object toNative() {
return this.getPointer();
}
}
package com.example.seccomp.core;
public class SeccompException extends RuntimeException {
public SeccompException(String message) {
super(message);
}
public SeccompException(String message, Throwable cause) {
super(message, cause);
}
}
3. Seccomp Policy Manager

```java
package com.example.seccomp.policy;

import com.example.seccomp.core.SeccompFilter;
import com.example.seccomp.core.SeccompArg;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.; import java.util.;

public class SeccompPolicyManager {

private static final Logger logger = LoggerFactory.getLogger(SeccompPolicyManager.class);
private final ObjectMapper objectMapper;
private final ObjectMapper yamlMapper;
private final Map<String, SeccompPolicy> policies;
private SeccompFilter currentFilter;
public SeccompPolicyManager() {
this.objectMapper = new ObjectMapper();
this.yamlMapper = new ObjectMapper(new YAMLFactory());
this.policies = new HashMap<>();
}
public SeccompPolicy loadPolicy(String name, File policyFile) throws IOException {
SeccompPolicy policy;
if (policyFile.getName().endsWith(".json")) {
policy = objectMapper.readValue(policyFile, SeccompPolicy.class);
} else if (policyFile.getName().endsWith(".yaml") || policyFile.getName().endsWith(".yml")) {
policy = yamlMapper.readValue(policyFile, SeccompPolicy.class);
} else {
throw new IllegalArgumentException("Unsupported policy file format: " + policyFile.getName());
}
policy.setName(name);
policies.put(name, policy);
logger.info("Loaded seccomp policy: {} from {}", name, policyFile.getAbsolutePath());
return policy;
}
public SeccompPolicy createPolicy(String name, PolicyConfig config) {
SeccompPolicy policy = new SeccompPolicy();
policy.setName(name);
policy.setDefaultAction(config.getDefaultAction());
policy.setArchitectures(config.getArchitectures());
policy.setSyscalls(new ArrayList<>());
// Add default syscalls based on profile
if (config.getProfile() != null) {
applyProfile(policy, config.getProfile());
}
// Add custom syscalls
if (config.getAdditionalSyscalls() != null) {
config.getAdditionalSyscalls().forEach((syscall, action) -> 
policy.addSyscall(new SyscallRule(syscall, action)));
}
policies.put(name, policy);
logger.info("Created seccomp policy: {}", name);
return policy;
}
public void applyPolicy(String policyName) {
SeccompPolicy policy = policies.get(policyName);
if (policy == null) {
throw new IllegalArgumentException("Policy not found: " + policyName);
}
applyPolicy(policy);
}
public void applyPolicy(SeccompPolicy policy) {
if (currentFilter != null && currentFilter.isLoaded()) {
logger.warn("Seccomp filter already loaded, creating new filter");
}
// Create new filter
currentFilter = new SeccompFilter(policy.getDefaultAction());
// Add architectures
if (policy.getArchitectures() != null) {
for (String arch : policy.getArchitectures()) {
int archToken = mapArchitecture(arch);
currentFilter.addArchitecture(archToken);
}
}
// Add syscall rules
if (policy.getSyscalls() != null) {
for (SyscallRule rule : policy.getSyscalls()) {
applySyscallRule(currentFilter, rule);
}
}
// Set attributes
if (policy.getAttributes() != null) {
policy.getAttributes().forEach((attr, value) -> 
currentFilter.setAttribute(mapAttribute(attr), value));
}
// Load the filter
currentFilter.load();
logger.info("Applied seccomp policy: {}", policy.getName());
}
public void savePolicy(String policyName, File outputFile) throws IOException {
SeccompPolicy policy = policies.get(policyName);
if (policy == null) {
throw new IllegalArgumentException("Policy not found: " + policyName);
}
if (outputFile.getName().endsWith(".json")) {
objectMapper.writerWithDefaultPrettyPrinter().writeValue(outputFile, policy);
} else if (outputFile.getName().endsWith(".yaml") || outputFile.getName().endsWith(".yml")) {
yamlMapper.writerWithDefaultPrettyPrinter().writeValue(outputFile, policy);
} else {
throw new IllegalArgumentException("Unsupported output format: " + outputFile.getName());
}
logger.info("Saved policy {} to {}", policyName, outputFile.getAbsolutePath());
}
public void exportCurrentFilter(File bpfFile, File pfcFile) throws IOException {
if (currentFilter == null || !currentFilter.isLoaded()) {
throw new IllegalStateException("No seccomp filter loaded");
}
if (bpfFile != null) {
try (FileOutputStream fos = new FileOutputStream(bpfFile)) {
currentFilter.exportBpf(fos);
logger.debug("Exported BPF to: {}", bpfFile.getAbsolutePath());
}
}
if (pfcFile != null) {
try (FileOutputStream fos = new FileOutputStream(pfcFile)) {
currentFilter.exportPfc(fos);
logger.debug("Exported PFC to: {}", pfcFile.getAbsolutePath());
}
}
}
public SeccompPolicy getPolicy(String name) {
return policies.get(name);
}
public Map<String, SeccompPolicy> getAllPolicies() {
return new HashMap<>(policies);
}
public void removePolicy(String name) {
policies.remove(name);
logger.info("Removed policy: {}", name);
}
public String getCurrentFilterVersion() {
if (currentFilter == null) {
return "No filter loaded";
}
return currentFilter.getVersion();
}
private void applyProfile(SeccompPolicy policy, SecurityProfile profile) {
switch (profile) {
case RESTRICTED:
applyRestrictedProfile(policy);
break;
case BASELINE:
applyBaselineProfile(policy);
break;
case PRIVILEGED:
applyPrivilegedProfile(policy);
break;
case DOCKER_DEFAULT:
applyDockerDefaultProfile(policy);
break;
default:
logger.warn("Unknown profile: {}", profile);
}
}
private void applyRestrictedProfile(SeccompPolicy policy) {
// Very restrictive profile - only essential syscalls
String[] allowedSyscalls = {
"read", "write", "close", "fstat", "lseek", "mmap", "mprotect",
"munmap", "brk", "rt_sigaction", "rt_sigprocmask", "rt_sigreturn",
"ioctl", "pread64", "pwrite64", "readv", "writev", "access",
"pipe", "select", "dup", "dup2", "getpid", "socketcall",
"fcntl", "fsync", "fdatasync", "truncate", "ftruncate",
"getcwd", "chdir", "fchdir", "rename", "mkdir", "rmdir",
"creat", "link", "unlink", "symlink", "readlink", "chmod",
"fchmod", "chown", "fchown", "lchown", "umask", "gettimeofday",
"getrlimit", "getrusage", "sysinfo", "times", "ptrace",
"getuid", "syscall", "exit", "exit_group", "wait4", "kill",
"uname", "semget", "semop", "semctl", "shmdt", "msgrcv",
"msgsnd", "msgctl", "fcntl64", "getdents", "getdents64",
"gettid", "time", "futex", "sched_setaffinity", "sched_getaffinity",
"set_thread_area", "exit_group", "epoll_wait", "epoll_ctl",
"tgkill", "utimes", "vserver", "open", "openat"
};
for (String syscall : allowedSyscalls) {
policy.addSyscall(new SyscallRule(syscall, "ALLOW"));
}
// Deny dangerous syscalls
String[] deniedSyscalls = {
"execve", "fork", "vfork", "clone", "kill", "ptrace",
"capset", "setuid", "setgid", "setgroups", "setreuid",
"setregid", "setresuid", "setresgid", "setfsuid", "setfsgid",
"acct", "chroot", "personality", "setpriority", "sched_setscheduler",
"iopl", "ioperm", "create_module", "init_module", "delete_module",
"quotactl", "nfsservctl", "mount", "umount2", "swapon", "swapoff",
"syslog", "reboot", "sethostname", "setdomainname"
};
for (String syscall : deniedSyscalls) {
policy.addSyscall(new SyscallRule(syscall, "KILL"));
}
policy.setDefaultAction("ERRNO(EPERM)");
}
private void applyBaselineProfile(SeccompPolicy policy) {
// Baseline profile - common syscalls for typical applications
applyRestrictedProfile(policy); // Start with restricted
// Additional allowed syscalls
String[] additionalAllowed = {
"execve", "fork", "clone", "waitpid", "wait4",
"getppid", "getpgrp", "setsid", "setpgid", "getsid",
"prctl", "arch_prctl", "set_tid_address", "set_robust_list",
"get_robust_list", "setrlimit", "chroot", "sync", "fsync",
"fdatasync", "truncate", "ftruncate", "getdents", "getdents64",
"getcwd", "chdir", "fchdir", "rename", "mkdir", "rmdir",
"creat", "link", "unlink", "symlink", "readlink", "chmod",
"fchmod", "chown", "fchown", "lchown", "umask", "gettimeofday",
"getrlimit", "getrusage", "sysinfo", "times", "ptrace",
"getuid", "syscall", "exit", "exit_group", "wait4", "kill"
};
for (String syscall : additionalAllowed) {
policy.addSyscall(new SyscallRule(syscall, "ALLOW"));
}
policy.setDefaultAction("ALLOW");
}
private void applyPrivilegedProfile(SeccompPolicy policy) {
// Privileged profile - allow most syscalls (for trusted applications)
policy.setDefaultAction("ALLOW");
// Only block the most dangerous syscalls
String[] blockedSyscalls = {
"keyctl", "add_key", "request_key", "iopl", "ioperm",
"sysctl", "nfsservctl", "quotactl", "swapon", "swapoff",
"syslog", "reboot"
};
for (String syscall : blockedSyscalls) {
policy.addSyscall(new SyscallRule(syscall, "KILL"));
}
}
private void applyDockerDefaultProfile(SeccompPolicy policy) {
// Docker's default seccomp profile (simplified)
String[] allowedSyscalls = {
"accept", "accept4", "access", "alarm", "bind", "brk", "capget",
"capset", "chdir", "chmod", "chown", "chown32", "clock_getres",
"clock_gettime", "clock_nanosleep", "close", "connect", "copy_file_range",
"creat", "dup", "dup2", "dup3", "epoll_create", "epoll_create1",
"epoll_ctl", "epoll_ctl_old", "epoll_pwait", "epoll_wait", "epoll_wait_old",
"eventfd", "eventfd2", "execve", "execveat", "exit", "exit_group",
"faccessat", "fadvise64", "fadvise64_64", "fallocate", "fanotify_mark",
"fchdir", "fchmod", "fchmodat", "fchown", "fchown32", "fchownat",
"fcntl", "fcntl64", "fdatasync", "fgetxattr", "flistxattr", "flock",
"fork", "fremovexattr", "fsetxattr", "fstat", "fstat64", "fstatat64",
"fstatfs", "fstatfs64", "fsync", "ftruncate", "ftruncate64", "futex",
"futimesat", "getcpu", "getcwd", "getdents", "getdents64", "getegid",
"getegid32", "geteuid", "geteuid32", "getgid", "getgid32", "getgroups",
"getgroups32", "getitimer", "getpeername", "getpgid", "getpgrp",
"getpid", "getppid", "getpriority", "getrandom", "getresgid",
"getresgid32", "getresuid", "getresuid32", "getrlimit", "get_robust_list",
"getrusage", "getsid", "getsockname", "getsockopt", "get_thread_area",
"gettid", "gettimeofday", "getuid", "getuid32", "getxattr", "inotify_add_watch",
"inotify_init", "inotify_init1", "inotify_rm_watch", "io_cancel", "ioctl",
"io_destroy", "io_getevents", "ioprio_get", "ioprio_set", "io_setup",
"io_submit", "ipc", "kill", "lchown", "lchown32", "lgetxattr", "link",
"linkat", "listen", "listxattr", "llistxattr", "lremovexattr", "lseek",
"lsetxattr", "lstat", "lstat64", "madvise", "memfd_create", "mincore",
"mkdir", "mkdirat", "mknod", "mknodat", "mlock", "mlock2", "mlockall",
"mmap", "mmap2", "mprotect", "mq_getsetattr", "mq_notify", "mq_open",
"mq_timedreceive", "mq_timedsend", "mq_unlink", "mremap", "msgctl",
"msgget", "msgrcv", "msgsnd", "msync", "munlock", "munlockall",
"munmap", "nanosleep", "newfstatat", "_newselect", "open", "openat",
"pause", "pipe", "pipe2", "poll", "ppoll", "prctl", "pread64",
"preadv", "preadv2", "prlimit64", "pselect6", "ptrace", "pwrite64",
"pwritev", "pwritev2", "read", "readahead", "readlink", "readlinkat",
"readv", "recv", "recvfrom", "recvmmsg", "recvmsg", "remap_file_pages",
"removexattr", "rename", "renameat", "renameat2", "restart_syscall",
"rmdir", "rt_sigaction", "rt_sigpending", "rt_sigprocmask", "rt_sigqueueinfo",
"rt_sigreturn", "rt_sigsuspend", "rt_sigtimedwait", "rt_tgsigqueueinfo",
"sched_getaffinity", "sched_getattr", "sched_getparam", "sched_get_priority_max",
"sched_get_priority_min", "sched_getscheduler", "sched_rr_get_interval",
"sched_setaffinity", "sched_setattr", "sched_setparam", "sched_setscheduler",
"sched_yield", "seccomp", "select", "semctl", "semget", "semop", "semtimedop",
"send", "sendfile", "sendfile64", "sendmmsg", "sendmsg", "sendto", "setfsgid",
"setfsgid32", "setfsuid", "setfsuid32", "setgid", "setgid32", "setgroups",
"setgroups32", "setitimer", "setpgid", "setpriority", "setregid", "setregid32",
"setresgid", "setresgid32", "setresuid", "setresuid32", "setreuid",
"setreuid32", "setrlimit", "set_robust_list", "setsid", "setsockopt",
"set_thread_area", "set_tid_address", "setuid", "setuid32", "setxattr",
"shmat", "shmctl", "shmdt", "shmget", "shutdown", "sigaltstack", "signalfd",
"signalfd4", "sigprocmask", "sigreturn", "socket", "socketcall", "socketpair",
"splice", "stat", "stat64", "statfs", "statfs64", "statx", "symlink",
"symlinkat", "sync", "sync_file_range", "syncfs", "sysinfo", "tee", "tgkill",
"time", "timer_create", "timer_delete", "timer_getoverrun", "timer_gettime",
"timer_settime", "timerfd_create", "timerfd_gettime", "timerfd_settime",
"times", "tkill", "truncate", "truncate64", "ugetrlimit", "umask", "uname",
"unlink", "unlinkat", "utime", "utimensat", "utimes", "vfork", "vmsplice",
"wait4", "waitid", "waitpid", "write", "writev"
};
for (String syscall : allowedSyscalls) {
policy.addSyscall(new SyscallRule(syscall, "ALLOW"));
}
policy.setDefaultAction("SCMP_ACT_ERRNO(EPERM)");

Advanced Java Container Security, Sandboxing & Trusted Runtime Environments

https://macronepal.com/blog/sandboxing-java-applications-implementing-landlock-lsm-for-enhanced-container-security/
Explains using Linux Landlock LSM to sandbox Java applications by restricting file system and resource access without root privileges, improving application-level isolation and reducing attack surface.

https://macronepal.com/blog/gvisor-sandbox-integration-in-java-complete-guide/
Explains integrating gVisor with Java to provide a user-space kernel sandbox that intercepts system calls and isolates applications from the host operating system for stronger security.

https://macronepal.com/blog/selinux-for-java-mandatory-access-control-for-jvm-applications/
Explains how SELinux enforces Mandatory Access Control (MAC) policies on Java applications, strictly limiting what files, processes, and network resources the JVM can access.

https://macronepal.com/java/a-comprehensive-guide-to-intel-sgx-sdk-integration-in-java/
Explains Intel SGX integration in Java, allowing sensitive code and data to run inside secure hardware enclaves that remain protected even if the OS is compromised.

https://macronepal.com/blog/building-a-microvm-runtime-with-aws-firecracker-in-java-a-comprehensive-guide/
Explains using AWS Firecracker microVMs with Java to run workloads in lightweight virtual machines that provide strong isolation with near-container performance efficiency.

https://macronepal.com/blog/enforcing-mandatory-access-control-implementing-apparmor-for-java-applications/
Explains AppArmor security profiles for Java applications, enforcing rules that restrict file access, execution rights, and system-level permissions.

https://macronepal.com/blog/rootless-containers-in-java-secure-container-operations-without-root/
Explains running Java applications in rootless containers using Linux user namespaces so containers operate securely without requiring root privileges.

https://macronepal.com/blog/unlocking-container-security-harnessing-user-namespaces-in-java/
Explains Linux user namespaces, which isolate user and group IDs inside containers to improve privilege separation and enhance container security for Java workloads.

https://macronepal.com/blog/secure-bootstrapping-in-java-comprehensive-trust-establishment-framework/
Explains secure bootstrapping in Java, focusing on how systems establish trust during startup using secure key management, identity verification, and trusted configuration loading.

https://macronepal.com/blog/securing-java-applications-with-chainguard-wolfi-a-comprehensive-guide-2/
Explains using Chainguard/Wolfi minimal container images to secure Java applications by reducing unnecessary packages, minimizing vulnerabilities, and providing a hardened runtime environment.

Leave a Reply

Your email address will not be published. Required fields are marked *


Macro Nepal Helper