/bin/kill in ubuntu22.04 has bug in killing process group

Bug #2025603 reported by li liao
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
procps (Ubuntu)
New
Undecided
Unassigned

Bug Description

root@master:~/software/test# cat /etc/os-release
PRETTY_NAME="Ubuntu 22.04.1 LTS"
NAME="Ubuntu"
VERSION_ID="22.04"
VERSION="22.04.1 LTS (Jammy Jellyfish)"
VERSION_CODENAME=jammy
ID=ubuntu
ID_LIKE=debian
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
UBUNTU_CODENAME=jammy

procps 2:3.3.17-6ubuntu2

root@master:~/software/test# strace -f kill -15 -2345
execve("/usr/bin/kill", ["kill", "-15", "-2345"], 0x7ffc2eb1ba28 /* 34 vars */) = 0
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) {
        printf("TERM, from [%d]\n", (int)sender_pid);
        return;
    }

    return;
}

int main(int argc, const char *argv[])
{
 int status;
 // prepare sigaction
    siga.sa_sigaction = *signal_handler;
    siga.sa_flags |= SA_SIGINFO; // get detail info
 if(sigaction(SIGTERM, &siga, NULL) != 0) {
  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(status));
  }
  if (WIFSIGNALED(status)) {
   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(PACKAGE, LOCALEDIR);
 textdomain(PACKAGE);
 atexit(close_stdout);

 if (argc < 2)
  kill_usage(stderr);

 signo = skill_sig_option(&argc, argv);
 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(_("invalid argument %c"), optopt);
    kill_usage(stderr);
   } else {
       /* Special case for signal digit negative
        * PIDs */
       pid = atoi(argv[optind-1]);
       if (kill((pid_t)pid, signo) != 0)
    exitvalue = EXIT_FAILURE;
       exit(exitvalue);
   }
   xerrx(EXIT_FAILURE, _("internal error"));
  default:
   kill_usage(stderr);
  }
}

```

maybe getopt_long parse negative pid(-2345) as opt,so pid = atoi(argv[optind-1]) become 0.

To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.