Question

The following code works exactly as expected if the cap_enter line is removed. However I'd like to make sure my program runs in capability mode.

I've distilled this program down from a 4000+ line bigger program into a minimal example.

When I use ktrace to run the program and them kdump the output I see the following line:

52225 tests RET open -1 errno 94 Not permitted in capability mode

around the point I wanted the history.

Is it possible to both use capability mode and keep history ?

#include <err.h>
#include <errno.h>
#include <histedit.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/capsicum.h>

static const char* promptstr = "";

static const char * prompt(EditLine *e __unused) {
    return promptstr;
}
-
int
main(int argc __unused, char **argv)
{

    History *inhistory;
    EditLine *el;
    HistEvent ev;

    inhistory = history_init();
    el = el_init(argv[0], stdin, stdout, stderr);
    el_set(el, EL_PROMPT, &prompt);
    el_set(el, EL_EDITOR, "emacs");
    el_set(el, EL_SIGNAL, 1);
    el_set(el, EL_HIST, history, inhistory);
    el_source(el, NULL);
    history(inhistory, &ev, H_SETSIZE, 50);
    if (inhistory == 0)
        err(1, "Could not initalize history");

    if (cap_enter() < 0)
        err(1, "unable to enter capability mode");

    for (;;) {
        const char* havestr;
        int inputsz;

        havestr = el_gets(el, &inputsz);
        if (havestr == NULL)
            exit(0);
        if (inputsz > 0)
            history(inhistory, &ev, H_ENTER, havestr);
        if (*havestr == '.')
            break;
    }

    history(inhistory, &ev, H_SAVE, "/tmp/myhistory");

    history_end(inhistory);
    return(0);
}
Was it helpful?

Solution

You won't be able to open any file when in capability mode. The best way to solve it would be to extend history() API to make it possible to pass a file descriptor instead of path; you would then first open the history file, then call cap_enter(), and then write the history using file descriptor opened in the first step.

A workaround would be to open the history file, then call cap_enter(), and then save the history "by hand", using loop obtaining history entries (H_FIRST or H_NEXT) and saving to the file.

OTHER TIPS

It turns out there is H_SAVE_FP which saves files to an opened file pointer.

The code then looks like:

FILE* fp = fopen("historyfile", "w");
...
cap_enter();
...
history(inhistory, &ev, H_SAVE_FP, fp);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top