Hi,
I noticed the Debian postgresql-common instance management wrappers do
not work properly on the Hurd. If an instance is started via the
pg_ctcluster wrapper (which is written in perl) via sudo, the wrapper
properly changes uid/gid of the resulting processes to postgres, but
then the postgres user cannot send signals to it:
|postgres@debian:~$ ps -ef | grep ^postgres.*17.main | head -1
|postgres 14971 1 - 0:00.07 /usr/lib/postgresql/17/bin/postgres -D
/var/lib/postgresql/17/main -c
config_file=/etc/postgresql/17/main/postgresql.conf
|postgres@debian:~$ LANG=C kill -s HUP 14971
|-bash: kill: (14971) - Operation not permitted
I can reproduce it with the attached minimal Perl script (101 is the
postgres uid/gid on my Hurd VM), which exhibits the same behaviour as
the pg_ctlcluster wrapper on the Hurd but works on Linux.
So I thought this was a bug in the Hurd Perl code, but then I ran the
perl script under strace on Linux, and it calls the following relevant
syscalls:
|setregid(101, -1) = 0
|setreuid(101, -1) = 0
|setresuid(-1, 101, -1) = 0
If I run those in a minimal C program (also attached), I can reproduce
the problem in C as well. That program issues to following auth_makeauth
calls via rpctrace:
| 8<--39(pid16773)->auth_makeauth ( 0 {0 0 1000} 0 {101 0}) = 0
52<--47(pid16773)
| 52<--47(pid16773)->auth_makeauth ( 0 {101 0 1000} 0 {101 0}) = 0
40<--62(pid16773)
| 40<--62(pid16773)->auth_makeauth ( 101 {101 0 1000} 0 {101 0}) = 0
61<--58(pid16773)
So is this a bug or just undefined behaviour in auth?
Michael
#!/bin/perl
my $uid = 101; # postgres pid
my $gid = 101; # postgres gid
print("switching to uid $uid and gid $gid\n");
$( = $gid;
$< = $uid;
$> = $uid;
die 'Could not change user id' if $< != $uid;
die 'Could not change group id' if $( != $gid;
print("euid: $>, uid: $<, gid: $( \n");
sleep(1000);
#define _GNU_SOURCE
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
int main (void) {
setregid(101, -1);
setreuid(101, -1);
setresuid(-1, 101, -1);
printf("euid: %d, uid: %d, gid: %d\n", geteuid(), getuid(), getgid());
sleep(10000);
}