Skip to content

Commit f10d059

Browse files
zhuyifei1999Alexei Starovoitov
authored andcommitted
bpf: Make BPF_PROG_RUN_ARRAY return -err instead of allow boolean
Right now BPF_PROG_RUN_ARRAY and related macros return 1 or 0 for whether the prog array allows or rejects whatever is being hooked. The caller of these macros then return -EPERM or continue processing based on thw macro's return value. Unforunately this is inflexible, since -EPERM is the only err that can be returned. This patch should be a no-op; it prepares for the next patch. The returning of the -EPERM is moved to inside the macros, so the outer functions are directly returning what the macros returned if they are non-zero. Signed-off-by: YiFei Zhu <zhuyifei@google.com> Reviewed-by: Stanislav Fomichev <sdf@google.com> Link: https://lore.kernel.org/r/788abcdca55886d1f43274c918eaa9f792a9f33b.1639619851.git.zhuyifei@google.com Signed-off-by: Alexei Starovoitov <ast@kernel.org>
1 parent d81283d commit f10d059

File tree

3 files changed

+25
-34
lines changed

3 files changed

+25
-34
lines changed

include/linux/bpf.h

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1277,7 +1277,7 @@ static inline void bpf_reset_run_ctx(struct bpf_run_ctx *old_ctx)
12771277

12781278
typedef u32 (*bpf_prog_run_fn)(const struct bpf_prog *prog, const void *ctx);
12791279

1280-
static __always_inline u32
1280+
static __always_inline int
12811281
BPF_PROG_RUN_ARRAY_CG_FLAGS(const struct bpf_prog_array __rcu *array_rcu,
12821282
const void *ctx, bpf_prog_run_fn run_prog,
12831283
u32 *ret_flags)
@@ -1287,7 +1287,7 @@ BPF_PROG_RUN_ARRAY_CG_FLAGS(const struct bpf_prog_array __rcu *array_rcu,
12871287
const struct bpf_prog_array *array;
12881288
struct bpf_run_ctx *old_run_ctx;
12891289
struct bpf_cg_run_ctx run_ctx;
1290-
u32 ret = 1;
1290+
int ret = 0;
12911291
u32 func_ret;
12921292

12931293
migrate_disable();
@@ -1298,7 +1298,8 @@ BPF_PROG_RUN_ARRAY_CG_FLAGS(const struct bpf_prog_array __rcu *array_rcu,
12981298
while ((prog = READ_ONCE(item->prog))) {
12991299
run_ctx.prog_item = item;
13001300
func_ret = run_prog(prog, ctx);
1301-
ret &= (func_ret & 1);
1301+
if (!(func_ret & 1))
1302+
ret = -EPERM;
13021303
*(ret_flags) |= (func_ret >> 1);
13031304
item++;
13041305
}
@@ -1308,7 +1309,7 @@ BPF_PROG_RUN_ARRAY_CG_FLAGS(const struct bpf_prog_array __rcu *array_rcu,
13081309
return ret;
13091310
}
13101311

1311-
static __always_inline u32
1312+
static __always_inline int
13121313
BPF_PROG_RUN_ARRAY_CG(const struct bpf_prog_array __rcu *array_rcu,
13131314
const void *ctx, bpf_prog_run_fn run_prog)
13141315
{
@@ -1317,7 +1318,7 @@ BPF_PROG_RUN_ARRAY_CG(const struct bpf_prog_array __rcu *array_rcu,
13171318
const struct bpf_prog_array *array;
13181319
struct bpf_run_ctx *old_run_ctx;
13191320
struct bpf_cg_run_ctx run_ctx;
1320-
u32 ret = 1;
1321+
int ret = 0;
13211322

13221323
migrate_disable();
13231324
rcu_read_lock();
@@ -1326,7 +1327,8 @@ BPF_PROG_RUN_ARRAY_CG(const struct bpf_prog_array __rcu *array_rcu,
13261327
old_run_ctx = bpf_set_run_ctx(&run_ctx.run_ctx);
13271328
while ((prog = READ_ONCE(item->prog))) {
13281329
run_ctx.prog_item = item;
1329-
ret &= run_prog(prog, ctx);
1330+
if (!run_prog(prog, ctx))
1331+
ret = -EPERM;
13301332
item++;
13311333
}
13321334
bpf_reset_run_ctx(old_run_ctx);
@@ -1394,7 +1396,7 @@ BPF_PROG_RUN_ARRAY(const struct bpf_prog_array __rcu *array_rcu,
13941396
u32 _ret; \
13951397
_ret = BPF_PROG_RUN_ARRAY_CG_FLAGS(array, ctx, func, &_flags); \
13961398
_cn = _flags & BPF_RET_SET_CN; \
1397-
if (_ret) \
1399+
if (!_ret) \
13981400
_ret = (_cn ? NET_XMIT_CN : NET_XMIT_SUCCESS); \
13991401
else \
14001402
_ret = (_cn ? NET_XMIT_DROP : -EPERM); \

kernel/bpf/cgroup.c

Lines changed: 15 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1080,7 +1080,6 @@ int __cgroup_bpf_run_filter_skb(struct sock *sk,
10801080
} else {
10811081
ret = BPF_PROG_RUN_ARRAY_CG(cgrp->bpf.effective[atype], skb,
10821082
__bpf_prog_run_save_cb);
1083-
ret = (ret == 1 ? 0 : -EPERM);
10841083
}
10851084
bpf_restore_data_end(skb, saved_data_end);
10861085
__skb_pull(skb, offset);
@@ -1107,10 +1106,9 @@ int __cgroup_bpf_run_filter_sk(struct sock *sk,
11071106
enum cgroup_bpf_attach_type atype)
11081107
{
11091108
struct cgroup *cgrp = sock_cgroup_ptr(&sk->sk_cgrp_data);
1110-
int ret;
11111109

1112-
ret = BPF_PROG_RUN_ARRAY_CG(cgrp->bpf.effective[atype], sk, bpf_prog_run);
1113-
return ret == 1 ? 0 : -EPERM;
1110+
return BPF_PROG_RUN_ARRAY_CG(cgrp->bpf.effective[atype], sk,
1111+
bpf_prog_run);
11141112
}
11151113
EXPORT_SYMBOL(__cgroup_bpf_run_filter_sk);
11161114

@@ -1142,7 +1140,6 @@ int __cgroup_bpf_run_filter_sock_addr(struct sock *sk,
11421140
};
11431141
struct sockaddr_storage unspec;
11441142
struct cgroup *cgrp;
1145-
int ret;
11461143

11471144
/* Check socket family since not all sockets represent network
11481145
* endpoint (e.g. AF_UNIX).
@@ -1156,10 +1153,8 @@ int __cgroup_bpf_run_filter_sock_addr(struct sock *sk,
11561153
}
11571154

11581155
cgrp = sock_cgroup_ptr(&sk->sk_cgrp_data);
1159-
ret = BPF_PROG_RUN_ARRAY_CG_FLAGS(cgrp->bpf.effective[atype], &ctx,
1160-
bpf_prog_run, flags);
1161-
1162-
return ret == 1 ? 0 : -EPERM;
1156+
return BPF_PROG_RUN_ARRAY_CG_FLAGS(cgrp->bpf.effective[atype], &ctx,
1157+
bpf_prog_run, flags);
11631158
}
11641159
EXPORT_SYMBOL(__cgroup_bpf_run_filter_sock_addr);
11651160

@@ -1184,11 +1179,9 @@ int __cgroup_bpf_run_filter_sock_ops(struct sock *sk,
11841179
enum cgroup_bpf_attach_type atype)
11851180
{
11861181
struct cgroup *cgrp = sock_cgroup_ptr(&sk->sk_cgrp_data);
1187-
int ret;
11881182

1189-
ret = BPF_PROG_RUN_ARRAY_CG(cgrp->bpf.effective[atype], sock_ops,
1190-
bpf_prog_run);
1191-
return ret == 1 ? 0 : -EPERM;
1183+
return BPF_PROG_RUN_ARRAY_CG(cgrp->bpf.effective[atype], sock_ops,
1184+
bpf_prog_run);
11921185
}
11931186
EXPORT_SYMBOL(__cgroup_bpf_run_filter_sock_ops);
11941187

@@ -1201,15 +1194,15 @@ int __cgroup_bpf_check_dev_permission(short dev_type, u32 major, u32 minor,
12011194
.major = major,
12021195
.minor = minor,
12031196
};
1204-
int allow;
1197+
int ret;
12051198

12061199
rcu_read_lock();
12071200
cgrp = task_dfl_cgroup(current);
1208-
allow = BPF_PROG_RUN_ARRAY_CG(cgrp->bpf.effective[atype], &ctx,
1209-
bpf_prog_run);
1201+
ret = BPF_PROG_RUN_ARRAY_CG(cgrp->bpf.effective[atype], &ctx,
1202+
bpf_prog_run);
12101203
rcu_read_unlock();
12111204

1212-
return !allow;
1205+
return ret;
12131206
}
12141207

12151208
static const struct bpf_func_proto *
@@ -1350,7 +1343,7 @@ int __cgroup_bpf_run_filter_sysctl(struct ctl_table_header *head,
13501343
kfree(ctx.new_val);
13511344
}
13521345

1353-
return ret == 1 ? 0 : -EPERM;
1346+
return ret;
13541347
}
13551348

13561349
#ifdef CONFIG_NET
@@ -1455,10 +1448,8 @@ int __cgroup_bpf_run_filter_setsockopt(struct sock *sk, int *level,
14551448
&ctx, bpf_prog_run);
14561449
release_sock(sk);
14571450

1458-
if (!ret) {
1459-
ret = -EPERM;
1451+
if (ret)
14601452
goto out;
1461-
}
14621453

14631454
if (ctx.optlen == -1) {
14641455
/* optlen set to -1, bypass kernel */
@@ -1565,10 +1556,8 @@ int __cgroup_bpf_run_filter_getsockopt(struct sock *sk, int level,
15651556
&ctx, bpf_prog_run);
15661557
release_sock(sk);
15671558

1568-
if (!ret) {
1569-
ret = -EPERM;
1559+
if (ret)
15701560
goto out;
1571-
}
15721561

15731562
if (ctx.optlen > max_optlen || ctx.optlen < 0) {
15741563
ret = -EFAULT;
@@ -1624,8 +1613,8 @@ int __cgroup_bpf_run_filter_getsockopt_kern(struct sock *sk, int level,
16241613

16251614
ret = BPF_PROG_RUN_ARRAY_CG(cgrp->bpf.effective[CGROUP_GETSOCKOPT],
16261615
&ctx, bpf_prog_run);
1627-
if (!ret)
1628-
return -EPERM;
1616+
if (ret)
1617+
return ret;
16291618

16301619
if (ctx.optlen > *optlen)
16311620
return -EFAULT;

security/device_cgroup.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -838,7 +838,7 @@ int devcgroup_check_permission(short type, u32 major, u32 minor, short access)
838838
int rc = BPF_CGROUP_RUN_PROG_DEVICE_CGROUP(type, major, minor, access);
839839

840840
if (rc)
841-
return -EPERM;
841+
return rc;
842842

843843
#ifdef CONFIG_CGROUP_DEVICE
844844
return devcgroup_legacy_check_permission(type, major, minor, access);

0 commit comments

Comments
 (0)