History

bpf: reject program if a __user tagged memory accessed in kernel way

BPF verifier supports direct memory access for BPF_PROG_TYPE_TRACING type of bpf programs, e.g., a->b. If "a" is a pointer pointing to kernel memory, bpf verifier will allow user to write code in C like a->b and the verifier will translate it to a kernel load properly. If "a" is a pointer to user memory, it is expected that bpf developer should be bpf_probe_read_user() helper to get the value a->b. Without utilizing BTF __user tagging information, current verifier will assume that a->b is a kernel memory access and this may generate incorrect result. Now BTF contains __user information, it can check whether the pointer points to a user memory or not. If it is, the verifier can reject the program and force users to use bpf_probe_read_user() helper explicitly. In the future, we can easily extend btf_add_space for other address space tagging, for example, rcu/percpu etc.

Yonghong Song committed 4 years ago

Commit c6f1bfe1 parent 7472d5a6 files · +71 −24Browse files

Unified · Split

6 files
  1. include/linux/bpf.h +6 −3
  2. include/linux/btf.h +5 −0
  3. kernel/bpf/btf.c +28 −6
  4. kernel/bpf/verifier.c +24 −11
  5. net/bpf/bpf_dummy_struct_ops.c +4 −2
  6. net/ipv4/bpf_tcp_ca.c +4 −2
include/linux/bpf.h+6−3
@@ -332,7 +332,10 @@ enum bpf_type_flag { · 331 unmodified lines
332332 */
333333 MEM_ALLOC = BIT(2 + BPF_BASE_TYPE_BITS),
334334
335− __BPF_TYPE_LAST_FLAG = MEM_ALLOC,
335+ /* MEM is in user address space. */
336+ MEM_USER = BIT(3 + BPF_BASE_TYPE_BITS),
337+
338+ __BPF_TYPE_LAST_FLAG = MEM_USER,
336339 };
337340
338341 /* Max number of base types. */
@@ -588,7 +591,7 @@ struct bpf_verifier_ops { · 249 unmodified lines
588591 const struct btf *btf,
589592 const struct btf_type *t, int off, int size,
590593 enum bpf_access_type atype,
591− u32 *next_btf_id);
594+ u32 *next_btf_id, enum bpf_type_flag *flag);
592595 };
593596
594597 struct bpf_prog_offload_ops {
@@ -1780,7 +1783,7 @@ static inline bool bpf_tracing_btf_ctx_access(int off, int size, · 1185 unmodified lines
17801783 int btf_struct_access(struct bpf_verifier_log *log, const struct btf *btf,
17811784 const struct btf_type *t, int off, int size,
17821785 enum bpf_access_type atype,
1783− u32 *next_btf_id);
1786+ u32 *next_btf_id, enum bpf_type_flag *flag);
17841787 bool btf_struct_ids_match(struct bpf_verifier_log *log,
17851788 const struct btf *btf, u32 id, int off,
17861789 const struct btf *need_btf, u32 need_type_id);
include/linux/btf.h+5−0
@@ -238,6 +238,11 @@ static inline bool btf_type_is_var(const struct btf_type *t) · 237 unmodified lines
238238 return BTF_INFO_KIND(t->info) == BTF_KIND_VAR;
239239 }
240240
241+static inline bool btf_type_is_type_tag(const struct btf_type *t)
242+{
243+ return BTF_INFO_KIND(t->info) == BTF_KIND_TYPE_TAG;
244+}
245+
241246 /* union is only a special case of struct:
242247 * all its offsetof(member) == 0
243248 */
kernel/bpf/btf.c+28−6
@@ -4886,6 +4886,7 @@ bool btf_ctx_access(int off, int size, enum bpf_access_type type, · 4885 unmodified lines
48864886 const char *tname = prog->aux->attach_func_name;
48874887 struct bpf_verifier_log *log = info->log;
48884888 const struct btf_param *args;
4889+ const char *tag_value;
48894890 u32 nr_args, arg;
48904891 int i, ret;
48914892
@@ -5038,6 +5039,13 @@ bool btf_ctx_access(int off, int size, enum bpf_access_type type, · 146 unmodified lines
50385039 info->btf = btf;
50395040 info->btf_id = t->type;
50405041 t = btf_type_by_id(btf, t->type);
5042+
5043+ if (btf_type_is_type_tag(t)) {
5044+ tag_value = __btf_name_by_offset(btf, t->name_off);
5045+ if (strcmp(tag_value, "user") == 0)
5046+ info->reg_type |= MEM_USER;
5047+ }
5048+
50415049 /* skip modifiers */
50425050 while (btf_type_is_modifier(t)) {
50435051 info->btf_id = t->type;
@@ -5064,12 +5072,12 @@ enum bpf_struct_walk_result { · 20 unmodified lines
50645072
50655073 static int btf_struct_walk(struct bpf_verifier_log *log, const struct btf *btf,
50665074 const struct btf_type *t, int off, int size,
5067− u32 *next_btf_id)
5075+ u32 *next_btf_id, enum bpf_type_flag *flag)
50685076 {
50695077 u32 i, moff, mtrue_end, msize = 0, total_nelems = 0;
50705078 const struct btf_type *mtype, *elem_type = NULL;
50715079 const struct btf_member *member;
5072− const char *tname, *mname;
5080+ const char *tname, *mname, *tag_value;
50735081 u32 vlen, elem_id, mid;
50745082
50755083 again:
@@ -5253,7 +5261,8 @@ error: · 177 unmodified lines
52535261 }
52545262
52555263 if (btf_type_is_ptr(mtype)) {
5256− const struct btf_type *stype;
5264+ const struct btf_type *stype, *t;
5265+ enum bpf_type_flag tmp_flag = 0;
52575266 u32 id;
52585267
52595268 if (msize != size || off != moff) {
@@ -5262,9 +5271,19 @@ error: · 2 unmodified lines
52625271 mname, moff, tname, off, size);
52635272 return -EACCES;
52645273 }
5274+
5275+ /* check __user tag */
5276+ t = btf_type_by_id(btf, mtype->type);
5277+ if (btf_type_is_type_tag(t)) {
5278+ tag_value = __btf_name_by_offset(btf, t->name_off);
5279+ if (strcmp(tag_value, "user") == 0)
5280+ tmp_flag = MEM_USER;
5281+ }
5282+
52655283 stype = btf_type_skip_modifiers(btf, mtype->type, &id);
52665284 if (btf_type_is_struct(stype)) {
52675285 *next_btf_id = id;
5286+ *flag = tmp_flag;
52685287 return WALK_PTR;
52695288 }
52705289 }
@@ -5291,13 +5310,14 @@ error: · 20 unmodified lines
52915310 int btf_struct_access(struct bpf_verifier_log *log, const struct btf *btf,
52925311 const struct btf_type *t, int off, int size,
52935312 enum bpf_access_type atype __maybe_unused,
5294− u32 *next_btf_id)
5313+ u32 *next_btf_id, enum bpf_type_flag *flag)
52955314 {
5315+ enum bpf_type_flag tmp_flag = 0;
52965316 int err;
52975317 u32 id;
52985318
52995319 do {
5300− err = btf_struct_walk(log, btf, t, off, size, &id);
5320+ err = btf_struct_walk(log, btf, t, off, size, &id, &tmp_flag);
53015321
53025322 switch (err) {
53035323 case WALK_PTR:
@@ -5305,6 +5325,7 @@ int btf_struct_access(struct bpf_verifier_log *log, const struct btf *btf, · 1 unmodified line
53055325 * we're done.
53065326 */
53075327 *next_btf_id = id;
5328+ *flag = tmp_flag;
53085329 return PTR_TO_BTF_ID;
53095330 case WALK_SCALAR:
53105331 return SCALAR_VALUE;
@@ -5349,6 +5370,7 @@ bool btf_struct_ids_match(struct bpf_verifier_log *log, · 38 unmodified lines
53495370 const struct btf *need_btf, u32 need_type_id)
53505371 {
53515372 const struct btf_type *type;
5373+ enum bpf_type_flag flag;
53525374 int err;
53535375
53545376 /* Are we already done? */
@@ -5359,7 +5381,7 @@ again: · 4 unmodified lines
53595381 type = btf_type_by_id(btf, id);
53605382 if (!type)
53615383 return false;
5362− err = btf_struct_walk(log, btf, type, off, 1, &id);
5384+ err = btf_struct_walk(log, btf, type, off, 1, &id, &flag);
53635385 if (err != WALK_STRUCT)
53645386 return false;
53655387
kernel/bpf/verifier.c+24−11
@@ -536,7 +536,7 @@ static bool is_cmpxchg_insn(const struct bpf_insn *insn) · 535 unmodified lines
536536 static const char *reg_type_str(struct bpf_verifier_env *env,
537537 enum bpf_reg_type type)
538538 {
539− char postfix[16] = {0}, prefix[16] = {0};
539+ char postfix[16] = {0}, prefix[32] = {0};
540540 static const char * const str[] = {
541541 [NOT_INIT] = "?",
542542 [SCALAR_VALUE] = "inv",
@@ -570,9 +570,11 @@ static const char *reg_type_str(struct bpf_verifier_env *env, · 27 unmodified lines
570570 }
571571
572572 if (type & MEM_RDONLY)
573− strncpy(prefix, "rdonly_", 16);
573+ strncpy(prefix, "rdonly_", 32);
574574 if (type & MEM_ALLOC)
575− strncpy(prefix, "alloc_", 16);
575+ strncpy(prefix, "alloc_", 32);
576+ if (type & MEM_USER)
577+ strncpy(prefix, "user_", 32);
576578
577579 snprintf(env->type_str_buf, TYPE_STR_BUF_LEN, "%s%s%s",
578580 prefix, str[base_type(type)], postfix);
@@ -1547,14 +1549,15 @@ static void mark_reg_not_init(struct bpf_verifier_env *env, · 968 unmodified lines
15471549 static void mark_btf_ld_reg(struct bpf_verifier_env *env,
15481550 struct bpf_reg_state *regs, u32 regno,
15491551 enum bpf_reg_type reg_type,
1550− struct btf *btf, u32 btf_id)
1552+ struct btf *btf, u32 btf_id,
1553+ enum bpf_type_flag flag)
15511554 {
15521555 if (reg_type == SCALAR_VALUE) {
15531556 mark_reg_unknown(env, regs, regno);
15541557 return;
15551558 }
15561559 mark_reg_known_zero(env, regs, regno);
1557− regs[regno].type = PTR_TO_BTF_ID;
1560+ regs[regno].type = PTR_TO_BTF_ID | flag;
15581561 regs[regno].btf = btf;
15591562 regs[regno].btf_id = btf_id;
15601563 }
@@ -4152,6 +4155,7 @@ static int check_ptr_to_btf_access(struct bpf_verifier_env *env, · 2591 unmodified lines
41524155 struct bpf_reg_state *reg = regs + regno;
41534156 const struct btf_type *t = btf_type_by_id(reg->btf, reg->btf_id);
41544157 const char *tname = btf_name_by_offset(reg->btf, t->name_off);
4158+ enum bpf_type_flag flag = 0;
41554159 u32 btf_id;
41564160 int ret;
41574161
@@ -4171,9 +4175,16 @@ static int check_ptr_to_btf_access(struct bpf_verifier_env *env, · 13 unmodified lines
41714175 return -EACCES;
41724176 }
41734177
4178+ if (reg->type & MEM_USER) {
4179+ verbose(env,
4180+ "R%d is ptr_%s access user memory: off=%d\n",
4181+ regno, tname, off);
4182+ return -EACCES;
4183+ }
4184+
41744185 if (env->ops->btf_struct_access) {
41754186 ret = env->ops->btf_struct_access(&env->log, reg->btf, t,
4176− off, size, atype, &btf_id);
4187+ off, size, atype, &btf_id, &flag);
41774188 } else {
41784189 if (atype != BPF_READ) {
41794190 verbose(env, "only read is supported\n");
@@ -4181,14 +4192,14 @@ static int check_ptr_to_btf_access(struct bpf_verifier_env *env, · 1 unmodified line
41814192 }
41824193
41834194 ret = btf_struct_access(&env->log, reg->btf, t, off, size,
4184− atype, &btf_id);
4195+ atype, &btf_id, &flag);
41854196 }
41864197
41874198 if (ret < 0)
41884199 return ret;
41894200
41904201 if (atype == BPF_READ && value_regno >= 0)
4191− mark_btf_ld_reg(env, regs, value_regno, ret, reg->btf, btf_id);
4202+ mark_btf_ld_reg(env, regs, value_regno, ret, reg->btf, btf_id, flag);
41924203
41934204 return 0;
41944205 }
@@ -4201,6 +4212,7 @@ static int check_ptr_to_map_access(struct bpf_verifier_env *env, · 6 unmodified lines
42014212 {
42024213 struct bpf_reg_state *reg = regs + regno;
42034214 struct bpf_map *map = reg->map_ptr;
4215+ enum bpf_type_flag flag = 0;
42044216 const struct btf_type *t;
42054217 const char *tname;
42064218 u32 btf_id;
@@ -4238,12 +4250,12 @@ static int check_ptr_to_map_access(struct bpf_verifier_env *env, · 31 unmodified lines
42384250 return -EACCES;
42394251 }
42404252
4241− ret = btf_struct_access(&env->log, btf_vmlinux, t, off, size, atype, &btf_id);
4253+ ret = btf_struct_access(&env->log, btf_vmlinux, t, off, size, atype, &btf_id, &flag);
42424254 if (ret < 0)
42434255 return ret;
42444256
42454257 if (value_regno >= 0)
4246− mark_btf_ld_reg(env, regs, value_regno, ret, btf_vmlinux, btf_id);
4258+ mark_btf_ld_reg(env, regs, value_regno, ret, btf_vmlinux, btf_id, flag);
42474259
42484260 return 0;
42494261 }
@@ -4444,7 +4456,8 @@ static int check_mem_access(struct bpf_verifier_env *env, int insn_idx, u32 regn · 194 unmodified lines
44444456 if (err < 0)
44454457 return err;
44464458
4447− err = check_ctx_access(env, insn_idx, off, size, t, &reg_type, &btf, &btf_id);
4459+ err = check_ctx_access(env, insn_idx, off, size, t, &reg_type, &btf,
4460+ &btf_id);
44484461 if (err)
44494462 verbose_linfo(env, insn_idx, "; ");
44504463 if (!err && t == BPF_READ && value_regno >= 0) {
net/bpf/bpf_dummy_struct_ops.c+4−2
@@ -145,7 +145,8 @@ static int bpf_dummy_ops_btf_struct_access(struct bpf_verifier_log *log, · 144 unmodified lines
145145 const struct btf *btf,
146146 const struct btf_type *t, int off,
147147 int size, enum bpf_access_type atype,
148− u32 *next_btf_id)
148+ u32 *next_btf_id,
149+ enum bpf_type_flag *flag)
149150 {
150151 const struct btf_type *state;
151152 s32 type_id;
@@ -162,7 +163,8 @@ static int bpf_dummy_ops_btf_struct_access(struct bpf_verifier_log *log, · 10 unmodified lines
162163 return -EACCES;
163164 }
164165
165− err = btf_struct_access(log, btf, t, off, size, atype, next_btf_id);
166+ err = btf_struct_access(log, btf, t, off, size, atype, next_btf_id,
167+ flag);
166168 if (err < 0)
167169 return err;
168170
net/ipv4/bpf_tcp_ca.c+4−2
@@ -96,12 +96,14 @@ static int bpf_tcp_ca_btf_struct_access(struct bpf_verifier_log *log, · 95 unmodified lines
9696 const struct btf *btf,
9797 const struct btf_type *t, int off,
9898 int size, enum bpf_access_type atype,
99− u32 *next_btf_id)
99+ u32 *next_btf_id,
100+ enum bpf_type_flag *flag)
100101 {
101102 size_t end;
102103
103104 if (atype == BPF_READ)
104− return btf_struct_access(log, btf, t, off, size, atype, next_btf_id);
105+ return btf_struct_access(log, btf, t, off, size, atype, next_btf_id,
106+ flag);
105107
106108 if (t != tcp_sock_type) {
107109 bpf_log(log, "only read is supported\n");