Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

selftests/bpf: Handle SYSCALL_EPERM and SYSCALL_ENOTSUPP test cases

In preparation to move test cases from bpf/test_sock_addr.c that expect
system calls to return ENOTSUPP or EPERM, this patch propagates errno
from relevant system calls up to test_sock_addr() where the result can
be checked.

Signed-off-by: Jordan Rife <jrife@google.com>
Link: https://lore.kernel.org/r/20240510190246.3247730-6-jrife@google.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>

authored by

Jordan Rife and committed by
Alexei Starovoitov
a2618c0d 5a047b22

+58 -20
+58 -20
tools/testing/selftests/bpf/prog_tests/sock_addr.c
··· 19 19 #include "getpeername_unix_prog.skel.h" 20 20 #include "network_helpers.h" 21 21 22 + #ifndef ENOTSUPP 23 + # define ENOTSUPP 524 24 + #endif 25 + 22 26 #define TEST_NS "sock_addr" 23 27 #define TEST_IF_PREFIX "test_sock_addr" 24 28 #define TEST_IPV4 "127.0.0.4" ··· 46 42 #define SERVUN_ADDRESS "bpf_cgroup_unix_test" 47 43 #define SERVUN_REWRITE_ADDRESS "bpf_cgroup_unix_test_rewrite" 48 44 #define SRCUN_ADDRESS "bpf_cgroup_unix_test_src" 45 + 46 + #define save_errno_do(op) ({ int __save = errno; op; errno = __save; }) 49 47 50 48 enum sock_addr_test_type { 51 49 SOCK_ADDR_TEST_BIND, ··· 104 98 goto err; 105 99 106 100 err = topts.retval; 101 + errno = -topts.retval; 107 102 goto out; 108 103 err: 109 104 err = -1; ··· 228 221 "kernel_init_sock")) 229 222 goto err; 230 223 231 - if (!ASSERT_OK(kernel_connect((struct sockaddr *)addr, addrlen), 232 - "kernel_connect")) 224 + if (kernel_connect((struct sockaddr *)addr, addrlen) < 0) 233 225 goto err; 234 226 235 227 /* Test code expects a "file descriptor" on success. */ ··· 236 230 goto out; 237 231 err: 238 232 err = -1; 239 - ASSERT_OK(kernel_close_sock(0), "kernel_close_sock"); 233 + save_errno_do(ASSERT_OK(kernel_close_sock(0), "kernel_close_sock")); 240 234 out: 241 235 return err; 242 236 } ··· 254 248 if (make_sockaddr(family, addr_str, port, &addr, &addrlen)) 255 249 goto err; 256 250 257 - if (!ASSERT_OK(kernel_bind(0, (struct sockaddr *)&addr, addrlen), 258 - "kernel_bind")) 251 + if (kernel_bind(0, (struct sockaddr *)&addr, addrlen) < 0) 259 252 goto err; 260 253 261 254 if (type == SOCK_STREAM) { ··· 267 262 goto out; 268 263 err: 269 264 err = -1; 270 - ASSERT_OK(kernel_close_sock(0), "kernel_close_sock"); 265 + save_errno_do(ASSERT_OK(kernel_close_sock(0), "kernel_close_sock")); 271 266 out: 272 267 return err; 273 268 } ··· 1071 1066 sock_addr_kern__destroy(skel); 1072 1067 } 1073 1068 1074 - static void test_bind(struct sock_addr_test *test) 1069 + static int test_bind(struct sock_addr_test *test) 1075 1070 { 1076 1071 struct sockaddr_storage expected_addr; 1077 1072 socklen_t expected_addr_len = sizeof(struct sockaddr_storage); ··· 1080 1075 serv = test->ops->start_server(test->socket_family, test->socket_type, 1081 1076 test->requested_addr, 1082 1077 test->requested_port, 0); 1083 - if (!ASSERT_GE(serv, 0, "start_server")) 1084 - goto cleanup; 1078 + if (serv < 0) { 1079 + err = errno; 1080 + goto err; 1081 + } 1085 1082 1086 1083 err = make_sockaddr(test->socket_family, 1087 1084 test->expected_addr, test->expected_port, ··· 1102 1095 goto cleanup; 1103 1096 1104 1097 cleanup: 1098 + err = 0; 1099 + err: 1105 1100 if (client != -1) 1106 1101 close(client); 1107 1102 if (serv != -1) 1108 1103 test->ops->close(serv); 1104 + 1105 + return err; 1109 1106 } 1110 1107 1111 - static void test_connect(struct sock_addr_test *test) 1108 + static int test_connect(struct sock_addr_test *test) 1112 1109 { 1113 1110 struct sockaddr_storage addr, expected_addr, expected_src_addr; 1114 1111 socklen_t addr_len = sizeof(struct sockaddr_storage), ··· 1132 1121 1133 1122 client = test->ops->connect_to_addr(test->socket_type, &addr, addr_len, 1134 1123 NULL); 1135 - if (!ASSERT_GE(client, 0, "connect_to_addr")) 1136 - goto cleanup; 1124 + if (client < 0) { 1125 + err = errno; 1126 + goto err; 1127 + } 1137 1128 1138 1129 err = make_sockaddr(test->socket_family, test->expected_addr, test->expected_port, 1139 1130 &expected_addr, &expected_addr_len); ··· 1162 1149 goto cleanup; 1163 1150 } 1164 1151 cleanup: 1152 + err = 0; 1153 + err: 1165 1154 if (client != -1) 1166 1155 test->ops->close(client); 1167 1156 if (serv != -1) 1168 1157 close(serv); 1158 + 1159 + return err; 1169 1160 } 1170 1161 1171 - static void test_xmsg(struct sock_addr_test *test) 1162 + static int test_xmsg(struct sock_addr_test *test) 1172 1163 { 1173 1164 struct sockaddr_storage addr, src_addr; 1174 1165 socklen_t addr_len = sizeof(struct sockaddr_storage), ··· 1213 1196 if (test->socket_type == SOCK_DGRAM) { 1214 1197 err = test->ops->sendmsg(client, (struct sockaddr *)&addr, 1215 1198 addr_len, &data, sizeof(data)); 1199 + if (err < 0) { 1200 + err = errno; 1201 + goto err; 1202 + } 1203 + 1216 1204 if (!ASSERT_EQ(err, sizeof(data), "sendmsg")) 1217 1205 goto cleanup; 1218 1206 } else { ··· 1267 1245 } 1268 1246 1269 1247 cleanup: 1248 + err = 0; 1249 + err: 1270 1250 if (client != -1) 1271 1251 test->ops->close(client); 1272 1252 if (serv != -1) 1273 1253 close(serv); 1254 + 1255 + return err; 1274 1256 } 1275 1257 1276 - static void test_getsockname(struct sock_addr_test *test) 1258 + static int test_getsockname(struct sock_addr_test *test) 1277 1259 { 1278 1260 struct sockaddr_storage expected_addr; 1279 1261 socklen_t expected_addr_len = sizeof(struct sockaddr_storage); ··· 1301 1275 cleanup: 1302 1276 if (serv != -1) 1303 1277 test->ops->close(serv); 1278 + 1279 + return 0; 1304 1280 } 1305 1281 1306 - static void test_getpeername(struct sock_addr_test *test) 1282 + static int test_getpeername(struct sock_addr_test *test) 1307 1283 { 1308 1284 struct sockaddr_storage addr, expected_addr; 1309 1285 socklen_t addr_len = sizeof(struct sockaddr_storage), ··· 1342 1314 test->ops->close(client); 1343 1315 if (serv != -1) 1344 1316 close(serv); 1317 + 1318 + return 0; 1345 1319 } 1346 1320 1347 1321 static int setup_test_env(struct nstoken **tok) ··· 1399 1369 1400 1370 for (size_t i = 0; i < ARRAY_SIZE(tests); ++i) { 1401 1371 struct sock_addr_test *test = &tests[i]; 1372 + int err; 1402 1373 1403 1374 if (!test__start_subtest(test->name)) 1404 1375 continue; ··· 1416 1385 * the future. 1417 1386 */ 1418 1387 case SOCK_ADDR_TEST_BIND: 1419 - test_bind(test); 1388 + err = test_bind(test); 1420 1389 break; 1421 1390 case SOCK_ADDR_TEST_CONNECT: 1422 - test_connect(test); 1391 + err = test_connect(test); 1423 1392 break; 1424 1393 case SOCK_ADDR_TEST_SENDMSG: 1425 1394 case SOCK_ADDR_TEST_RECVMSG: 1426 - test_xmsg(test); 1395 + err = test_xmsg(test); 1427 1396 break; 1428 1397 case SOCK_ADDR_TEST_GETSOCKNAME: 1429 - test_getsockname(test); 1398 + err = test_getsockname(test); 1430 1399 break; 1431 1400 case SOCK_ADDR_TEST_GETPEERNAME: 1432 - test_getpeername(test); 1401 + err = test_getpeername(test); 1433 1402 break; 1434 1403 default: 1435 1404 ASSERT_TRUE(false, "Unknown sock addr test type"); 1436 1405 break; 1437 1406 } 1407 + 1408 + if (test->expected_result == SYSCALL_EPERM) 1409 + ASSERT_EQ(err, EPERM, "socket operation returns EPERM"); 1410 + else if (test->expected_result == SYSCALL_ENOTSUPP) 1411 + ASSERT_EQ(err, ENOTSUPP, "socket operation returns ENOTSUPP"); 1412 + else if (test->expected_result == SUCCESS) 1413 + ASSERT_OK(err, "socket operation succeeds"); 1438 1414 1439 1415 test->destroyfn(skel); 1440 1416 }