22
22
DEFINE_STATIC_KEY_ARRAY_FALSE (cgroup_bpf_enabled_key , MAX_CGROUP_BPF_ATTACH_TYPE );
23
23
EXPORT_SYMBOL (cgroup_bpf_enabled_key );
24
24
25
+ /* __always_inline is necessary to prevent indirect call through run_prog
26
+ * function pointer.
27
+ */
28
+ static __always_inline int
29
+ bpf_prog_run_array_cg_flags (const struct cgroup_bpf * cgrp ,
30
+ enum cgroup_bpf_attach_type atype ,
31
+ const void * ctx , bpf_prog_run_fn run_prog ,
32
+ int retval , u32 * ret_flags )
33
+ {
34
+ const struct bpf_prog_array_item * item ;
35
+ const struct bpf_prog * prog ;
36
+ const struct bpf_prog_array * array ;
37
+ struct bpf_run_ctx * old_run_ctx ;
38
+ struct bpf_cg_run_ctx run_ctx ;
39
+ u32 func_ret ;
40
+
41
+ run_ctx .retval = retval ;
42
+ migrate_disable ();
43
+ rcu_read_lock ();
44
+ array = rcu_dereference (cgrp -> effective [atype ]);
45
+ item = & array -> items [0 ];
46
+ old_run_ctx = bpf_set_run_ctx (& run_ctx .run_ctx );
47
+ while ((prog = READ_ONCE (item -> prog ))) {
48
+ run_ctx .prog_item = item ;
49
+ func_ret = run_prog (prog , ctx );
50
+ if (!(func_ret & 1 ) && !IS_ERR_VALUE ((long )run_ctx .retval ))
51
+ run_ctx .retval = - EPERM ;
52
+ * (ret_flags ) |= (func_ret >> 1 );
53
+ item ++ ;
54
+ }
55
+ bpf_reset_run_ctx (old_run_ctx );
56
+ rcu_read_unlock ();
57
+ migrate_enable ();
58
+ return run_ctx .retval ;
59
+ }
60
+
61
+ static __always_inline int
62
+ bpf_prog_run_array_cg (const struct cgroup_bpf * cgrp ,
63
+ enum cgroup_bpf_attach_type atype ,
64
+ const void * ctx , bpf_prog_run_fn run_prog ,
65
+ int retval )
66
+ {
67
+ const struct bpf_prog_array_item * item ;
68
+ const struct bpf_prog * prog ;
69
+ const struct bpf_prog_array * array ;
70
+ struct bpf_run_ctx * old_run_ctx ;
71
+ struct bpf_cg_run_ctx run_ctx ;
72
+
73
+ run_ctx .retval = retval ;
74
+ migrate_disable ();
75
+ rcu_read_lock ();
76
+ array = rcu_dereference (cgrp -> effective [atype ]);
77
+ item = & array -> items [0 ];
78
+ old_run_ctx = bpf_set_run_ctx (& run_ctx .run_ctx );
79
+ while ((prog = READ_ONCE (item -> prog ))) {
80
+ run_ctx .prog_item = item ;
81
+ if (!run_prog (prog , ctx ) && !IS_ERR_VALUE ((long )run_ctx .retval ))
82
+ run_ctx .retval = - EPERM ;
83
+ item ++ ;
84
+ }
85
+ bpf_reset_run_ctx (old_run_ctx );
86
+ rcu_read_unlock ();
87
+ migrate_enable ();
88
+ return run_ctx .retval ;
89
+ }
90
+
25
91
void cgroup_bpf_offline (struct cgroup * cgrp )
26
92
{
27
93
cgroup_get (cgrp );
@@ -1075,11 +1141,38 @@ int __cgroup_bpf_run_filter_skb(struct sock *sk,
1075
1141
bpf_compute_and_save_data_end (skb , & saved_data_end );
1076
1142
1077
1143
if (atype == CGROUP_INET_EGRESS ) {
1078
- ret = BPF_PROG_CGROUP_INET_EGRESS_RUN_ARRAY (
1079
- cgrp -> bpf .effective [atype ], skb , __bpf_prog_run_save_cb );
1144
+ u32 flags = 0 ;
1145
+ bool cn ;
1146
+
1147
+ ret = bpf_prog_run_array_cg_flags (
1148
+ & cgrp -> bpf , atype ,
1149
+ skb , __bpf_prog_run_save_cb , 0 , & flags );
1150
+
1151
+ /* Return values of CGROUP EGRESS BPF programs are:
1152
+ * 0: drop packet
1153
+ * 1: keep packet
1154
+ * 2: drop packet and cn
1155
+ * 3: keep packet and cn
1156
+ *
1157
+ * The returned value is then converted to one of the NET_XMIT
1158
+ * or an error code that is then interpreted as drop packet
1159
+ * (and no cn):
1160
+ * 0: NET_XMIT_SUCCESS skb should be transmitted
1161
+ * 1: NET_XMIT_DROP skb should be dropped and cn
1162
+ * 2: NET_XMIT_CN skb should be transmitted and cn
1163
+ * 3: -err skb should be dropped
1164
+ */
1165
+
1166
+ cn = flags & BPF_RET_SET_CN ;
1167
+ if (ret && !IS_ERR_VALUE ((long )ret ))
1168
+ ret = - EFAULT ;
1169
+ if (!ret )
1170
+ ret = (cn ? NET_XMIT_CN : NET_XMIT_SUCCESS );
1171
+ else
1172
+ ret = (cn ? NET_XMIT_DROP : ret );
1080
1173
} else {
1081
- ret = BPF_PROG_RUN_ARRAY_CG ( cgrp -> bpf . effective [ atype ], skb ,
1082
- __bpf_prog_run_save_cb , 0 );
1174
+ ret = bpf_prog_run_array_cg ( & cgrp -> bpf , atype ,
1175
+ skb , __bpf_prog_run_save_cb , 0 );
1083
1176
if (ret && !IS_ERR_VALUE ((long )ret ))
1084
1177
ret = - EFAULT ;
1085
1178
}
@@ -1109,8 +1202,7 @@ int __cgroup_bpf_run_filter_sk(struct sock *sk,
1109
1202
{
1110
1203
struct cgroup * cgrp = sock_cgroup_ptr (& sk -> sk_cgrp_data );
1111
1204
1112
- return BPF_PROG_RUN_ARRAY_CG (cgrp -> bpf .effective [atype ], sk ,
1113
- bpf_prog_run , 0 );
1205
+ return bpf_prog_run_array_cg (& cgrp -> bpf , atype , sk , bpf_prog_run , 0 );
1114
1206
}
1115
1207
EXPORT_SYMBOL (__cgroup_bpf_run_filter_sk );
1116
1208
@@ -1155,8 +1247,8 @@ int __cgroup_bpf_run_filter_sock_addr(struct sock *sk,
1155
1247
}
1156
1248
1157
1249
cgrp = sock_cgroup_ptr (& sk -> sk_cgrp_data );
1158
- return BPF_PROG_RUN_ARRAY_CG_FLAGS ( cgrp -> bpf . effective [ atype ], & ctx ,
1159
- bpf_prog_run , 0 , flags );
1250
+ return bpf_prog_run_array_cg_flags ( & cgrp -> bpf , atype ,
1251
+ & ctx , bpf_prog_run , 0 , flags );
1160
1252
}
1161
1253
EXPORT_SYMBOL (__cgroup_bpf_run_filter_sock_addr );
1162
1254
@@ -1182,8 +1274,8 @@ int __cgroup_bpf_run_filter_sock_ops(struct sock *sk,
1182
1274
{
1183
1275
struct cgroup * cgrp = sock_cgroup_ptr (& sk -> sk_cgrp_data );
1184
1276
1185
- return BPF_PROG_RUN_ARRAY_CG ( cgrp -> bpf . effective [ atype ] , sock_ops ,
1186
- bpf_prog_run , 0 );
1277
+ return bpf_prog_run_array_cg ( & cgrp -> bpf , atype , sock_ops , bpf_prog_run ,
1278
+ 0 );
1187
1279
}
1188
1280
EXPORT_SYMBOL (__cgroup_bpf_run_filter_sock_ops );
1189
1281
@@ -1200,8 +1292,7 @@ int __cgroup_bpf_check_dev_permission(short dev_type, u32 major, u32 minor,
1200
1292
1201
1293
rcu_read_lock ();
1202
1294
cgrp = task_dfl_cgroup (current );
1203
- ret = BPF_PROG_RUN_ARRAY_CG (cgrp -> bpf .effective [atype ], & ctx ,
1204
- bpf_prog_run , 0 );
1295
+ ret = bpf_prog_run_array_cg (& cgrp -> bpf , atype , & ctx , bpf_prog_run , 0 );
1205
1296
rcu_read_unlock ();
1206
1297
1207
1298
return ret ;
@@ -1366,8 +1457,7 @@ int __cgroup_bpf_run_filter_sysctl(struct ctl_table_header *head,
1366
1457
1367
1458
rcu_read_lock ();
1368
1459
cgrp = task_dfl_cgroup (current );
1369
- ret = BPF_PROG_RUN_ARRAY_CG (cgrp -> bpf .effective [atype ], & ctx ,
1370
- bpf_prog_run , 0 );
1460
+ ret = bpf_prog_run_array_cg (& cgrp -> bpf , atype , & ctx , bpf_prog_run , 0 );
1371
1461
rcu_read_unlock ();
1372
1462
1373
1463
kfree (ctx .cur_val );
@@ -1459,7 +1549,7 @@ int __cgroup_bpf_run_filter_setsockopt(struct sock *sk, int *level,
1459
1549
}
1460
1550
1461
1551
lock_sock (sk );
1462
- ret = BPF_PROG_RUN_ARRAY_CG ( cgrp -> bpf . effective [ CGROUP_SETSOCKOPT ] ,
1552
+ ret = bpf_prog_run_array_cg ( & cgrp -> bpf , CGROUP_SETSOCKOPT ,
1463
1553
& ctx , bpf_prog_run , 0 );
1464
1554
release_sock (sk );
1465
1555
@@ -1559,7 +1649,7 @@ int __cgroup_bpf_run_filter_getsockopt(struct sock *sk, int level,
1559
1649
}
1560
1650
1561
1651
lock_sock (sk );
1562
- ret = BPF_PROG_RUN_ARRAY_CG ( cgrp -> bpf . effective [ CGROUP_GETSOCKOPT ] ,
1652
+ ret = bpf_prog_run_array_cg ( & cgrp -> bpf , CGROUP_GETSOCKOPT ,
1563
1653
& ctx , bpf_prog_run , retval );
1564
1654
release_sock (sk );
1565
1655
@@ -1608,7 +1698,7 @@ int __cgroup_bpf_run_filter_getsockopt_kern(struct sock *sk, int level,
1608
1698
* be called if that data shouldn't be "exported".
1609
1699
*/
1610
1700
1611
- ret = BPF_PROG_RUN_ARRAY_CG ( cgrp -> bpf . effective [ CGROUP_GETSOCKOPT ] ,
1701
+ ret = bpf_prog_run_array_cg ( & cgrp -> bpf , CGROUP_GETSOCKOPT ,
1612
1702
& ctx , bpf_prog_run , retval );
1613
1703
if (ret < 0 )
1614
1704
return ret ;
0 commit comments