Commit e07b98d9bffe410019dfcf62c3428d4a96c56a2c

Authored by David S. Miller
1 parent c5fc9692d1

bpf: Add strict alignment flag for BPF_PROG_LOAD.

Add a new field, "prog_flags", and an initial flag value
BPF_F_STRICT_ALIGNMENT.

When set, the verifier will enforce strict pointer alignment
regardless of the setting of CONFIG_EFFICIENT_UNALIGNED_ACCESS.

The verifier, in this mode, will also use a fixed value of "2" in
place of NET_IP_ALIGN.

This facilitates test cases that will exercise and validate this part
of the verifier even when run on architectures where alignment doesn't
matter.

Signed-off-by: David S. Miller <davem@davemloft.net>
Acked-by: Daniel Borkmann <daniel@iogearbox.net>

Showing 6 changed files with 40 additions and 9 deletions Side-by-side Diff

include/linux/bpf_verifier.h
... ... @@ -90,6 +90,7 @@
90 90 struct bpf_prog *prog; /* eBPF program being verified */
91 91 struct bpf_verifier_stack_elem *head; /* stack of verifier states to be processed */
92 92 int stack_size; /* number of states to be processed */
  93 + bool strict_alignment; /* perform strict pointer alignment checks */
93 94 struct bpf_verifier_state cur_state; /* current verifier state */
94 95 struct bpf_verifier_state_list **explored_states; /* search pruning optimization */
95 96 const struct bpf_ext_analyzer_ops *analyzer_ops; /* external analyzer ops */
include/uapi/linux/bpf.h
... ... @@ -132,6 +132,13 @@
132 132 */
133 133 #define BPF_F_ALLOW_OVERRIDE (1U << 0)
134 134  
  135 +/* If BPF_F_STRICT_ALIGNMENT is used in BPF_PROG_LOAD command, the
  136 + * verifier will perform strict alignment checking as if the kernel
  137 + * has been built with CONFIG_EFFICIENT_UNALIGNED_ACCESS not set,
  138 + * and NET_IP_ALIGN defined to 2.
  139 + */
  140 +#define BPF_F_STRICT_ALIGNMENT (1U << 0)
  141 +
135 142 #define BPF_PSEUDO_MAP_FD 1
136 143  
137 144 /* flags for BPF_MAP_UPDATE_ELEM command */
... ... @@ -177,6 +184,7 @@
177 184 __u32 log_size; /* size of user buffer */
178 185 __aligned_u64 log_buf; /* user supplied buffer */
179 186 __u32 kern_version; /* checked when prog_type=kprobe */
  187 + __u32 prog_flags;
180 188 };
181 189  
182 190 struct { /* anonymous struct used by BPF_OBJ_* commands */
kernel/bpf/syscall.c
... ... @@ -783,7 +783,7 @@
783 783 EXPORT_SYMBOL_GPL(bpf_prog_get_type);
784 784  
785 785 /* last field in 'union bpf_attr' used by this command */
786   -#define BPF_PROG_LOAD_LAST_FIELD kern_version
  786 +#define BPF_PROG_LOAD_LAST_FIELD prog_flags
787 787  
788 788 static int bpf_prog_load(union bpf_attr *attr)
789 789 {
... ... @@ -794,6 +794,9 @@
794 794 bool is_gpl;
795 795  
796 796 if (CHECK_ATTR(BPF_PROG_LOAD))
  797 + return -EINVAL;
  798 +
  799 + if (attr->prog_flags & ~BPF_F_STRICT_ALIGNMENT)
797 800 return -EINVAL;
798 801  
799 802 /* copy eBPF program license from user space */
kernel/bpf/verifier.c
... ... @@ -791,6 +791,7 @@
791 791 static int check_pkt_ptr_alignment(const struct bpf_reg_state *reg,
792 792 int off, int size, bool strict)
793 793 {
  794 + int ip_align;
794 795 int reg_off;
795 796  
796 797 /* Byte size accesses are always allowed. */
797 798  
... ... @@ -807,10 +808,14 @@
807 808 reg_off += reg->aux_off;
808 809 }
809 810  
810   - /* skb->data is NET_IP_ALIGN-ed */
811   - if ((NET_IP_ALIGN + reg_off + off) % size != 0) {
  811 + /* skb->data is NET_IP_ALIGN-ed, but for strict alignment checking
  812 + * we force this to 2 which is universally what architectures use
  813 + * when they don't set CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS.
  814 + */
  815 + ip_align = strict ? 2 : NET_IP_ALIGN;
  816 + if ((ip_align + reg_off + off) % size != 0) {
812 817 verbose("misaligned packet access off %d+%d+%d size %d\n",
813   - NET_IP_ALIGN, reg_off, off, size);
  818 + ip_align, reg_off, off, size);
814 819 return -EACCES;
815 820 }
816 821  
817 822  
... ... @@ -828,10 +833,11 @@
828 833 return 0;
829 834 }
830 835  
831   -static int check_ptr_alignment(const struct bpf_reg_state *reg,
  836 +static int check_ptr_alignment(struct bpf_verifier_env *env,
  837 + const struct bpf_reg_state *reg,
832 838 int off, int size)
833 839 {
834   - bool strict = false;
  840 + bool strict = env->strict_alignment;
835 841  
836 842 if (!IS_ENABLED(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS))
837 843 strict = true;
... ... @@ -873,7 +879,7 @@
873 879 if (size < 0)
874 880 return size;
875 881  
876   - err = check_ptr_alignment(reg, off, size);
  882 + err = check_ptr_alignment(env, reg, off, size);
877 883 if (err)
878 884 return err;
879 885  
... ... @@ -3568,6 +3574,10 @@
3568 3574 } else {
3569 3575 log_level = 0;
3570 3576 }
  3577 + if (attr->prog_flags & BPF_F_STRICT_ALIGNMENT)
  3578 + env->strict_alignment = true;
  3579 + else
  3580 + env->strict_alignment = false;
3571 3581  
3572 3582 ret = replace_map_fd_with_map_ptr(env);
3573 3583 if (ret < 0)
... ... @@ -3673,6 +3683,7 @@
3673 3683 mutex_lock(&bpf_verifier_lock);
3674 3684  
3675 3685 log_level = 0;
  3686 + env->strict_alignment = false;
3676 3687  
3677 3688 env->explored_states = kcalloc(env->prog->len,
3678 3689 sizeof(struct bpf_verifier_state_list *),
tools/build/feature/test-bpf.c
... ... @@ -29,6 +29,7 @@
29 29 attr.log_size = 0;
30 30 attr.log_level = 0;
31 31 attr.kern_version = 0;
  32 + attr.prog_flags = 0;
32 33  
33 34 /*
34 35 * Test existence of __NR_bpf and BPF_PROG_LOAD.
tools/include/uapi/linux/bpf.h
... ... @@ -132,6 +132,13 @@
132 132 */
133 133 #define BPF_F_ALLOW_OVERRIDE (1U << 0)
134 134  
  135 +/* If BPF_F_STRICT_ALIGNMENT is used in BPF_PROG_LOAD command, the
  136 + * verifier will perform strict alignment checking as if the kernel
  137 + * has been built with CONFIG_EFFICIENT_UNALIGNED_ACCESS not set,
  138 + * and NET_IP_ALIGN defined to 2.
  139 + */
  140 +#define BPF_F_STRICT_ALIGNMENT (1U << 0)
  141 +
135 142 #define BPF_PSEUDO_MAP_FD 1
136 143  
137 144 /* flags for BPF_MAP_UPDATE_ELEM command */
... ... @@ -177,6 +184,7 @@
177 184 __u32 log_size; /* size of user buffer */
178 185 __aligned_u64 log_buf; /* user supplied buffer */
179 186 __u32 kern_version; /* checked when prog_type=kprobe */
  187 + __u32 prog_flags;
180 188 };
181 189  
182 190 struct { /* anonymous struct used by BPF_OBJ_* commands */
... ... @@ -481,8 +489,7 @@
481 489 * u32 bpf_get_socket_uid(skb)
482 490 * Get the owner uid of the socket stored inside sk_buff.
483 491 * @skb: pointer to skb
484   - * Return: uid of the socket owner on success or 0 if the socket pointer
485   - * inside sk_buff is NULL
  492 + * Return: uid of the socket owner on success or overflowuid if failed.
486 493 */
487 494 #define __BPF_FUNC_MAPPER(FN) \
488 495 FN(unspec), \