Index: usr.sbin/jail/command.c =================================================================== --- usr.sbin/jail/command.c +++ usr.sbin/jail/command.c @@ -677,6 +677,13 @@ paralimit--; return 1; } + } else { + /* + * The parent is ignoring SIGINT, with the expectation that the + * command should be terminated first, triggering appropriate + * cleanup here in jail(8). + */ + (void)signal(SIGINT, SIG_DFL); } if (bg) setsid(); Index: usr.sbin/jail/jail.c =================================================================== --- usr.sbin/jail/jail.c +++ usr.sbin/jail/jail.c @@ -153,6 +153,14 @@ cfname = CONF_FILE; JidFile = NULL; + /* + * Ignore any SIGINT during jail(8) operation. If we're running a + * command, then it should generally be terminated to trigger cleanup of + * the jail. Otherwise, we may end up with jails sticking around that + * should have been destroyed. + */ + (void)signal(SIGINT, SIG_IGN); + while ((ch = getopt(argc, argv, "cde:f:hiJ:lmn:p:qrRs:u:U:v")) != -1) { switch (ch) { case 'c':