Giter Site home page Giter Site logo

Comments (8)

rusty-snake avatar rusty-snake commented on June 16, 2024 1

You have to use ACT_NOTIFY, as you already did in your OP, to get user space callbacks.

Also you must make sure that the program can not spoof user input and self-approve those requests.

from libseccomp.

pcmoore avatar pcmoore commented on June 16, 2024

Hi @godalming123,

As a FYI, we don't provide Zig language bindings so the amount of help we can provide may be limited, but we'll try. Beyond that, I'm not clear what you are asking about in this issue, can you rephrase your question?

from libseccomp.

godalming123 avatar godalming123 commented on June 16, 2024

@pcmoore
Firstly, zig has built in c/c++ interop, and so far, I've managed to get a program that restricts the syscalls and then dies because it uses a restricted syscall in zig. And if you feel more comfortable giving me C examples, then go ahead.

In terms of what I want, I want to create a whitelist syscall filter that a sandboxed program can use, and then when the sandboxed program tries to use a syscall that isn't in the whitelist, trigger a callback so that the main program can ask the user if they want to allow the sandboxed program access to the syscall.

Something like:

Sandbox /bin/echo Hello world
/bin/echo would like access to the write syscall (allow/deny): allow
Hello world

from libseccomp.

godalming123 avatar godalming123 commented on June 16, 2024

@pcmoore Is this possible, and if so how can it be done? I don't mind if this isn't possible, I just want a response please.

from libseccomp.

pcmoore avatar pcmoore commented on June 16, 2024

Hi @godalming123, are you satisfied with @rusty-snake's answer above?

from libseccomp.

godalming123 avatar godalming123 commented on June 16, 2024

@pcmoore rusty-snakes answer helped, but I still can't get it too work, so far I have the following:

const std = @import("std");
const c = @cImport({
    @cInclude("seccomp.h");
});

pub fn main() !void {
    // Initialise libseccomp
    const ctx = c.seccomp_init(c.SCMP_ACT_NOTIFY);
    if (ctx == null) {
        return error.FailedToInitialiseSeccomp;
    }
    defer c.seccomp_release(ctx);

    // Apply seccomp filters
    // TODO: add any other filters that are needed
    if (c.seccomp_rule_add_exact(ctx, c.SCMP_ACT_ALLOW, c.__NR_read, 0) != 0) {
        return error.FailedToAllowReadSyscall;
    }
    if (c.seccomp_rule_add_exact(ctx, c.SCMP_ACT_ALLOW, c.__NR_write, 0) != 0) {
        return error.FailedToAllowWriteSyscall;
    }

    // Load seccomp filters
    if (c.seccomp_load(ctx) < 0) {
        return error.FailedToLoadSeccompRules;
    }

    // Setup listener for a notify event
    const fd = c.seccomp_notify_fd(ctx);
    if (fd < 0) {
        return error.FailedToFindSeccompNotifyFileDiscriptor;
    }
    std.os.close(fd);

    // Fork
    const pid = try std.os.fork();
    if (pid == 0) { // Child process for running the specified command
        return std.os.execvpeZ(std.os.argv[1], @ptrCast(&std.os.argv[1..]), &[_:null]?[*:0]u8{null});
    } else { // Parent process for listening if the child process uses a syscall other then `read` or `write`
        // Allocate structs for request and response
        var req: ?*c.seccomp_notif = null;
        var resp: ?*c.seccomp_notif_resp = null;
        if (c.seccomp_notify_alloc(&req, &resp) != 0) {
            return error.FailedToAllocateNotify;
        }

        // Loop for listening to notify events
        while (true) {
            if (c.seccomp_notify_receive(fd, req) != 0) {
                return error.FailedToRecieveNotify;
            }

            std.debug.print("Seccomp process tried to use syscall number: {}.", .{req.?.data.nr});

            if (c.seccomp_notify_id_valid(fd, req.?.id) != 0) {
                return error.SeccompNotifyIdIsNotValid;
            }

            if (c.seccomp_notify_respond(fd, null) != 0) {
                return error.FailedToRespondToSeccompNotifySyscall;
            }
        }
    }
}

If I run the compiled binary like so:
sandpack sh
Then I just get a blank console, and do not see any text on the screen saying that the command tried to acess any syscalls.
Do you have any ideas as to why this might not be working, or any code fixes because I am not confident in this programs memory safety?
Much appreciated.

from libseccomp.

rusty-snake avatar rusty-snake commented on June 16, 2024

You create a seccomp filter that only allows read(2) and write(2). Every other syscall will trigger a userspace callback and block the calling thread indefinitely (ignoring signals and the like). Then you load this seccomp filter. In other words you activate it. After that, you try to get the unotify fd (ioctl(2), fork(2), execve(2), mmap(2)?, .... All those syscalls will not get executed.

from libseccomp.

godalming123 avatar godalming123 commented on June 16, 2024

@rusty-snake thank you for the explanation as to why my code does not work. Do you have a way to implement this functionality that does work? If you move the part of the code that gets the file descriptor before the code that loads the filter, then libseccomp returns a negative file descriptor which (correct me if I'm wrong) signals an error.

from libseccomp.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.