/bin/kill in ubuntu22.04 has bug in killing process group
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
procps (Ubuntu) |
New
|
Undecided
|
Unassigned |
Bug Description
root@master:
PRETTY_NAME="Ubuntu 22.04.1 LTS"
NAME="Ubuntu"
VERSION_ID="22.04"
VERSION="22.04.1 LTS (Jammy Jellyfish)"
VERSION_
ID=ubuntu
ID_LIKE=debian
HOME_URL="https:/
SUPPORT_URL="https:/
BUG_REPORT_URL="https:/
PRIVACY_
UBUNTU_
procps 2:3.3.17-6ubuntu2
root@master:
execve(
brk(NULL) = 0x55ac1f787000
kill(0, SIGTERMstrace: Process 228286 detached
<detached ...>
Terminated
when pid is not exist negative pid(-2345), then become 0
test code:
```c
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <signal.h>
#include <errno.h>
#include <pthread.h>
void parentProcess();
void childProcess();
static struct sigaction siga;
static void signal_handler(int sig, siginfo_t *siginfo, void *context) {
// get pid of sender,
pid_t sender_pid = siginfo->si_pid;
if(sig == SIGTERM) {
return;
}
return;
}
int main(int argc, const char *argv[])
{
int status;
// prepare sigaction
siga.
siga.sa_flags |= SA_SIGINFO; // get detail info
if(sigaction(
printf("error sigaction()");
return errno;
}
int pid = fork();
if (pid != 0) {
parentProcess();
pid = wait(&status);
printf("End of process %d: \n", pid);
if (WIFEXITED(status)) {
printf("The child process ended with exit(%d).\n", WEXITSTATUS(
}
if (WIFSIGNALED(
printf("The child process ended with kill -%d.\n", WTERMSIG(status));
}
}
else
childProcess();
return 0;
}
void parentProcess()
{
pid_t pid = getpid();
char prefix[] = "Parent: ";
printf("%sPID:%d %s\n", prefix, pid, "");
}
void childProcess()
{
pid_t pid = getpid();
char prefix[] = "Child: ";
printf("%sPID:%d %s\n", prefix, pid, "");
char *args[4];
args[0] = "kill"; // first arg is the full path to the executable
args[1] = "-15";
args[2] = "-2345";
args[3] = NULL; // list of args must be NULL terminated
execv( "/bin/kill", args );
sleep(5);
}
```
pid equals 0, then sig is sent to every process in the process group of the calling process.
skill.c code:
```c
static void __attribute__ ((__noreturn__))
kill_main(int argc, char **argv)
{
int signo, i;
long pid;
int exitvalue = EXIT_SUCCESS;
union sigval sigval;
bool use_sigqueue = false;
char *sig_option;
static const struct option longopts[] = {
{"list", optional_argument, NULL, 'l'},
{"table", no_argument, NULL, 'L'},
{"signal", required_argument, NULL, 's'},
{"help", no_argument, NULL, 'h'},
{"version", no_argument, NULL, 'V'},
{"queue", required_argument, NULL, 'q'},
{NULL, 0, NULL, 0}
};
setlocale (LC_ALL, "");
bindtextdomain
textdomain(
atexit(
if (argc < 2)
kill_
signo = skill_sig_
if (signo < 0)
signo = SIGTERM;
opterr=0; /* suppress errors on -123 */
while ((i = getopt_long(argc, argv, "l::Ls:hVq:", longopts, NULL)) != -1)
switch (i) {
case '?':
if (!isdigit(optopt)) {
xwarnx(
kill_
} else {
/* Special case for signal digit negative
* PIDs */
pid = atoi(argv[
if (kill((pid_t)pid, signo) != 0)
exitvalue = EXIT_FAILURE;
}
xerrx(
default:
kill_
}
}
```
maybe getopt_long parse negative pid(-2345) as opt,so pid = atoi(argv[