|
54 | 54 | enforceSocks5Auth bool |
55 | 55 | enforceSocks5TorAuth bool |
56 | 56 | killAllTracees bool |
| 57 | + coreDump bool |
57 | 58 | ) |
58 | 59 |
|
59 | 60 | var ( |
@@ -262,6 +263,7 @@ Note: |
262 | 263 | rootCmd.Flags().BoolVar(&enforceSocks5Auth, "enforce-socks5-auth", false, "Enforce SOCKS5 authentication (default: false)") |
263 | 264 | rootCmd.Flags().BoolVar(&enforceSocks5TorAuth, "enforce-socks5-tor-auth", false, "Enforce SOCKS5 authentication (default: false)") |
264 | 265 | rootCmd.Flags().BoolVar(&killAllTracees, "kill-all-tracees", false, "Kill all traced processes (default: false)") |
| 266 | + rootCmd.Flags().BoolVar(&coreDump, "core-dump", false, "Enable core dump (default: false)") |
265 | 267 |
|
266 | 268 | return rootCmd |
267 | 269 | } |
@@ -543,6 +545,14 @@ func handleIPEvent(fd uint64, pid uint32, address FullAddress) (uint64, int32, u |
543 | 545 | } else if logLeaks { |
544 | 546 | logger.Warn().Msgf("Proxy Leak detected, but allowed: %s", address.String()) |
545 | 547 | return 0, 0, unix.SECCOMP_USER_NOTIF_FLAG_CONTINUE |
| 548 | + } else if coreDump { |
| 549 | + logger.Info().Msgf("Dumping core for PID %d", pid) |
| 550 | + err := generateCoreDump(int(pid)) |
| 551 | + if err != nil { |
| 552 | + logger.Fatal().Msgf("Error generating core dump: %v", err) |
| 553 | + } |
| 554 | + |
| 555 | + os.Exit(0) |
546 | 556 | } else { |
547 | 557 | tgid, err := getTgid(pid) |
548 | 558 | if err != nil { |
@@ -628,10 +638,9 @@ func handleIPEvent(fd uint64, pid uint32, address FullAddress) (uint64, int32, u |
628 | 638 | logger.Fatal().Msgf("Error connecting to %s proxy: %v", redirect, err) |
629 | 639 | } |
630 | 640 | } |
631 | | - |
632 | | - // Default action is to block the connection |
633 | | - return 0, 0, 0 |
634 | 641 | } |
| 642 | + // Default action is to block the connection |
| 643 | + return 0, 0, 0 |
635 | 644 | } |
636 | 645 |
|
637 | 646 | func IsIPAddressAllowed(address FullAddress, fd uint64) bool { |
@@ -1255,3 +1264,40 @@ func validateSOCKS5Auth(username, password string) error { |
1255 | 1264 |
|
1256 | 1265 | return nil |
1257 | 1266 | } |
| 1267 | + |
| 1268 | +// generateCoreDump sends SIGABRT to the given PID to trigger a core dump. |
| 1269 | +// It does not attempt to move or rename the core dump file. |
| 1270 | +func generateCoreDump(pid int) error { |
| 1271 | + // Check if core dumps are allowed |
| 1272 | + if err := checkCoreDumpLimit(); err != nil { |
| 1273 | + return err |
| 1274 | + } |
| 1275 | + |
| 1276 | + // Send SIGABRT |
| 1277 | + if err := syscall.Kill(pid, syscall.SIGABRT); err != nil { |
| 1278 | + return fmt.Errorf("failed to send SIGABRT to PID %d: %w", pid, err) |
| 1279 | + } |
| 1280 | + return nil |
| 1281 | +} |
| 1282 | + |
| 1283 | +// checkCoreDumpLimit ensures core dumps are enabled and warns if size is limited. |
| 1284 | +func checkCoreDumpLimit() error { |
| 1285 | + var rlimit unix.Rlimit |
| 1286 | + |
| 1287 | + if err := unix.Getrlimit(unix.RLIMIT_CORE, &rlimit); err != nil { |
| 1288 | + return fmt.Errorf("failed to get RLIMIT_CORE: %w", err) |
| 1289 | + } |
| 1290 | + |
| 1291 | + switch { |
| 1292 | + case rlimit.Cur == 0: |
| 1293 | + return fmt.Errorf("core dumps are disabled (ulimit -c 0); enable with 'ulimit -c unlimited'") |
| 1294 | + |
| 1295 | + case rlimit.Cur != unix.RLIM_INFINITY: |
| 1296 | + fmt.Fprintf(os.Stderr, |
| 1297 | + "Warning: core dumps are limited to %d bytes.\n"+ |
| 1298 | + "For full dumps, consider setting 'ulimit -c unlimited'\n", rlimit.Cur) |
| 1299 | + } |
| 1300 | + |
| 1301 | + // Core dumps are enabled |
| 1302 | + return nil |
| 1303 | +} |
0 commit comments