kill: Negative PIDs kill the wrong group (truncated CLI-OPT parsing)

Running /bin/kill -PID will mis-parse the PID and take only the first digit, which leads to killing the wrong process group.

strace -ekill /bin/kill -SIGTERM -432
kill(-4, SIGTERM)                       = -1 ESRCH (No such process)
+++ exited with 0 +++

(Note how -4 is killed, not -432).

This results from this piece of code in kill.c:

        case '?':
            if (!isdigit(optopt)) {
                xwarnx(_("invalid argument %c"), optopt);
                print_usage(stderr);
            } else {
                /* Special case for signal digit negative
                 * PIDs */
        pid = (long)('0' - optopt);                                          /// <<<<<<<<<<<<<<<<<< WRONG
        if (!execute_kill((pid_t) pid, signo, use_sigqueue, sigval))
            exitvalue = EXIT_FAILURE;
                exit(exitvalue);
            }
            xerrx(EXIT_FAILURE, _("internal error"));
        default:
            print_usage(stderr);
        }

Reproducer:


docker run -it -e DEBIAN_FRONTEND=noninteractive ubuntu:24.04 bash -c "apt update && apt install --yes strace && strace -ekill /bin/kill -SIGTERM -432"

As far as I can tell this has been the case since at least:

commit f65121ef74f2792b4ed0e4e457e85d55eb5a80ef
Author: Craig Small <csmall@enc.com.au>
Date:   Sat Sep 26 09:13:13 2015 +1000

    kill: split out from skill/snice

But this works correctly in v3.3.17 which ships with Ubuntu v22.04

Edited by Gilad Naaman