Пример #1
2
/* Returns 0 if the the sandbox is enabled using
 * the time setter policy.
 */
int
enable_setter_seccomp (void)
{
  static const struct sock_filter insns[] =
  {
    /* Ensure the syscall arch convention is as expected. */
    BPF_STMT (BPF_LD+BPF_W+BPF_ABS,
    offsetof (struct seccomp_data, arch)),
    BPF_JUMP (BPF_JMP+BPF_JEQ+BPF_K, SECCOMP_AUDIT_ARCH, 1, 0),
    BPF_STMT (BPF_RET+BPF_K, SECCOMP_FILTER_FAIL),
    /* Load the syscall number for checking. */
    BPF_STMT (BPF_LD+BPF_W+BPF_ABS,
    offsetof (struct seccomp_data, nr)),

    /* Process ALLOWs as quickly as possible */
    SC_ALLOW (read),
    SC_ALLOW (write),
    SC_ALLOW (pwritev),

    SC_ALLOW (settimeofday),
    SC_ALLOW (ioctl), /* TODO(wad) filter for fd and RTC_SET_TIME */
#ifdef __NR_time /* This is required for x86 systems */
    SC_ALLOW (time),
#endif

    SC_ALLOW (lseek),
    SC_ALLOW (close),
    SC_ALLOW (munmap),

    SC_ALLOW (exit_group),
    SC_ALLOW (exit),

    SC_DENY (open, EINVAL),
    SC_DENY (fcntl, EINVAL),
    SC_DENY (fstat, EINVAL),
#ifdef __NR_mmap
    SC_DENY (mmap, EINVAL),
#endif
#ifdef __NR_mmap2
    SC_DENY (mmap2, EINVAL),
#endif
#ifdef __NR_sendto
    SC_DENY (sendto, EINVAL),
#endif
#ifdef __NR_socket
    SC_DENY (socket, EINVAL),
#endif
#ifdef __NR_socketcall
    SC_DENY (socketcall, EINVAL),
#endif
    BPF_STMT (BPF_RET+BPF_K, SECCOMP_FILTER_FAIL),
  };
  static const struct sock_fprog prog =
  {
    .len = (unsigned short) (sizeof (insns) /sizeof (insns[0])),
    .filter = (struct sock_filter *) insns,
  };
  return (prctl (PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) ||
          prctl (PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog));
}
Пример #2
0
/*
 * npfctl_bpf_icmp: code block to match ICMP type and/or code.
 * Note: suitable both for the ICMPv4 and ICMPv6.
 */
void
npfctl_bpf_icmp(npf_bpf_t *ctx, int type, int code)
{
	const u_int type_off = offsetof(struct icmp, icmp_type);
	const u_int code_off = offsetof(struct icmp, icmp_code);

	assert(offsetof(struct icmp6_hdr, icmp6_type) == type_off);
	assert(offsetof(struct icmp6_hdr, icmp6_code) == code_off);
	assert(type != -1 || code != -1);

	/* X <- IP header length */
	fetch_l3(ctx, AF_UNSPEC, X_EQ_L4OFF);

	if (type != -1) {
		struct bpf_insn insns_type[] = {
			BPF_STMT(BPF_LD+BPF_B+BPF_IND, type_off),
			BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, type, 0, JUMP_MAGIC),
		};
		add_insns(ctx, insns_type, __arraycount(insns_type));

		uint32_t mwords[] = { BM_ICMP_TYPE, 1, type };
		done_block(ctx, mwords, sizeof(mwords));
	}

	if (code != -1) {
		struct bpf_insn insns_code[] = {
			BPF_STMT(BPF_LD+BPF_B+BPF_IND, code_off),
			BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, code, 0, JUMP_MAGIC),
		};
		add_insns(ctx, insns_code, __arraycount(insns_code));

		uint32_t mwords[] = { BM_ICMP_CODE, 1, code };
		done_block(ctx, mwords, sizeof(mwords));
	}
}
Пример #3
0
/**
 * Create the berkeley packet filter for our ethertype
 *
 * Creates a BPF for our ether type.
 *
 * @param [in,out] ether The MetisGenericEther to modify
 *
 * @retval true success
 * @retval false failure
 *
 * Example:
 * @code
 * <#example#>
 * @endcode
 */
static bool
_darwinEthernet_SetFilter(MetisGenericEther *ether)
{
    struct bpf_program filterCode = { 0 };

    // BPF instructions:
    // Load 12 to accumulator (offset of ethertype)
    // Jump Equal to netbyteorder_ethertype 0 instructions, otherwise 1 instruction
    // 0: return a length of -1 (meaning whole packet)
    // 1: return a length of 0 (meaning skip packet)
    struct bpf_insn instructions[] = {
        BPF_STMT(BPF_LD + BPF_H + BPF_ABS,  12),
        BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, 0x0801,      0,  1),
        BPF_STMT(BPF_RET + BPF_K,           (u_int) - 1),
        BPF_STMT(BPF_RET + BPF_K,           0),
    };
    //        BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, ether->ethertype, 0, 1),

    /* Set the filter */
    filterCode.bf_len = sizeof(instructions) / sizeof(struct bpf_insn);
    filterCode.bf_insns = &instructions[0];

    if (ioctl(ether->etherSocket, BIOCSETF, &filterCode) < 0) {
        return false;
    }

    return true;
}
Пример #4
0
int filter_syscall(int syscall_nr, unsigned int flags)
{
	struct sock_filter filter[] = {
		BPF_STMT(BPF_LD+BPF_W+BPF_ABS, offsetof(struct seccomp_data, nr)),
		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, syscall_nr, 0, 1),
		BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_KILL),
		BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW),
	};

	struct sock_fprog bpf_prog = {
		.len = (unsigned short)(sizeof(filter)/sizeof(filter[0])),
		.filter = filter,
	};

	if (syscall(__NR_seccomp, SECCOMP_SET_MODE_FILTER, flags, &bpf_prog) < 0) {
		pr_perror("seccomp failed");
		return -1;
	}

	return 0;
}

void *wait_and_getpid(void *arg)
{
	pthread_mutex_lock(&getpid_wait);
	pthread_mutex_unlock(&getpid_wait);
	pthread_mutex_destroy(&getpid_wait);

	/* we expect the tg to get killed by the seccomp filter that was
	 * installed via TSYNC */
	ptrace(PTRACE_TRACEME);
	pthread_exit((void *)1);
}
Пример #5
0
/*
 * npfctl_bpf_tcpfl: code block to match TCP flags.
 */
void
npfctl_bpf_tcpfl(npf_bpf_t *ctx, uint8_t tf, uint8_t tf_mask)
{
	const u_int tcpfl_off = offsetof(struct tcphdr, th_flags);

	/* X <- IP header length */
	fetch_l3(ctx, AF_UNSPEC, X_EQ_L4OFF);

	struct bpf_insn insns_tf[] = {
		/* A <- TCP flags */
		BPF_STMT(BPF_LD+BPF_B+BPF_IND, tcpfl_off),
	};
	add_insns(ctx, insns_tf, __arraycount(insns_tf));

	if (tf_mask != tf) {
		/* A <- (A & mask) */
		struct bpf_insn insns_mask[] = {
			BPF_STMT(BPF_ALU+BPF_AND+BPF_K, tf_mask),
		};
		add_insns(ctx, insns_mask, __arraycount(insns_mask));
	}

	struct bpf_insn insns_cmp[] = {
		/* A == expected-TCP-flags? */
		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, tf, 0, JUMP_MAGIC),
	};
	add_insns(ctx, insns_cmp, __arraycount(insns_cmp));

	uint32_t mwords[] = { BM_TCPFL, 2, tf, tf_mask};
	done_block(ctx, mwords, sizeof(mwords));
}
Пример #6
0
/* Filter out messages from self that occur on listener socket,
   caused by our actions on the command socket
 */
static void netlink_install_filter (int sock, __u32 pid)
{
  struct sock_filter filter[] = {
    /* 0: ldh [4]	          */
    BPF_STMT(BPF_LD|BPF_ABS|BPF_H, offsetof(struct nlmsghdr, nlmsg_type)),
    /* 1: jeq 0x18 jt 3 jf 6  */
    BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, htons(RTM_NEWROUTE), 1, 0),
    /* 2: jeq 0x19 jt 3 jf 6  */
    BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, htons(RTM_DELROUTE), 0, 3),
    /* 3: ldw [12]		  */
    BPF_STMT(BPF_LD|BPF_ABS|BPF_W, offsetof(struct nlmsghdr, nlmsg_pid)),
    /* 4: jeq XX  jt 5 jf 6   */
    BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, htonl(pid), 0, 1),
    /* 5: ret 0    (skip)     */
    BPF_STMT(BPF_RET|BPF_K, 0),
    /* 6: ret 0xffff (keep)   */
    BPF_STMT(BPF_RET|BPF_K, 0xffff),
  };

  struct sock_fprog prog = {
    .len = sizeof(filter) / sizeof(filter[0]),
    .filter = filter,
  };

  if (setsockopt(sock, SOL_SOCKET, SO_ATTACH_FILTER, &prog, sizeof(prog)) < 0)
    zlog_warn ("Can't install socket filter: %s\n", safe_strerror(errno));
}

/* Exported interface function.  This function simply calls
   netlink_socket (). */
void
kernel_init (void)
{
  unsigned long groups;

  groups = RTMGRP_LINK | RTMGRP_IPV4_ROUTE | RTMGRP_IPV4_IFADDR;
#ifdef HAVE_IPV6
  groups |= RTMGRP_IPV6_ROUTE | RTMGRP_IPV6_IFADDR;
#endif /* HAVE_IPV6 */
  netlink_socket (&netlink, groups);
  netlink_socket (&netlink_cmd, 0);

  /* Register kernel socket. */
  if (netlink.sock > 0)
    {
      /* Only want non-blocking on the netlink event socket */
      if (fcntl (netlink.sock, F_SETFL, O_NONBLOCK) < 0)
	zlog (NULL, LOG_ERR, "Can't set %s socket flags: %s", netlink.name,
		safe_strerror (errno));

      /* Set receive buffer size if it's set from command line */
      if (nl_rcvbufsize)
	netlink_recvbuf (&netlink, nl_rcvbufsize);

      netlink_install_filter (netlink.sock, netlink_cmd.snl.nl_pid);
      thread_add_read (hm->master, kernel_read, NULL, netlink.sock);
    }
}
Пример #7
0
static void
install_filter(void)
{
    struct sock_filter filter[] = {
        /* Load architecture */

        BPF_STMT(BPF_LD | BPF_W | BPF_ABS,
                (offsetof(struct seccomp_data, arch))),

        /* Kill process if the architecture is not what we expect */

        BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, AUDIT_ARCH_X86_64, 1, 0),
        BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_KILL),

        /* Load system call number */

        BPF_STMT(BPF_LD | BPF_W | BPF_ABS,
                 (offsetof(struct seccomp_data, nr))),

        /* Allow system calls other than open() */

        BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_open, 1, 0),
        BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW),

        /* Kill process on open() */

        BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_KILL)
    };

    struct sock_fprog prog = {
        .len = (unsigned short) (sizeof(filter) / sizeof(filter[0])),
        .filter = filter,
    };

    if (seccomp(SECCOMP_SET_MODE_FILTER, 0, &prog) == -1)
        errExit("seccomp");
    /* On Linux 3.16 and earlier, we must instead use:
            if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog))
                errExit("prctl-PR_SET_SECCOMP");
    */
}

int
main(int argc, char **argv)
{
    if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0))
        errExit("prctl");

    install_filter();

    if (open("/tmp/a", O_RDONLY) == -1)
        errExit("open");

    printf("We shouldn't see this message\n");

    exit(EXIT_SUCCESS);
}
Пример #8
0
Файл: seccomp.c Проект: nbp/rr
static void install_filter(void) {
  struct sock_filter filter[] = {
    /* Load system call number from 'seccomp_data' buffer into
       accumulator */
    BPF_STMT(BPF_LD | BPF_W | BPF_ABS, offsetof(struct seccomp_data, nr)),
    /* Jump forward 1 instruction if system call number
       is not SYS_pipe */
    BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, SYS_pipe, 0, 1),
    /* Error out with ESRCH */
    BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ERRNO | (ESRCH & SECCOMP_RET_DATA)),
    /* Jump forward 1 instruction if system call number
       is not SYS_geteuid */
    BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, SYS_geteuid, 0, 1),
    /* Trigger SIGSYS */
    BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_TRAP),
    /* Jump forward 1 instruction if system call number
       is not SYS_open */
    BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, SYS_open, 0, 1),
    /* Trigger SIGSYS */
    BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_TRAP),
    /* Jump forward 1 instruction if system call number
       is not SYS_rrcall_init_buffers */
    BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, SYS_rrcall_init_buffers, 0, 1),
    /* Trigger SIGSYS */
    BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_TRAP),
    /* Jump forward 1 instruction if system call number
       is not SYS_ioctl */
    BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, SYS_ioctl, 0, 1),
    /* Trigger SIGSYS */
    BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_TRAP),
    /* Destination of system call number mismatch: allow other
       system calls */
    BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW)
  };
  struct sock_fprog prog = {
    .len = (unsigned short)(sizeof(filter) / sizeof(filter[0])),
    .filter = filter,
  };
  int ret;

  ret = syscall(RR_seccomp, SECCOMP_SET_MODE_FILTER, 0, &prog);
  if (ret == -1 && errno == ENOSYS) {
    ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog);
  }
  test_assert(ret == 0);
}

static void* waiting_thread(void* p) {
  char buf;
  test_assert(1 == read(pipe_fds[0], &buf, 1));
  /* Check this thread wasn't affected by the SET_SECCOMP */
  test_assert(0 == prctl(PR_GET_SECCOMP));
  return NULL;
}
Пример #9
0
int main(int argc, char *argv[])
{
    pid_t pid;

    struct sock_filter filter[] = {
        /* Load architecture */
        BPF_STMT(BPF_LD+BPF_W+BPF_ABS, (offsetof(struct seccomp_data, arch))),

        /* Kill process if the architecture is not what we expect */
        /* AUDIT_ARCH_X86_64 or AUDIT_ARCH_I386 */
        BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, AUDIT_ARCH_X86_64, 1, 0),
        BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_KILL),

        /* Load system call number */
        BPF_STMT(BPF_LD+BPF_W+BPF_ABS, (offsetof(struct seccomp_data, nr))),

        /* Allow system calls other than open() */
        BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, __NR_open, 1, 0),
        BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW),

        /* Kill process on open() */
        BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_KILL)
    };

    struct sock_fprog prog = {
        .len = (unsigned short) (sizeof(filter) / sizeof(filter[0])),
        .filter = filter,
    };

    printf("\n*** Appling BPF filter ***\n\n");
    if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0))
        perror("prctl");
    if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog))
        perror("seccomp");

    pid=fork();
    if(pid==0)
    {
        printf("I am the child\n");
        printf("The PID of child is %d\n",getpid());
        printf("The PID of parent of child is %d\n\n",getppid());
    }
    else
    {
        printf("I am the parent\n");
        printf("The PID of parent is %d\n",getpid());
        printf("The PID of parent of parent is %d\n\n",getppid());        
    }

    exit(EXIT_SUCCESS);
}
Пример #10
0
static int
_open_socket(const char *device)
{
    int etherSocket;

    etherSocket = _open_bpf_device();
    if (etherSocket == -1) {
        perror("bpf");
        return -1;
    }

    // Attach the requested interface
    struct ifreq if_idx = { {0} };
    strncpy(if_idx.ifr_name, device, strlen(device) + 1);
    if (ioctl(etherSocket, BIOCSETIF, &if_idx)) {
        perror("BIOCSETIF");
        return -1;
    }

    // Set immediate read on packet reception
    uint32_t on = 1;
    if (ioctl(etherSocket, BIOCIMMEDIATE, &on)) {
        perror("BIOCIMMEDIATE");
        return -1;
    }

    // Setup the BPF filter for CCNX_ETHERTYPE
    struct bpf_program filterCode = { 0 };

    // BPF instructions:
    // Load 12 to accumulator (offset of ethertype)
    // Jump Equal to netbyteorder_ethertype 0 instructions, otherwise 1 instruction
    // 0: return a length of -1 (meaning whole packet)
    // 1: return a length of 0 (meaning skip packet)
    struct bpf_insn instructions[] = {
        BPF_STMT(BPF_LD + BPF_H + BPF_ABS,  12),
        BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, CCNX_ETHERTYPE,0,  1),
        BPF_STMT(BPF_RET + BPF_K,           (u_int) - 1),
        BPF_STMT(BPF_RET + BPF_K,           0),
    };

    // Install the filter
    filterCode.bf_len = sizeof(instructions) / sizeof(struct bpf_insn);
    filterCode.bf_insns = &instructions[0];
    if (ioctl(etherSocket, BIOCSETF, &filterCode) < 0) {
        perror("BIOCSETF");
        return -1;
    }

    return etherSocket;
}
Пример #11
0
/*
 * npfctl_bpf_table: code block to match source/destination IP address
 * against NPF table specified by ID.
 */
void
npfctl_bpf_table(npf_bpf_t *ctx, u_int opts, u_int tid)
{
	const bool src = (opts & MATCH_SRC) != 0;

	struct bpf_insn insns_table[] = {
		BPF_STMT(BPF_LD+BPF_IMM, (src ? SRC_FLAG_BIT : 0) | tid),
		BPF_STMT(BPF_MISC+BPF_COP, NPF_COP_TABLE),
		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0, JUMP_MAGIC, 0),
	};
	add_insns(ctx, insns_table, __arraycount(insns_table));

	uint32_t mwords[] = { src ? BM_SRC_TABLE: BM_DST_TABLE, 1, tid };
	done_block(ctx, mwords, sizeof(mwords));
}
Пример #12
0
static int load_arp_bpflet(int fd)
{
	static struct sock_filter insns[] = {
		BPF_STMT(BPF_LD|BPF_H|BPF_ABS, 6),
		BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, ARPOP_RREQUEST, 0, 1),
		BPF_STMT(BPF_RET|BPF_K, 1024),
		BPF_STMT(BPF_RET|BPF_K, 0),
	};
	static struct sock_fprog filter = {
		sizeof insns / sizeof(insns[0]),
		insns
	};

	return setsockopt(fd, SOL_SOCKET, SO_ATTACH_FILTER, &filter, sizeof(filter));
}
Пример #13
0
int
bpf_arp_filter(int fd, int type_offset, int type, int pkt_size)
{
    struct bpf_insn insns[] = {
	BPF_STMT(BPF_LD+BPF_H+BPF_ABS, type_offset),
	BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, type, 0, 1),
	BPF_STMT(BPF_RET+BPF_K, pkt_size),
	BPF_STMT(BPF_RET+BPF_K, 0),
    };
    struct bpf_program prog;

    prog.bf_len = sizeof(insns) / sizeof(struct bpf_insn);
    prog.bf_insns = insns;
    return ioctl(fd, BIOCSETF, &prog);
}
Пример #14
0
void
npfctl_bpf_endgroup(npf_bpf_t *ctx)
{
	struct bpf_program *bp = &ctx->prog;
	const size_t curoff = bp->bf_len;

	/* If there are no blocks or only one - nothing to do. */
	if ((ctx->nblocks - ctx->gblock) <= 1) {
		ctx->goff = ctx->gblock = 0;
		return;
	}

	/*
	 * Append a failure return as a fall-through i.e. if there is
	 * no match within the group.
	 */
	struct bpf_insn insns_ret[] = {
		BPF_STMT(BPF_RET+BPF_K, NPF_BPF_FAILURE),
	};
	add_insns(ctx, insns_ret, __arraycount(insns_ret));

	/*
	 * Adjust jump offsets: on match - jump outside the group i.e.
	 * to the current offset.  Otherwise, jump to the next instruction
	 * which would lead to the fall-through code above if none matches.
	 */
	fixup_jumps(ctx, ctx->goff, curoff, true);
	ctx->goff = ctx->gblock = 0;
}
Пример #15
0
ATF_TC_BODY(bpfjit_extmem_side_effect, tc)
{
	static struct bpf_insn insns[] = {
		BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 0),  /* A <- P[0]  */
		BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 2), /* X <- 2     */
		BPF_STMT(BPF_ST, 1),                /* M[1] <- A  */
		BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0), /* A <- A + X */
		BPF_STMT(BPF_STX, 2),               /* M[2] <- X  */
		BPF_STMT(BPF_ST, 3),                /* M[3] <- A  */
		BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 99), /* A <- P[99] */
		BPF_STMT(BPF_RET+BPF_A, 0)          /* ret A      */
	};

	bpfjit_func_t code;
	uint8_t pkt[1] = { 1 };
	uint32_t mem[ctx.extwords];

	/* Pre-inited words. */
	mem[0] = 0;
	mem[3] = 7;

	mem[1] = mem[2] = 0xdeadbeef;

	bpf_args_t args = {
		.pkt = pkt,
		.buflen = sizeof(pkt),
		.wirelen = sizeof(pkt),
		.mem = mem,
	};

	size_t insn_count = sizeof(insns) / sizeof(insns[0]);

	RZ(rump_init());

	rump_schedule();
	code = rumpns_bpfjit_generate_code(&ctx, insns, insn_count);
	rump_unschedule();
	ATF_REQUIRE(code != NULL);

	ATF_CHECK(code(&ctx, &args) == 0);

	rump_schedule();
	rumpns_bpfjit_free_code(code);
	rump_unschedule();

	ATF_CHECK(mem[0] == 0);
	ATF_CHECK(mem[1] == 1);
	ATF_CHECK(mem[2] == 2);
	ATF_CHECK(mem[3] == 3);
}

ATF_TC(bpfjit_extmem_invalid_store);
ATF_TC_HEAD(bpfjit_extmem_invalid_store, tc)
{
	atf_tc_set_md_var(tc, "descr", "Test that out-of-range store "
	    "fails validation");
}
Пример #16
0
/*
 * npfctl_bpf_tcpfl: code block to match TCP flags.
 */
void
npfctl_bpf_tcpfl(npf_bpf_t *ctx, uint8_t tf, uint8_t tf_mask, bool checktcp)
{
	const u_int tcpfl_off = offsetof(struct tcphdr, th_flags);
	const bool usingmask = tf_mask != tf;

	/* X <- IP header length */
	fetch_l3(ctx, AF_UNSPEC, X_EQ_L4OFF);
	if (checktcp) {
		const u_int jf = usingmask ? 3 : 2;
		assert(ctx->ingroup == false);

		/* A <- L4 protocol; A == TCP?  If not, jump out. */
		struct bpf_insn insns_tcp[] = {
			BPF_STMT(BPF_LD+BPF_W+BPF_MEM, BPF_MW_L4PROTO),
			BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, IPPROTO_TCP, 0, jf),
		};
		add_insns(ctx, insns_tcp, __arraycount(insns_tcp));
	} else {
		assert(ctx->flags & CHECKED_L4);
	}

	struct bpf_insn insns_tf[] = {
		/* A <- TCP flags */
		BPF_STMT(BPF_LD+BPF_B+BPF_IND, tcpfl_off),
	};
	add_insns(ctx, insns_tf, __arraycount(insns_tf));

	if (usingmask) {
		/* A <- (A & mask) */
		struct bpf_insn insns_mask[] = {
			BPF_STMT(BPF_ALU+BPF_AND+BPF_K, tf_mask),
		};
		add_insns(ctx, insns_mask, __arraycount(insns_mask));
	}

	struct bpf_insn insns_cmp[] = {
		/* A == expected-TCP-flags? */
		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, tf, 0, JUMP_MAGIC),
	};
	add_insns(ctx, insns_cmp, __arraycount(insns_cmp));

	if (!checktcp) {
		uint32_t mwords[] = { BM_TCPFL, 2, tf, tf_mask};
		done_block(ctx, mwords, sizeof(mwords));
	}
}
Пример #17
0
ATF_TC_BODY(bpfjit_extmem_invalid_store, tc)
{
	static struct bpf_insn insns[] = {
		BPF_STMT(BPF_ST, 4),
		BPF_STMT(BPF_RET+BPF_A, 0)
	};

	bpfjit_func_t code;
	size_t insn_count = sizeof(insns) / sizeof(insns[0]);

	RZ(rump_init());

	rump_schedule();
	code = rumpns_bpfjit_generate_code(&ctx, insns, insn_count);
	rump_unschedule();
	ATF_CHECK(code == NULL);
}
Пример #18
0
struct bpf_program *
npfctl_bpf_complete(npf_bpf_t *ctx)
{
	struct bpf_program *bp = &ctx->prog;
	const u_int retoff = bp->bf_len;

	/* Add the return fragment (success and failure paths). */
	struct bpf_insn insns_ret[] = {
		BPF_STMT(BPF_RET+BPF_K, NPF_BPF_SUCCESS),
		BPF_STMT(BPF_RET+BPF_K, NPF_BPF_FAILURE),
	};
	add_insns(ctx, insns_ret, __arraycount(insns_ret));

	/* Fixup all jumps to the main failure path. */
	fixup_jumps(ctx, 0, retoff, false);

	return &ctx->prog;
}
Пример #19
0
ATF_TC_BODY(bpfjit_extmem_load_preinited, tc)
{
	static struct bpf_insn insns[] = {
		BPF_STMT(BPF_LD+BPF_MEM, 3),
		BPF_STMT(BPF_RET+BPF_A, 0)
	};

	bpfjit_func_t code;
	uint8_t pkt[1] = { 0 };
	uint32_t mem[ctx.extwords];

	/* Pre-inited words. */
	mem[0] = 0;
	mem[3] = 3;

	bpf_args_t args = {
		.pkt = pkt,
		.buflen = sizeof(pkt),
		.wirelen = sizeof(pkt),
		.mem = mem,
	};

	size_t insn_count = sizeof(insns) / sizeof(insns[0]);

	RZ(rump_init());

	rump_schedule();
	code = rumpns_bpfjit_generate_code(&ctx, insns, insn_count);
	rump_unschedule();
	ATF_REQUIRE(code != NULL);

	ATF_CHECK(code(&ctx, &args) == 3);

	rump_schedule();
	rumpns_bpfjit_free_code(code);
	rump_unschedule();
}

ATF_TC(bpfjit_extmem_invalid_load);
ATF_TC_HEAD(bpfjit_extmem_invalid_load, tc)
{
	atf_tc_set_md_var(tc, "descr", "Test that out-of-range load "
	    "fails validation");
}
Пример #20
0
static int setup_seccomp_filter(void)
{
	struct sock_filter filter[] = {
		BPF_STMT(BPF_LD+BPF_W+BPF_ABS, offsetof(struct seccomp_data, nr)),
		/* Allow all syscalls except ptrace */
		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, __NR_ptrace, 0, 1),
		BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_KILL),
		BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW),
	};

	struct sock_fprog bpf_prog = {
		.len = (unsigned short)(sizeof(filter)/sizeof(filter[0])),
		.filter = filter,
	};

	if (sys_prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, (long) &bpf_prog, 0, 0) < 0)
		return -1;

	return 0;
}

static int check_ptrace_dump_seccomp_filters(void)
{
	pid_t pid;
	int ret = 0, len;

	if (opts.check_ms_kernel) {
		pr_warn("Skipping PTRACE_SECCOMP_GET_FILTER check");
		return 0;
	}

	pid = fork_and_ptrace_attach(setup_seccomp_filter);
	if (pid < 0)
		return -1;

	len = ptrace(PTRACE_SECCOMP_GET_FILTER, pid, 0, NULL);
	if (len < 0) {
		ret = -1;
		pr_perror("Dumping seccomp filters not supported");
	}

	kill(pid, SIGKILL);
	return ret;
}
Пример #21
0
/**********************************************************************
*%FUNCTION: initFilter
*%ARGUMENTS:
* fd -- file descriptor of BSD device
* type -- Ethernet frame type (0 for watch mode)
* hwaddr -- buffer with ehthernet address
*%RETURNS:
* Nothing
*%DESCRIPTION:
* Initializes the packet filter rules.
***********************************************************************/
void
initFilter(int fd, UINT16_t type, unsigned char *hwaddr)
{
    /* Packet Filter Instructions:
     * Note that the ethernet type names come from "pppoe.h" and are
     * used here to maintain consistency with the rest of this file. */
    static struct bpf_insn bpfRun[] = {         /* run PPPoE */
        BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 12),     /* ethernet type */
        BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, ETH_PPPOE_SESSION, 5, 0),
        BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, ETH_PPPOE_DISCOVERY, 0, 9),
        BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 0),      /* first word of dest. addr */
#define PPPOE_BCAST_CMPW 4                     /* offset of word compare */
        BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0, 0, 2),
        BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 4),      /* next 1/2 word of dest. */
#define PPPOE_BCAST_CMPH 6                     /* offset of 1/2 word compare */
        BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0, 4, 0),
        BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 0),      /* first word of dest. addr */
#define PPPOE_FILTER_CMPW 8                     /* offset of word compare */
        BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0, 0, 3),
        BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 4),      /* next 1/2 word of dest. */
#define PPPOE_FILTER_CMPH 10                    /* offset of 1/rd compare */
        BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0, 0, 1),
        BPF_STMT(BPF_RET+BPF_K, (u_int) -1),    /* keep packet */
        BPF_STMT(BPF_RET+BPF_K, 0),             /* drop packet */
    };

    /* Fix the potentially varying parts */
    bpfRun[1].code = (u_short) BPF_JMP+BPF_JEQ+BPF_K;
    bpfRun[1].jt   = 5;
    bpfRun[1].jf   = 0;
    bpfRun[1].k    = Eth_PPPOE_Session;

    bpfRun[2].code = (u_short) BPF_JMP+BPF_JEQ+BPF_K;
    bpfRun[2].jt   = 0;
    bpfRun[2].jf   = 9;
    bpfRun[2].k    = Eth_PPPOE_Discovery;

    {
      struct bpf_insn bpfInsn[sizeof(bpfRun) / sizeof(bpfRun[0])];
      struct bpf_program bpfProgram;
      memcpy(bpfInsn, bpfRun, sizeof(bpfRun));
      bpfInsn[PPPOE_BCAST_CMPW].k = ((0xff << 24) | (0xff << 16) |
                                     (0xff << 8) | 0xff);
      bpfInsn[PPPOE_BCAST_CMPH].k = ((0xff << 8) | 0xff);
      bpfInsn[PPPOE_FILTER_CMPW].k = ((hwaddr[0] << 24) | (hwaddr[1] << 16) |
				      (hwaddr[2] << 8) | hwaddr[3]);
      bpfInsn[PPPOE_FILTER_CMPH].k = ((hwaddr[4] << 8) | hwaddr[5]);
      bpfProgram.bf_len = (sizeof(bpfInsn) / sizeof(bpfInsn[0]));
      bpfProgram.bf_insns = &bpfInsn[0];
      
      /* Apply the filter */
      if (ioctl(fd, BIOCSETF, &bpfProgram) < 0) {
	fatalSys("ioctl(BIOCSETF)");
      }
    }
}
Пример #22
0
static int install_filter(int nr, int arch, int error)
{
	struct sock_filter filter[] = {
		BPF_STMT(BPF_LD+BPF_W+BPF_ABS,
			 (offsetof(struct seccomp_data, arch))),
		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, arch, 0, 3),
		BPF_STMT(BPF_LD+BPF_W+BPF_ABS,
			 (offsetof(struct seccomp_data, nr))),
		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, nr, 0, 1),
		BPF_STMT(BPF_RET+BPF_K,
			 SECCOMP_RET_ERRNO|(error & SECCOMP_RET_DATA)),
		BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW),
	};
	struct sock_fprog prog = {
		.len = (unsigned short)(sizeof(filter)/sizeof(filter[0])),
		.filter = filter,
	};
	if (prctl(PR_SET_SECCOMP, 2, &prog)) {
		perror("prctl");
		return 1;
	}
	return 0;
}

int main(int argc, char **argv)
{
	if (argc < 5) {
		fprintf(stderr, "Usage:\n"
			"dropper <syscall_nr> <arch> <errno> <prog> [<args>]\n"
			"Hint:	AUDIT_ARCH_I386: 0x%X\n"
			"	AUDIT_ARCH_X86_64: 0x%X\n"
			"\n", AUDIT_ARCH_I386, AUDIT_ARCH_X86_64);
		return 1;
	}
	if (install_filter(strtol(argv[1], NULL, 0), strtol(argv[2], NULL, 0),
			   strtol(argv[3], NULL, 0)))
		return 1;
	execv(argv[4], &argv[4]);
	printf("Failed to execv\n");
	return 255;
}
Пример #23
0
int
bpf_filter_receive_none(int fd)
{
    struct bpf_insn insns[] = {
	BPF_STMT(BPF_RET+BPF_K, 0),
    };
    struct bpf_program prog;

    prog.bf_len = sizeof(insns) / sizeof(struct bpf_insn);
    prog.bf_insns = insns;
    return ioctl(fd, BIOCSETF, &prog);
}
Пример #24
0
int qrpc_set_filter(const int sock)
{
	struct sock_filter filter[] = {
		BPF_STMT(BPF_LD + BPF_H + BPF_ABS, ETH_ALEN << 1),	/* read packet type id */
		BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K,
			QRPC_RAW_SOCK_PROT, 0, 1),			/* if qtn packet */
		BPF_STMT(BPF_RET + BPF_K, ETH_FRAME_LEN),		/* accept packet */
		BPF_STMT(BPF_RET + BPF_K, 0)				/* else  ignore packet */
	};
	struct sock_fprog fp;

	fp.filter = filter;
	fp.len = ARRAY_SIZE(filter);

	if (setsockopt(sock, SOL_SOCKET, SO_ATTACH_FILTER, &fp, sizeof(fp)) < 0) {
		printf("Cannot set rpc packet filter\n");
		return -1;
	}

	return 0;
}
Пример #25
0
int lldp_network_bind_raw_socket(int ifindex) {
        typedef struct LLDPFrame {
                struct ethhdr hdr;
                uint8_t tlvs[0];
        } LLDPFrame;

        struct sock_filter filter[] = {
                BPF_STMT(BPF_LD + BPF_W + BPF_ABS, offsetof(LLDPFrame, hdr.h_dest)),      /* A <- 4 bytes of destination MAC */
                BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, 0x0180c200, 1, 0),                    /* A != 01:80:c2:00 */
                BPF_STMT(BPF_RET + BPF_K, 0),                                             /* drop packet */
                BPF_STMT(BPF_LD + BPF_H + BPF_ABS, offsetof(LLDPFrame, hdr.h_dest) + 4),  /* A <- remaining 2 bytes of destination MAC */
                BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, 0x0000, 3, 0),                        /* A != 00:00 */
                BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, 0x0003, 2, 0),                        /* A != 00:03 */
                BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, 0x000e, 1, 0),                        /* A != 00:0e */
                BPF_STMT(BPF_RET + BPF_K, 0),                                             /* drop packet */
                BPF_STMT(BPF_LD + BPF_H + BPF_ABS, offsetof(LLDPFrame, hdr.h_proto)),     /* A <- protocol */
                BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, ETHERTYPE_LLDP, 1, 0),                /* A != ETHERTYPE_LLDP */
                BPF_STMT(BPF_RET + BPF_K, 0),                                             /* drop packet */
                BPF_STMT(BPF_RET + BPF_K, (uint32_t) -1),                                 /* accept packet */
        };

        struct sock_fprog fprog = {
                .len = ELEMENTSOF(filter),
                .filter = filter
        };

        _cleanup_close_ int s = -1;

        union sockaddr_union saddrll = {
                .ll.sll_family = AF_PACKET,
                .ll.sll_ifindex = ifindex,
        };

        int r;

        assert(ifindex > 0);

        s = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
        if (s < 0)
                return -errno;

        r = setsockopt(s, SOL_SOCKET, SO_ATTACH_FILTER, &fprog, sizeof(fprog));
        if (r < 0)
                return -errno;

        r = bind(s, &saddrll.sa, sizeof(saddrll.ll));
        if (r < 0)
                return -errno;

        r = s;
        s = -1;

        return r;
}
Пример #26
0
void
initFilter(int fd, UINT16_t type, unsigned char *hwaddr)
{
    static struct bpf_insn bpfRun[] = {         
	BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 12),     
	BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, ETH_PPPOE_SESSION, 5, 0),
	BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, ETH_PPPOE_DISCOVERY, 0, 9),
	BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 0),      
#define PPPOE_BCAST_CMPW 4                     
	BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0, 0, 2),
	BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 4),      
#define PPPOE_BCAST_CMPH 6                     
	BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0, 4, 0),
	BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 0),      
#define PPPOE_FILTER_CMPW 8                     
	BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0, 0, 3),
	BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 4),      
#define PPPOE_FILTER_CMPH 10                    
	BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0, 0, 1),
	BPF_STMT(BPF_RET+BPF_K, (u_int) -1),    
	BPF_STMT(BPF_RET+BPF_K, 0),             
    };

    
    bpfRun[1].code = (u_short) BPF_JMP+BPF_JEQ+BPF_K;
    bpfRun[1].jt   = 5;
    bpfRun[1].jf   = 0;
    bpfRun[1].k    = Eth_PPPOE_Session;

    bpfRun[2].code = (u_short) BPF_JMP+BPF_JEQ+BPF_K;
    bpfRun[2].jt   = 0;
    bpfRun[2].jf   = 9;
    bpfRun[2].k    = Eth_PPPOE_Discovery;

    {
      struct bpf_insn bpfInsn[sizeof(bpfRun) / sizeof(bpfRun[0])];
      struct bpf_program bpfProgram;
      memcpy(bpfInsn, bpfRun, sizeof(bpfRun));
      bpfInsn[PPPOE_BCAST_CMPW].k = ((0xff << 24) | (0xff << 16) |
				     (0xff << 8) | 0xff);
      bpfInsn[PPPOE_BCAST_CMPH].k = ((0xff << 8) | 0xff);
      bpfInsn[PPPOE_FILTER_CMPW].k = ((hwaddr[0] << 24) | (hwaddr[1] << 16) |
				      (hwaddr[2] << 8) | hwaddr[3]);
      bpfInsn[PPPOE_FILTER_CMPH].k = ((hwaddr[4] << 8) | hwaddr[5]);
      bpfProgram.bf_len = (sizeof(bpfInsn) / sizeof(bpfInsn[0]));
      bpfProgram.bf_insns = &bpfInsn[0];

      
      if (ioctl(fd, BIOCSETF, &bpfProgram) < 0) {
	fatalSys("ioctl(BIOCSETF)");
      }
    }
}
Пример #27
0
int arp_network_bind_raw_socket(int ifindex, union sockaddr_union *link) {

        static const struct sock_filter filter[] = {
                BPF_STMT(BPF_LD + BPF_W + BPF_LEN, 0),                                         /* A <- packet length */
                BPF_JUMP(BPF_JMP + BPF_JGE + BPF_K, sizeof(struct ether_arp), 1, 0),           /* packet >= arp packet ? */
                BPF_STMT(BPF_RET + BPF_K, 0),                                                  /* ignore */
                BPF_STMT(BPF_LD + BPF_H + BPF_ABS, offsetof(struct ether_arp, ea_hdr.ar_hrd)), /* A <- header */
                BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, ARPHRD_ETHER, 1, 0),                       /* header == ethernet ? */
                BPF_STMT(BPF_RET + BPF_K, 0),                                                  /* ignore */
                BPF_STMT(BPF_LD + BPF_H + BPF_ABS, offsetof(struct ether_arp, ea_hdr.ar_pro)), /* A <- protocol */
                BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, ETHERTYPE_IP, 1, 0),                       /* protocol == IP ? */
                BPF_STMT(BPF_RET + BPF_K, 0),                                                  /* ignore */
                BPF_STMT(BPF_LD + BPF_H + BPF_ABS, offsetof(struct ether_arp, ea_hdr.ar_op)),  /* A <- operation */
                BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, ARPOP_REQUEST, 0, 1),                      /* protocol == request ? */
                BPF_STMT(BPF_RET + BPF_K, 65535),                                              /* return all */
                BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, ARPOP_REPLY, 0, 1),                        /* protocol == reply ? */
                BPF_STMT(BPF_RET + BPF_K, 65535),                                              /* return all */
                BPF_STMT(BPF_RET + BPF_K, 0),                                                  /* ignore */
        };
        struct sock_fprog fprog = {
                .len = ELEMENTSOF(filter),
                .filter = (struct sock_filter*) filter
        };
        _cleanup_close_ int s = -1;
        int r;

        assert(ifindex > 0);
        assert(link);

        s = socket(PF_PACKET, SOCK_DGRAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0);
        if (s < 0)
                return -errno;

        r = setsockopt(s, SOL_SOCKET, SO_ATTACH_FILTER, &fprog, sizeof(fprog));
        if (r < 0)
                return -errno;

        link->ll.sll_family = AF_PACKET;
        link->ll.sll_protocol = htons(ETH_P_ARP);
        link->ll.sll_ifindex = ifindex;
        link->ll.sll_halen = ETH_ALEN;
        memset(link->ll.sll_addr, 0xff, ETH_ALEN);

        r = bind(s, &link->sa, sizeof(link->ll));
        if (r < 0)
                return -errno;

        r = s;
        s = -1;

        return r;
}
static void android_net_utils_attachRaFilter(JNIEnv *env, jobject clazz, jobject javaFd,
        jint hardwareAddressType)
{
    if (hardwareAddressType != ARPHRD_ETHER) {
        jniThrowExceptionFmt(env, "java/net/SocketException",
                "attachRaFilter only supports ARPHRD_ETHER");
        return;
    }

    uint32_t ipv6_offset = sizeof(ether_header);
    uint32_t ipv6_next_header_offset = ipv6_offset + offsetof(ip6_hdr, ip6_nxt);
    uint32_t icmp6_offset = ipv6_offset + sizeof(ip6_hdr);
    uint32_t icmp6_type_offset = icmp6_offset + offsetof(icmp6_hdr, icmp6_type);
    struct sock_filter filter_code[] = {
        // Check IPv6 Next Header is ICMPv6.
        BPF_STMT(BPF_LD  | BPF_B   | BPF_ABS,  ipv6_next_header_offset),
        BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K,    IPPROTO_ICMPV6, 0, 3),

        // Check ICMPv6 type is Router Advertisement.
        BPF_STMT(BPF_LD  | BPF_B   | BPF_ABS,  icmp6_type_offset),
        BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K,    ND_ROUTER_ADVERT, 0, 1),

        // Accept or reject.
        BPF_STMT(BPF_RET | BPF_K,              0xffff),
        BPF_STMT(BPF_RET | BPF_K,              0)
    };
    struct sock_fprog filter = {
        sizeof(filter_code) / sizeof(filter_code[0]),
        filter_code,
    };

    int fd = jniGetFDFromFileDescriptor(env, javaFd);
    if (setsockopt(fd, SOL_SOCKET, SO_ATTACH_FILTER, &filter, sizeof(filter)) != 0) {
        jniThrowExceptionFmt(env, "java/net/SocketException",
                "setsockopt(SO_ATTACH_FILTER): %s", strerror(errno));
    }
}
Пример #29
0
static void install_filter(void) {
  struct sock_filter filter[] = { /* Allow all system calls */
                                  BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW)
  };
  struct sock_fprog prog = {
    .len = (unsigned short)(sizeof(filter) / sizeof(filter[0])),
    .filter = filter,
  };
  int ret;

  ret = syscall(RR_seccomp, SECCOMP_SET_MODE_FILTER, SECCOMP_FILTER_FLAG_TSYNC,
                &prog);
  if (ret == -1 && errno == ENOSYS) {
    atomic_puts("seccomp syscall not supported");
    atomic_puts("EXIT-SUCCESS");
    exit(0);
  }
  test_assert(ret == 0);
}

static void* waiting_thread(__attribute__((unused)) void* p) {
  char buf;
  test_assert(1 == read(pipe_fds[0], &buf, 1));
  /* Check this thread *was* affected by SECCOMP_FILTER_FLAG_TSYNC */
  test_assert(2 == prctl(PR_GET_SECCOMP));
  return NULL;
}

int main(void) {
  pthread_t w_thread;

  test_assert(0 == pipe(pipe_fds));

  pthread_create(&w_thread, NULL, waiting_thread, NULL);

  /* Prepare syscallbuf patch path. Need to do this after
     pthread_create since when we have more than one
     thread we take a different syscall path... */
  test_assert(0 == prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0));
  install_filter();
  test_assert(2 == prctl(PR_GET_SECCOMP));

  test_assert(1 == write(pipe_fds[1], "c", 1));
  pthread_join(w_thread, NULL);

  atomic_puts("EXIT-SUCCESS");

  return 0;
}
Пример #30
0
int main(void)
{
	const size_t arch_offset    = offsetof(struct seccomp_data, arch);
	const size_t syscall_offset = offsetof(struct seccomp_data, nr);
	struct sock_fprog program;

	#define ARCH_NR AUDIT_ARCH_X86_64

	struct sock_filter filter[] = {
		BPF_STMT(BPF_LD + BPF_W + BPF_ABS, arch_offset),
		BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, AUDIT_ARCH_X86_64, 0, 1),
		BPF_STMT(BPF_LD + BPF_W + BPF_ABS, syscall_offset),
		BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, 0, 0, 1),
		BPF_STMT(BPF_RET + BPF_K, SECCOMP_RET_TRACE)
	};

	program.filter = filter;
	program.len = sizeof(filter) / sizeof(struct sock_filter);

	(void) prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
	(void) prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &program);

	return 1;
}