Sending data in a signal

The well-known kill system call has been around for decades and is used to send a signal to another process. The most common use is to terminate or kill another process by sending the KILL or TERM signal but it can be used for a form of IPC, usually around giving the other process a “kick” to do something.

One thing that isn’t as well known is besides sending a signal to a process, you can send some data to it. This can either be an integer or a pointer and uses similar semantics to the known kill and signal handler. I came across this when there was a merge request for procps. The main changes are using sigqueue instead of kill in the sender and using a signal action not a signal handler in the receiver.

To illustrate this feature, I have a small set of programs called sender and receiver that will pass an integer between them.

The Sender

The sender program is extremely simple, use a random(ish) from time masked to two bytes, put it in the required union and send the lot to sendqueue.

# include <signal.h>
# include <stdlib.h>
# include <stdio.h>
# include <time.h>

int main(int argc, char **argv)
{
    union sigval sigval;
    pid_t pid;

    if (argc < 2 || (pid = atoi(argv[1])) < 0)
	return EXIT_FAILURE;
    sigval.sival_int = time(NULL) &amp; 0xff;
    printf("sender: sending %d to PID %d\n",
        sigval.sival_int, pid);
    sigqueue(pid, SIGUSR1, sigval);
    return EXIT_SUCCESS;
}

The key lines are 13 and 16 where the random (ish) integer is stored in the sigval union and then sent to the other process with the sigqueue.

The receiver

The receiver just sets up the signal handler, sends its PID (so I know what to tell the sender) and sits in a sleeping loop.

# include <stdio.h>
# include <stdlib.h>
# include <sys/types.h>
# include <unistd.h>
# include <signal.h>

void signal_handler(int signum, siginfo_t *siginfo, void *ucontext)
{
    if (signum != SIGUSR1) return;
    if (siginfo->si_code != SI_QUEUE) return;

    printf("receiver: Got value %d\n",
	    siginfo->si_int);
}

int main(int argc, char **argv)
{
    pid_t pid = getpid();
    struct sigaction signal_action;

    printf("receiver: PID is %d\n", pid);

    signal_action.sa_sigaction = signal_handler;
    sigemptyset (&amp;signal_action.sa_mask);
    signal_action.sa_flags = SA_SIGINFO;
    sigaction(SIGUSR1, &amp;signal_action, NULL);

    while(1) sleep(100);
    return EXIT_SUCCESS;
}

Lines 16-26 setup the signal handler. The main difference here is SA_SIGINFO used for the signal flags and sigaction references a sa_sigaction function rather than sa_handler.

We need to use a different function because the sigaction only is passed the signal number but we need more information, including the integer that the sender process stored in sigval.

Lines 7-14 are the signal handler function itself. It first checks that the receiver process got the correct signal (SIGUSR1 in this case) and that we got this signal from sigqueue because the type is SI_QUEUE. Checking the type of signal is important because different signals give you different data. For example, if you signalled this process with kill then si_int is undefined.

The result

As a proof of concept, the results are not terribly exciting. We see the sender say what it will be sending and the receiver saying it got it. It was useful to get some results, especially when things went wrong.

$ ./receiver &amp;
[1] 370216
receiver: PID is 370216
$ ./sender 370216
sender: sending 133 to (gdPID 370216
receiver: Got value 133

Gotchas

While testing the two process there was two gotchas I encountered.

GDB and the siginfo structure

The sigaction manual page shows a simple siginfo_t structure, however when looking at what is passed to the signal handler, it’s much more complicated.

(gdb) p *siginfo
$2 = {si_signo = 10, si_errno = 0, si_code = -1, __pad0 = 0, _sifields = {_pad = {371539, 1000, 11, 32766, 0 <repeats 24 times>}, _kill = {si_pid = 371539, si_uid = 1000}, _timer = {si_tid = 371539, 
      si_overrun = 1000, si_sigval = {sival_int = 11, sival_ptr = 0x7ffe0000000b}}, _rt = {si_pid = 371539, si_uid = 1000, si_sigval = {sival_int = 11, sival_ptr = 0x7ffe0000000b}}, _sigchld = {
      si_pid = 371539, si_uid = 1000, si_status = 11, si_utime = 0, si_stime = 0}, _sigfault = {si_addr = 0x3e80005ab53, si_addr_lsb = 11, _bounds = {_addr_bnd = {_lower = 0x0, _upper = 0x0}, _pkey = 0}}, 
    _sigpoll = {si_band = 4294967667539, si_fd = 11}, _sigsys = {_call_addr = 0x3e80005ab53, _syscall = 11, _arch = 32766}}}
(gdb) p siginfo->_sifields._rt.si_sigval.sival_int
$3 = 11

So the integer is stored in a union in a structure in a structure. Much harder to find than just simply sival_int.

The pointer is just a pointer

So perhaps sending an integer is not enough. The sigval is a union with an integer and a pointer. Could a string be sent instead? I changed line 13 of the sender so it used a string instead of an integer.

    sigval.sival_ptr = "Hello, World!"

The receiver needed a minor adjustment to print out the string. I tried this and the receiver segmentation faulted. What was going on?

The issue is the set of system calls does a simple passing of the values. So if the sender sends a pointer to a string located at 0x1234567 then the receiver will have a pointer to the same location. When the receiver tries to dereference the sival_ptr, it is pointing to memory that is not owned by it but by another process (the sender) so it segmentation faults.

The solution would be to use shared memory between the processes. The signal queue would then use the pointer to the shared memory and, in theory, all would be well.

WordPress 5.4

Debian packages for WordPress version 5.4 will be uploaded shortly. I’m just going through the install testing now.

One problem I have noticed is, at least for my setup, there is an issue with network updates. The problem is that WordPress will ask me if I want to update the network sites, I say yes and get a SSL error.

After lots of debugging, the problem is that the fsockopen option to use SNI is turned off for network updates. My sites need SNI so without this they just bomb out with a SSL handshake error.

I’m not sure what the real fix is, but my work-around was to temporary set the SNI in the fsockopen transport while doing the site updates.

The file you want wp-includes/Requests/Transport/fsockopen.php and in the request method of Requests_Transport_fsockopen you’ll see something like:

                       stream_context_set_option($context, array('ssl' => $context_options)); 
                } 
                else { 
                        $remote_socket = 'tcp://' . $host; 
                }

Just before the stream_context_set_option put the line:

                        $context_options['SNI_enabled'] = true;

Ugly but it works

procps-ng 3.3.16

procps-ng version 3.3.16 was released today. Besides some documentation and library updates, there were a few incremental changes.

Zombie Hunting with pgrep

Ever wanted to find zombies? Perhaps processes with other states? pgrep has a shiny new runstate flag to help you which will match process against the runstate. I’m curious to see the use-cases for this flag; it certainly will get used (e.g. find my zombies) but as some processes bounce in and out of states (think Run to Sleep and back) it might add some confusion.

Snice plays nice with PIDs

Speaking of ancient corpses, snice was not matching against PIDs. The best use for snice is to not use it (as the man page says) but some people do and some people noticed it never matched against PIDs.
The issue was reading the process state up to 128 bytes, but process state lines are always longer than 128 bytes so a bounds check failed and it skipped that PID (and every other PID too).

Top Enhancements

Top got a bunch of love again in this release. If you ever wanted your processes to be shown in fuchsia? Perhaps goldenrod? With some earlier versions of top, you could by directly editing the toprc file but now everyone can have more than the standard 8 colours!

If you use the other filters parameter for some fancy process filtering in top, it now will save that configuration.

Collapsed children (process names are weird) get some help. If you are in tree view, you can collapse or fold the children processes under the parent. Their CPU is also added to the parent so there are no “missing” CPU ticks.

For people who use the One True Editor (which is, of course, VIM) you can use the vim navigation keys to move through the process list.

Where to find it?

You’ll find the latest version of procps either at our git repository or download a tarball.

WordPress 5.2.4

Hot on the heels of WordPress version 5.2.3 which fixed a bunch of stuff we have WordPress 5.2.4 with fixes for six security issues.

There is a certain trick to matching up what the WordPress Blog thinks has been fixed and the changsets between the old version and the new. The curious thing is there were 6 changsets backported to older versions of WordPress, so you might think “six issues, six changesets, what’s the problem?”. The problem is that two of them fix the same thing (or one sort-of fixed it and the second really did) and another I couldn’t link to any vulnerability, BUT it was to do with directory traversal issue.

The hardest part of maintaining the Debian WordPress packages is the backporting. Trying to link the changes to the bugs is next to impossible so I generally import all the ones they have in the specific major version and hope for the best. This isn’t ideal, but information about what the actual bugs are and how they are fixed is not forthcoming.

WordPress 5.1.1

The Debian packages for WordPress version 5.1.1 are being updated as I write this. This is a security fix for WordPress that stops comments causing a cross-site scripting bug. It’s an important one to update.

The backports should happen soon so even if you are using Debian stable you’ll be covered.