Code Monkey home page Code Monkey logo

Comments (10)

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

However I am unsure if this has the same TOUTOC issue that comes with filters targeting file path arguments.

Everytime your filters decision depends on memory controlled by the supervised process (/proc/[tid]/mem, process_vm_readv, ...) it will be vulnerable to TOUTOC attacks. No matter what the memory is; filepath, socket address, open_how structs, ptrace data, ... all kinds of pointers that need to be dereferenced.

seccomp_rule_add (ctx, SCMP_ACT_KILL, SCMP_SYS(connect), 1, SCMP_CMP(1, SCMP_CMP_EQ, '\0'))

Arg1 of connect is const struct sockaddr *addr, means it is passed by-reference (see the *) and not by-value like arg0 for example. Therefore you filter does not check the first byte of sun_path[0] (or whatever is behind the pointer, I didn't check) but instead the pointer it self. So connect(sockfd, &abst_sock_addr, size_of_abst_sock_addr) will be allowed and connect(sockfd, NULL, 0) will be blocked.

Is there a way to work around this filter or would this actually work to prevent the use of abstract sockets?

As you saw, this filter will not block abstract sockets and I do not know a secure way to do so with seccomp. Depending on your usecase, you can use unshare(CLONE_NEWNET).

from libseccomp.

valoq avatar valoq commented on June 11, 2024

However I am unsure if this has the same TOUTOC issue that comes with filters targeting file path arguments.

Everytime your filters decision depends on memory controlled by the supervised process (/proc/[tid]/mem, process_vm_readv, ...) it will be vulnerable to TOUTOC attacks. No matter what the memory is; filepath, socket address, open_how structs, ptrace data, ... all kinds of pointers that need to be dereferenced.

I was afraid that would be the case, thanks for the confirmation.

seccomp_rule_add (ctx, SCMP_ACT_KILL, SCMP_SYS(connect), 1, SCMP_CMP(1, SCMP_CMP_EQ, '\0'))

Arg1 of connect is const struct sockaddr *addr, means it is passed by-reference (see the *) and not by-value like arg0 for example. Therefore you filter does not check the first byte of sun_path[0] (or whatever is behind the pointer, I didn't check) but instead the pointer it self. So connect(sockfd, &abst_sock_addr, size_of_abst_sock_addr) will be allowed and connect(sockfd, NULL, 0) will be blocked.

If thats the case I'm not sure why, but the filter actually does block abstract sockets.
Im using it here https://github.com/valoq/bwscripts to prevent the use of abstract sockets for processes that need network namespaces. Using this filter with a bubblewrap script that blocks path access to the normal socket in the mount namespace, it is no longer possible to run xterm for example (since it can't reach the X11 socket path). Without the socket filter above, xterm works just fine. Question is why this works.

from libseccomp.

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

it is no longer possible to run xterm for example (since it can't reach the X11 socket path). Without the socket filter above, xterm works just fine. Question is why this works.

  1. If you make sure seccomp violations are logged (seccomp_attr_set(ctx, SCMP_FLTATR_CTL_LOG, 1)) what violation is logged in your syslog? The connect call?
  2. What error does xterm show?
  3. It is also blocked with only this connect rule in the filter?

Im using it here https://github.com/valoq/bwscripts to prevent the use of abstract sockets for processes that need network namespaces.

It compiles to this pfc:

  # filter for syscall "connect" (42) [priority: 65533]
  if ($syscall == 42)
    if ($a1.hi32 == 0)
      if ($a1.lo32 == 0)
        action KILL;

from libseccomp.

valoq avatar valoq commented on June 11, 2024

it is no longer possible to run xterm for example (since it can't reach the X11 socket path). Without the socket filter above, xterm works just fine. Question is why this works.

1. If you make sure seccomp violations are logged (`seccomp_attr_set(ctx, SCMP_FLTATR_CTL_LOG, 1)`) what violation is logged in your syslog? The `connect` call?

The filter above does not seem to log any syscalls for me. (I did add the command above right after (ctx = seccomp_init(SCMP_ACT_ALLOW))
I did try another filter that blocks the connect syscall completely and that failed right away, logging the failed connect syscall through auditd.

2. What error does xterm show?

xterm: Xt error: Can't open display: :0

3. It is also blocked with only this `connect` rule in the filter?

No, "connect" to normal sockets and even network calls work just fine.
I tested this filter with a number of applications, including firefox and everything works fine as long as no abstract sockets are called. Only applications using X11 didnt work (as intended)

Im using it here https://github.com/valoq/bwscripts to prevent the use of abstract sockets for processes that need network namespaces.

It compiles to this pfc:

  # filter for syscall "connect" (42) [priority: 65533]
  if ($syscall == 42)
    if ($a1.hi32 == 0)
      if ($a1.lo32 == 0)
        action KILL;

I have the suspicion this works a bit differently then we assume here. Could it be that for abstract sockets, the path argument is not passed to the connect syscall directly?

from libseccomp.

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

xterm: Xt error: Can't open display: :0

If the action in KILL you shouldn't see this, you should?

I have the suspicion this works a bit differently then we assume here. Could it be that for abstract sockets, the path argument is not passed to the connect syscall directly?

What do you mean with "directly"?

from libseccomp.

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

Ok, simple reproducer

bwrap \
  --dev-bind / / \             # no-op, mount full filesystem
  --tmpfs /tmp \               # Hide sockets in /tmp
  --tmpfs $XDG_RUNTIME_DIR \   # Hide sockets in $XDG_RUNTIME_DIR
  --unshare-net \              # Unshare network-namespaces including abstract unix socket namespace 
  --setenv GDK_BACKEND x11 \   # Force X11 backend
  --seccomp 3 3<seccomp_filter.bpf \  # Load your filter
  zenity --info                # Run a simple GTK program
  1. Failes with cannot open display: :0
  2. Remove --unshare-net and zenity opens a window and is listed by xlsclients.

from libseccomp.

valoq avatar valoq commented on June 11, 2024

You are right, I messed up my testscript and had --unshare-all included, sorry about that.

Seems like the filter does not work after all.

Kinda sad that it seems impossible to build a complete container sandbox on linux when network access is required

from libseccomp.

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

Kinda sad that it seems impossible to build a complete container sandbox on linux when network access is required

Internet access from a unshared network namespaces is possible. Either using the kernel native way with bridge interfaces (requires root AFAIK) or with userspace implementations like slirp4netns. bwrap+slirp4netns is not friendly to script in bash but with other languages it is not that much work to get working PoC (https://codeberg.org/crabjail/crabjail/src/commit/6d4e5076c74e7e29afe377b296ff723291d9344f/src/crabjail.rs#L698).

from libseccomp.

valoq avatar valoq commented on June 11, 2024

Kinda sad that it seems impossible to build a complete container sandbox on linux when network access is required

Internet access from a unshared network namespaces is possible. Either using the kernel native way with bridge interfaces (requires root AFAIK) or with userspace implementations like slirp4netns. bwrap+slirp4netns is not friendly to script in bash but with other languages it is not that much work to get working PoC (https://codeberg.org/crabjail/crabjail/src/commit/6d4e5076c74e7e29afe377b296ff723291d9344f/src/crabjail.rs#L698).

Yes, I am aware of that hack, but its not an ideal solution to the problem in my opinion.
A syscall filter would have been a lot better if it was possible.

Anyway, thanks for the reality check, I certainly owe you a coffee ;)

from libseccomp.

Drrr345 avatar Drrr345 commented on June 11, 2024

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.