iptables 1.8.8 fails with error code 111 but iptables 1.8.7 succeeds with same script

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hello,

I use Arch Linux. Apache 2.4.54 and iptables 1.8.8 (nft based).

I have a setuid script, given below, which runs via apache httpd and simply calls "iptables -w -nvL INPUT" and gives the output.

But with iptables 1.8.8 it fails with error code 111 (undocumented code)

> curl http://127.0.0.1/ipt.e
EUID = 0, EGID=33
iptables exited with exit code=111
iptables exited with exit code=111


It doesn't even print any error message. (not even to httpd error log - via stderr)

But if I downgrade to iptables 1.8.7, it works as expected.

> curl http://127.0.0.1/ipt.e
EUID = 0, EGID=33
iptables v1.8.7 (nf_tables)
iptables exited with exit code=0
Chain INPUT (policy DROP 290 packets, 27644 bytes)
 pkts bytes target     prot opt in     out source               destination
<output cut>
iptables exited with exit code=0


So it appears to be some kind of bug introduced in 1.8.8.

Can someone guide / check?

The C script follows: (Can be used for testing)

> cat ipt.c
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/wait.h>

extern char **environ;

pid_t my_wait(int *status, pid_t pid, int options)
{
    pid_t got_pid;
    while ((got_pid = waitpid(pid, status, options)) == (pid_t)-1) {
        if (errno != EINTR) return -1;
        errno = 0;
    }
    return got_pid;
}

int my_system(const char *program, char *const argv[])
{
    pid_t pid = fork();
    if (pid==(pid_t)-1) return -1;
    if (!pid) { execve(program, argv, environ); exit(127); }

    int status = -1;
    return ((my_wait(&status, pid, 0) == (pid_t)-1) ? -1 : status);
}

int main(int argc, char **main_argv)
{
    printf ("Content-type: text/plain\n\n");
    printf ("EUID = %d, EGID=%d\n", geteuid(), getegid());
    fflush (stdout);

    int i = 0;
    static char *argv[10];
    argv[i++] = (char *) "iptables";
    argv[i++] = (char *) "-w";
    argv[i++] = (char *) "--version";
    argv[i++] = NULL;
    int wstatus = my_system ("/usr/bin/iptables", argv);
    fflush (stdout);
    if (WIFEXITED(wstatus)) printf("iptables exited with exit code=%d\n", WEXITSTATUS(wstatus));
    else printf("something went wrong in calling iptables\n");
    fflush (stdout);

    i = 2;
    argv[i++] = (char *) "-nvL";
    argv[i++] = (char *) "INPUT";
    argv[i++] = NULL;
    wstatus = my_system ("/usr/bin/iptables", argv);
    fflush (stdout);
    if (WIFEXITED(wstatus)) printf("iptables exited with exit code=%d\n", WEXITSTATUS(wstatus));
    else printf("something went wrong in calling iptables\n");
    fflush (stdout);

    return 0;
}

# compiling and setting setuid bit
> cc ipt.c
> mv a.out /srv/http/ipt.e
> chown root:http /srv/http/ipt.e
> chmod 750 /srv/http/ipt.e
> chmod u+s /srv/http/ipt.e




[Index of Archives]     [Linux Netfilter Development]     [Linux Kernel Networking Development]     [Netem]     [Berkeley Packet Filter]     [Linux Kernel Development]     [Advanced Routing & Traffice Control]     [Bugtraq]

  Powered by Linux