bpf_helper.c 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. /*
  2. * Seccomp BPF helper functions
  3. *
  4. * Copyright (c) 2012 The Chromium OS Authors <chromium-os-dev@chromium.org>
  5. * Author: Will Drewry <wad@chromium.org>
  6. *
  7. * The code may be used by anyone for any purpose,
  8. * and can serve as a starting point for developing
  9. * applications using prctl(PR_ATTACH_SECCOMP_FILTER).
  10. */
  11. #define _GNU_SOURCE 1
  12. #ifndef __GNUC__
  13. #define __GNUC__ 1
  14. #endif
  15. typedef __builtin_va_list __gnuc_va_list;
  16. #include "bpf-helper.h"
  17. #include "internal.h"
  18. int bpf_resolve_jumps(struct bpf_labels *labels,
  19. struct sock_filter *filter, int count)
  20. {
  21. struct sock_filter *begin = filter;
  22. __u8 insn = count - 1;
  23. if (count < 1)
  24. return -1;
  25. /*
  26. * Walk it once, backwards, to build the label table and do fixups.
  27. * Since backward jumps are disallowed by BPF, this is easy.
  28. */
  29. filter += insn;
  30. for (; filter >= begin; --insn, --filter) {
  31. if (filter->code != (BPF_JMP+BPF_JA))
  32. continue;
  33. switch ((filter->jt<<8)|filter->jf) {
  34. case (JUMP_JT<<8)|JUMP_JF:
  35. if (labels->labels[filter->k].location == 0xffffffff) {
  36. printf("Unresolved label: '%s'\n",
  37. labels->labels[filter->k].label);
  38. return 1;
  39. }
  40. filter->k = labels->labels[filter->k].location -
  41. (insn + 1);
  42. filter->jt = 0;
  43. filter->jf = 0;
  44. continue;
  45. case (LABEL_JT<<8)|LABEL_JF:
  46. if (labels->labels[filter->k].location != 0xffffffff) {
  47. printf("Duplicate label use: '%s'\n",
  48. labels->labels[filter->k].label);
  49. return 1;
  50. }
  51. labels->labels[filter->k].location = insn;
  52. filter->k = 0; /* fall through */
  53. filter->jt = 0;
  54. filter->jf = 0;
  55. continue;
  56. }
  57. }
  58. return 0;
  59. }
  60. /* Simple lookup table for labels. */
  61. __u32 seccomp_bpf_label(struct bpf_labels *labels, const char *label)
  62. {
  63. struct __bpf_label *begin = labels->labels, *end;
  64. int id;
  65. if (labels->count == 0) {
  66. begin->label = label;
  67. begin->location = 0xffffffff;
  68. labels->count++;
  69. return 0;
  70. }
  71. int len = strlen(label);
  72. end = begin + labels->count;
  73. for (id = 0; begin < end; ++begin, ++id) {
  74. if (!memcmp(label, begin->label, len + 1))
  75. return id;
  76. }
  77. begin->label = label;
  78. begin->location = 0xffffffff;
  79. labels->count++;
  80. return id;
  81. }
  82. void seccomp_bpf_print(struct sock_filter *filter, int count)
  83. {
  84. struct sock_filter *end = filter + count;
  85. for ( ; filter < end; ++filter)
  86. printf("{ code=%u,jt=%u,jf=%u,k=%u },\n",
  87. filter->code, filter->jt, filter->jf, filter->k);
  88. }