SECCOMP_TRANSACTION_START(3)

🫢 NAME 🫢

okay bestie, welcome to the libseccomp documentation for the transaction girlies ✨ this page covers three functions β€” seccomp_transaction_start, seccomp_transaction_commit, and seccomp_transaction_reject β€” and they're all about managing seccomp filter transactions. yes ma'am, it's giving undo-button energy πŸ’…


✨ SYNOPSIS ✨

first thing's first, you gotta include the header, no cap:

#include <seccomp.h>

typedef void * scmp_filter_ctx;

int seccomp_transaction_start(scmp_filter_ctx ctx);
int seccomp_transaction_commit(scmp_filter_ctx ctx);
void seccomp_transaction_reject(scmp_filter_ctx ctx);

and when you link, you link with -lseccomp. that's it, that's the whole vibe. πŸŽ€


πŸ’– DESCRIPTION πŸ’–

so the way seccomp_transaction_start() works is it starts a brand new seccomp filter transaction. once you've done that, you β€” the caller β€” can do any number of filter modifications, and then either commit all of them to the filter with seccomp_transaction_commit() or throw them all away with seccomp_transaction_reject(). chef's kiss. πŸ”₯

now listen, this part matters: transactions only affect the seccomp filter state while libseccomp is still managing it. if a seccomp filter has already been loaded into the kernel, you literally cannot modify it. like, it's done, it's gone, no take-backs. the only thing you can do is add new seccomp filters on top of the existing loaded filter stack. periodt.

finishing (aka committing) a transaction is optional β€” though it is encouraged, bestie, please. at any point in time, no matter what the transaction state is, the seccomp filter is determined by all of the libseccomp operations performed on the filter up to that point. what does committing actually do? it just flushes the transaction rollback marker of the current transaction, which makes the filter changes permanent. and rejecting a transaction rolls the filter state back to immediately before the transaction was started. time travel but make it syscalls πŸ¦‹

and yes, transactions can be nested arbitrarily deep. seccomp_transaction_commit() and seccomp_transaction_reject() always operate on the deepest β€” meaning the most recently started β€” transaction. also important: a nested set of filter modifications, even if it's already committed, is still subject to rejection by shallower (older) transactions that haven't been committed or rejected yet. so your committed little nested baby can still get un-alived by grandma transaction. tragic but iconic. πŸ’€


🌈 RETURN VALUE 🌈

seccomp_transaction_start() and seccomp_transaction_commit() return zero on success, or one of these error codes on failure:

  • -EINVAL β€” the context is invalid. (the vibes were off 😭)
  • -ENOMEM β€” the library was unable to allocate enough memory. (it simply could not afford the rent πŸ“)
lowkey note: seccomp_transaction_reject() is void, so it doesn't hand you a return value at all. it just does its thing. main character behavior honestly. πŸ‘‘

🌸 EXAMPLES 🌸

here's the whole cute little setup, verbatim, no edits:

#include <seccomp.h>

int libseccomp_generate(scmp_filter_ctx *ctx)
{
     int rc;

     rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(close), 0);
     if (rc)
          return rc;
     rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(exit_group), 0);
     if (rc)
          return rc;
     rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(exit), 0);
     if (rc)
          return rc;

     return 0;
}

int main(int argc, char *argv[])
{
     int rc = -1;
     scmp_filter_ctx ctx;

     ctx = seccomp_init(SCMP_ACT_KILL);
     if (ctx == NULL)
          goto out;

     rc = seccomp_transaction_start(ctx)
     if (rc)
          goto out;
     rc = libseccomp_generate(ctx);
     if (rc == 0) {
          rc = seccomp_transaction_commit(ctx);
          if (rc)
               goto out;
     } else
          seccomp_transaction_reject(ctx);

     /* ... */

out:
     seccomp_release(ctx);
     return -rc;
}

see how it starts a transaction, does the filter work, and then commits if everything went okay and rejects if it didn't? that's the whole plot of the movie bestie. 🎬


🧚 NOTES 🧚

even though the seccomp filter can be generated totally independent of the kernel, kernel support is required to load and enforce the seccomp filter that libseccomp generates. so like, you can build it anywhere, but the kernel has to be the one to actually run it. iykyk. 🫢

the libseccomp project site, with more info and the source code repository, lives at https://github.com/seccomp/libseccomp. this tool, as well as the libseccomp library, is currently under development, so please report any bugs at the project site or directly to the author. do your civic duty bestie, report the bugs. πŸ›βœ¨


πŸ‘‘ AUTHOR πŸ‘‘

Paul Moore <paul@paul-moore.com>


⭐ SEE ALSO ⭐


okay that's the whole page, you ate that fr fr πŸ’…βœ¨ this lil masterpiece came from the libseccomp documentation, and it was last touched on 21 September 2023 by paul@paul-moore.com β€” so if you're reading this way later, hi, hope the transactions are still transacting πŸ¦‹πŸŽ€