Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Socket filtering broken on x86 #8

Closed
dbnicholson opened this issue Jun 30, 2015 · 3 comments
Closed

Socket filtering broken on x86 #8

dbnicholson opened this issue Jun 30, 2015 · 3 comments
Assignees
Labels

Comments

@dbnicholson
Copy link

I'm trying to filter socket families, but it seems to be broken on x86. Filtering any family will cause AF_UNIX (all?) to be blocked. Here's my simple program trying to open the X socket.

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <seccomp.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <X11/Xlib.h>

/* Build with:
 * $CC -o seccomp seccomp.c `pkg-config --cflags --libs libseccomp x11`
 */

int main(int argc, char *argv[])
{
  scmp_filter_ctx seccomp;
  int family = AF_VSOCK; /* any non AF_UNIX family */
  int ret;
  Display *dpy;

  seccomp = seccomp_init(SCMP_ACT_ALLOW);
  if (!seccomp)
    {
      fprintf(stderr, "Could not initialize seccomp\n");
      exit(1);
    }

  ret = seccomp_arch_add(seccomp, SCMP_ARCH_X86);
  if (ret < 0 && ret != -EEXIST)
    {
      fprintf(stderr, "Failed to add x86 seccomp arch: %s\n",
              strerror(-ret));
    }

  ret = seccomp_rule_add(seccomp, SCMP_ACT_ERRNO(EAFNOSUPPORT),
                         SCMP_SYS(socket), 1,
                         SCMP_A0(SCMP_CMP_EQ, family));
  if (ret < 0)
    {
      fprintf(stderr, "Failed to block socket family %d: %s\n", family,
              strerror(-ret));
      exit(1);
    }

  ret = seccomp_load(seccomp);
  if (ret < 0)
    {
      fprintf(stderr, "Failed to load seccomp filter: %s\n", strerror(-ret));
      exit(1);
    }

  dpy = XOpenDisplay(NULL);
  if (!dpy)
    {
      fprintf(stderr, "Failed to open X display: %s\n", strerror(errno));
      exit(1);
    }

  printf("X displayed opened!\n");
  return 0;
}

I'm using libseccomp master. Building as a 64 bit program, everything works fine. Building as a 32 bit program, I get Failed to open X display: Address family not supported by protocol. I've tried this on a couple systems. One is Fedora 20 running a 64 bit kernel on both 64 and 32 bit userspace. The other is on a debian style system with 32 bit userspace. In both cases, the kernel is a bit old, but I'm not sure that's the issue since the 64 bit program works. On Fedora 20, the kernel is 3.19.3. On the debian style system, the kernel is based on Ubuntu's 3.16 series, but I've also run it in a chroot on the Fedora 20 system.

Any ideas?

@pcmoore
Copy link
Member

pcmoore commented Jun 30, 2015

In the future, please send questions like this to the mailing list first.

This is a limitation in the 32-bit x86 ABI and the kernel's implementation of syscall filtering. On 32-bit x86 the socket syscalls are multiplexed over a single syscall, socketcall(). I'll leave the details as an exercise for the reader but the short version is that you can't filter socket related syscalls, with arguments, on 32-bit x86.

@pcmoore pcmoore self-assigned this Jun 30, 2015
@pcmoore pcmoore closed this as completed Jun 30, 2015
@dbnicholson
Copy link
Author

Interesting. Will send to the mailing list next time. Would it be possible to get this documented somewhere? Could libseccomp fail if you try to filter sockets on x86? That would have saved me quite a bit of time figuring out what was going on.

@pcmoore
Copy link
Member

pcmoore commented Jul 1, 2015

The first paragraph of the description section in the seccomp_rule_add(3) man page specifically mentions that the socket syscalls on x86; would you suggest something different? Patches are always welcome.

We do have APIs which would have failed in the particular example above, seccomp_rule_add_exact(3). We offer both because there are use cases for each; some developers need to add a rule regardless of the architecture, while some need to be notified if the rule can not be created exactly as requested. Unfortunately, I believe you had a bit of bad luck and picked the more permissive of the two APIs to start.

alexlarsson pushed a commit to alexlarsson/xdg-app that referenced this issue Sep 29, 2015
Filtering on socket related syscalls are not possible on x86. See
seccomp/libseccomp#8. Disable socket filtering
until a better solution comes along.

https://bugs.freedesktop.org/show_bug.cgi?id=91162
giuseppe added a commit to giuseppe/libseccomp that referenced this issue Mar 18, 2021
it was reported by clang with the option -fsanitize=memory:

Uninitialized bytes in MemcmpInterceptorCommon at offset 0 inside [0x7070000002a0, 56)
==3791089==WARNING: MemorySanitizer: use-of-uninitialized-value
    #0 0x482a2c in memcmp (fuzzer+0x482a2c)
    seccomp#1 0x7fed2f120ebb in _hsh_add src/libseccomp/src/gen_bpf.c:598:9
    seccomp#2 0x7fed2f121715 in _gen_bpf_action_hsh src/libseccomp/src/gen_bpf.c:796:6
    seccomp#3 0x7fed2f121a53 in _gen_bpf_node src/libseccomp/src/gen_bpf.c:831:11
    seccomp#4 0x7fed2f121a53 in _gen_bpf_chain.isra.0 src/libseccomp/src/gen_bpf.c:1072:13
    seccomp#5 0x7fed2f121f16 in _gen_bpf_chain_lvl_res src/libseccomp/src/gen_bpf.c:977:12
    seccomp#6 0x7fed2f121c74 in _gen_bpf_chain.isra.0 src/libseccomp/src/gen_bpf.c:1124:12
    seccomp#7 0x7fed2f12253c in _gen_bpf_syscall src/libseccomp/src/gen_bpf.c:1520:10
    seccomp#8 0x7fed2f12253c in _gen_bpf_syscalls src/libseccomp/src/gen_bpf.c:1615:18
    seccomp#9 0x7fed2f12253c in _gen_bpf_arch src/libseccomp/src/gen_bpf.c:1683:7
    seccomp#10 0x7fed2f12253c in _gen_bpf_build_bpf src/libseccomp/src/gen_bpf.c:2056:11
    seccomp#11 0x7fed2f12253c in gen_bpf_generate src/libseccomp/src/gen_bpf.c:2321:7
    seccomp#12 0x7fed2f11f41c in seccomp_export_bpf src/libseccomp/src/api.c:724:7

  Uninitialized value was created by a heap allocation
    #0 0x4547ef in realloc (fuzzer+0x4547ef)
    seccomp#1 0x7fed2f121244 in _blk_resize src/libseccomp/src/gen_bpf.c:362:8
    seccomp#2 0x7fed2f121244 in _blk_append src/libseccomp/src/gen_bpf.c:394:6

Signed-off-by: Giuseppe Scrivano <[email protected]>
giuseppe added a commit to giuseppe/libseccomp that referenced this issue Mar 18, 2021
it was reported by clang with the option -fsanitize=memory:

Uninitialized bytes in MemcmpInterceptorCommon at offset 0 inside [0x7070000002a0, 56)
==3791089==WARNING: MemorySanitizer: use-of-uninitialized-value
    #0 0x482a2c in memcmp (fuzzer+0x482a2c)
    seccomp#1 0x7fed2f120ebb in _hsh_add src/libseccomp/src/gen_bpf.c:598:9
    seccomp#2 0x7fed2f121715 in _gen_bpf_action_hsh src/libseccomp/src/gen_bpf.c:796:6
    seccomp#3 0x7fed2f121a53 in _gen_bpf_node src/libseccomp/src/gen_bpf.c:831:11
    seccomp#4 0x7fed2f121a53 in _gen_bpf_chain.isra.0 src/libseccomp/src/gen_bpf.c:1072:13
    seccomp#5 0x7fed2f121f16 in _gen_bpf_chain_lvl_res src/libseccomp/src/gen_bpf.c:977:12
    seccomp#6 0x7fed2f121c74 in _gen_bpf_chain.isra.0 src/libseccomp/src/gen_bpf.c:1124:12
    seccomp#7 0x7fed2f12253c in _gen_bpf_syscall src/libseccomp/src/gen_bpf.c:1520:10
    seccomp#8 0x7fed2f12253c in _gen_bpf_syscalls src/libseccomp/src/gen_bpf.c:1615:18
    seccomp#9 0x7fed2f12253c in _gen_bpf_arch src/libseccomp/src/gen_bpf.c:1683:7
    seccomp#10 0x7fed2f12253c in _gen_bpf_build_bpf src/libseccomp/src/gen_bpf.c:2056:11
    seccomp#11 0x7fed2f12253c in gen_bpf_generate src/libseccomp/src/gen_bpf.c:2321:7
    seccomp#12 0x7fed2f11f41c in seccomp_export_bpf src/libseccomp/src/api.c:724:7

  Uninitialized value was created by a heap allocation
    #0 0x4547ef in realloc (fuzzer+0x4547ef)
    seccomp#1 0x7fed2f121244 in _blk_resize src/libseccomp/src/gen_bpf.c:362:8
    seccomp#2 0x7fed2f121244 in _blk_append src/libseccomp/src/gen_bpf.c:394:6

Signed-off-by: Giuseppe Scrivano <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants