/*
 * Copyright (c) 2020 Andrew G Morgan <morgan@kernel.org>
 *
 * This program exploit demonstrates why libcap alone in a
 * multithreaded C/C++ program is inherently vulnerable to privilege
 * escalation.
 *
 * The code also serves as a demonstration of how linking with libpsx
 * can eliminate this vulnerability by maintaining a process wide
 * common security state.
 *
 * The basic idea (which is well known and why POSIX stipulates "posix
 * semantics" for security relevant state at the abstraction of a
 * process) is that, because of shared memory, if a single thread alone
 * is vulnerable to code injection, then it can cause any other thread
 * to execute arbitrary code. As such, if all but one thread drops
 * privilege, privilege escalation is somewhat trivial.
 */
#include <pthread.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/capability.h>
#include <sys/types.h>

/* thread coordination */
pthread_mutex_t mu;
pthread_cond_t cond;
int hits;

/* evidence of highest privilege attained */
ssize_t greatest_len;
char *text;

/*
 * interrupt handler - potentially watching for an opportunity to
 * perform an exploit when invoked as a privileged thread.
 */
static void handler(int signum, siginfo_t *info, void *ignore) {
    ssize_t length;
    char *working;
    pthread_mutex_lock(&mu);

    cap_t caps = cap_get_proc();
    working = cap_to_text(caps, &length);
    if (length > greatest_len) {
	/*
	 * This is where the exploit code might go.
	 */
	cap_free(text);
	text = working;
	greatest_len = length;
    }
    cap_free(caps);
    hits++;

    pthread_cond_signal(&cond);
    pthread_mutex_unlock(&mu);

}

/*
 * privileged thread code (imagine it doing whatever needs privilege).
 */
static void *victim(void *args) {
    pthread_mutex_lock(&mu);
    hits = 1;
    printf("started privileged thread\n");
    pthread_cond_signal(&cond);
    pthread_mutex_unlock(&mu);

    pthread_mutex_lock(&mu);
    while (hits < 2) {
	pthread_cond_wait(&cond, &mu);
    }
    pthread_mutex_unlock(&mu);

    return NULL;
}

int main(int argc, char **argv) {
    pthread_t peer;
    cap_t caps = cap_init();
    struct sigaction sig_action;

    printf("program starting\n");
    if (pthread_create(&peer, NULL, victim, NULL)) {
	perror("unable to start the victim thread");
	exit(1);
    }

    /*
     * Wait until the peer thread is fully up.
     */
    pthread_mutex_lock(&mu);
    while (hits < 1) {
	pthread_cond_wait(&cond, &mu);
    }
    pthread_mutex_unlock(&mu);

    printf("dropping privilege from main process thread\n");

    if (cap_set_proc(caps)) {
	perror("unable to drop capabilities from main process thread");
	exit(1);
    }
    cap_free(caps);

    /* confirm the low privilege of the process' main thread */

    caps = cap_get_proc();
    text = cap_to_text(caps, &greatest_len);
    cap_free(caps);

    printf("no privilege in main process thread: len:%ld, caps:\"%s\"\n",
	   greatest_len, text);
    if (greatest_len != 1) {
	printf("failed to lower privilege as expected\n");
	exit(1);
    }

    /*
     * So, we have confirmed that this running thread has no
     * privilege. From this thread we setup an interrupt handler and
     * then trigger it on the privileged peer thread.
     */

    sig_action.sa_sigaction = &handler;
    sigemptyset(&sig_action.sa_mask);
    sig_action.sa_flags = SA_SIGINFO | SA_RESTART;;
    sigaction(SIGRTMIN, &sig_action, NULL);

    pthread_kill(peer, SIGRTMIN);

    /*
     * Wait for the thread to exit.
     */
    pthread_join(peer, NULL);

    /*
     * Let's see how we did with the exploit.
     */

    printf("greatest privilege in main process thread: len:%ld, caps:\"%s\"\n",
	   greatest_len, text);

    cap_free(text);
    if (greatest_len != 1) {
	printf("exploit succeeded\n");
	exit(1);
    } else {
	printf("exploit failed\n");
    }
}
