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: net: cleanup busy_poller.c

Fix various integer type conversions by using strtoull and a temporary
variable which is bounds checked before being casted into the
appropriate cfg_* variable for use by the test program.

While here:
- free the strdup'd cfg string for overall hygenie.
- initialize napi_id = 0 in setup_queue to avoid warnings on some
compilers.

Signed-off-by: Joe Damato <jdamato@fastly.com>
Acked-by: Stanislav Fomichev <sdf@fomichev.me>
Link: https://patch.msgid.link/20241204163239.294123-1-jdamato@fastly.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

authored by

Joe Damato and committed by
Jakub Kicinski
48697bdf 6c36b5c2

+50 -38
+50 -38
tools/testing/selftests/net/busy_poller.c
··· 54 54 #define EPIOCGPARAMS _IOR(EPOLL_IOC_TYPE, 0x02, struct epoll_params) 55 55 #endif 56 56 57 - static uint32_t cfg_port = 8000; 57 + static uint16_t cfg_port = 8000; 58 58 static struct in_addr cfg_bind_addr = { .s_addr = INADDR_ANY }; 59 59 static char *cfg_outfile; 60 60 static int cfg_max_events = 8; 61 - static int cfg_ifindex; 61 + static uint32_t cfg_ifindex; 62 62 63 63 /* busy poll params */ 64 64 static uint32_t cfg_busy_poll_usecs; 65 - static uint32_t cfg_busy_poll_budget; 66 - static uint32_t cfg_prefer_busy_poll; 65 + static uint16_t cfg_busy_poll_budget; 66 + static uint8_t cfg_prefer_busy_poll; 67 67 68 68 /* IRQ params */ 69 69 static uint32_t cfg_defer_hard_irqs; ··· 79 79 80 80 static void parse_opts(int argc, char **argv) 81 81 { 82 + unsigned long long tmp; 82 83 int ret; 83 84 int c; 84 85 ··· 87 86 usage(argv[0]); 88 87 89 88 while ((c = getopt(argc, argv, "p:m:b:u:P:g:o:d:r:s:i:")) != -1) { 89 + /* most options take integer values, except o and b, so reduce 90 + * code duplication a bit for the common case by calling 91 + * strtoull here and leave bounds checking and casting per 92 + * option below. 93 + */ 94 + if (c != 'o' && c != 'b') 95 + tmp = strtoull(optarg, NULL, 0); 96 + 90 97 switch (c) { 91 98 case 'u': 92 - cfg_busy_poll_usecs = strtoul(optarg, NULL, 0); 93 - if (cfg_busy_poll_usecs == ULONG_MAX || 94 - cfg_busy_poll_usecs > UINT32_MAX) 99 + if (tmp == ULLONG_MAX || tmp > UINT32_MAX) 95 100 error(1, ERANGE, "busy_poll_usecs too large"); 101 + 102 + cfg_busy_poll_usecs = (uint32_t)tmp; 96 103 break; 97 104 case 'P': 98 - cfg_prefer_busy_poll = strtoul(optarg, NULL, 0); 99 - if (cfg_prefer_busy_poll == ULONG_MAX || 100 - cfg_prefer_busy_poll > 1) 105 + if (tmp == ULLONG_MAX || tmp > 1) 101 106 error(1, ERANGE, 102 107 "prefer busy poll should be 0 or 1"); 108 + 109 + cfg_prefer_busy_poll = (uint8_t)tmp; 103 110 break; 104 111 case 'g': 105 - cfg_busy_poll_budget = strtoul(optarg, NULL, 0); 106 - if (cfg_busy_poll_budget == ULONG_MAX || 107 - cfg_busy_poll_budget > UINT16_MAX) 112 + if (tmp == ULLONG_MAX || tmp > UINT16_MAX) 108 113 error(1, ERANGE, 109 114 "busy poll budget must be [0, UINT16_MAX]"); 115 + 116 + cfg_busy_poll_budget = (uint16_t)tmp; 110 117 break; 111 118 case 'p': 112 - cfg_port = strtoul(optarg, NULL, 0); 113 - if (cfg_port > UINT16_MAX) 119 + if (tmp == ULLONG_MAX || tmp > UINT16_MAX) 114 120 error(1, ERANGE, "port must be <= 65535"); 121 + 122 + cfg_port = (uint16_t)tmp; 115 123 break; 116 124 case 'b': 117 125 ret = inet_aton(optarg, &cfg_bind_addr); ··· 134 124 error(1, 0, "outfile invalid"); 135 125 break; 136 126 case 'm': 137 - cfg_max_events = strtol(optarg, NULL, 0); 138 - 139 - if (cfg_max_events == LONG_MIN || 140 - cfg_max_events == LONG_MAX || 141 - cfg_max_events <= 0) 127 + if (tmp == ULLONG_MAX || tmp > INT_MAX) 142 128 error(1, ERANGE, 143 - "max events must be > 0 and < LONG_MAX"); 129 + "max events must be > 0 and <= INT_MAX"); 130 + 131 + cfg_max_events = (int)tmp; 144 132 break; 145 133 case 'd': 146 - cfg_defer_hard_irqs = strtoul(optarg, NULL, 0); 147 - 148 - if (cfg_defer_hard_irqs == ULONG_MAX || 149 - cfg_defer_hard_irqs > INT32_MAX) 134 + if (tmp == ULLONG_MAX || tmp > INT32_MAX) 150 135 error(1, ERANGE, 151 136 "defer_hard_irqs must be <= INT32_MAX"); 137 + 138 + cfg_defer_hard_irqs = (uint32_t)tmp; 152 139 break; 153 140 case 'r': 154 - cfg_gro_flush_timeout = strtoull(optarg, NULL, 0); 155 - 156 - if (cfg_gro_flush_timeout == ULLONG_MAX) 141 + if (tmp == ULLONG_MAX || tmp > UINT64_MAX) 157 142 error(1, ERANGE, 158 - "gro_flush_timeout must be < ULLONG_MAX"); 143 + "gro_flush_timeout must be < UINT64_MAX"); 144 + 145 + cfg_gro_flush_timeout = (uint64_t)tmp; 159 146 break; 160 147 case 's': 161 - cfg_irq_suspend_timeout = strtoull(optarg, NULL, 0); 162 - 163 - if (cfg_irq_suspend_timeout == ULLONG_MAX) 148 + if (tmp == ULLONG_MAX || tmp > UINT64_MAX) 164 149 error(1, ERANGE, 165 150 "irq_suspend_timeout must be < ULLONG_MAX"); 151 + 152 + cfg_irq_suspend_timeout = (uint64_t)tmp; 166 153 break; 167 154 case 'i': 168 - cfg_ifindex = strtoul(optarg, NULL, 0); 169 - if (cfg_ifindex == ULONG_MAX) 155 + if (tmp == ULLONG_MAX || tmp > INT_MAX) 170 156 error(1, ERANGE, 171 - "ifindex must be < ULONG_MAX"); 157 + "ifindex must be <= INT_MAX"); 158 + 159 + cfg_ifindex = (int)tmp; 172 160 break; 173 161 } 174 162 } ··· 223 215 struct netdev_napi_set_req *set_req = NULL; 224 216 struct ynl_sock *ys; 225 217 struct ynl_error yerr; 226 - uint32_t napi_id; 218 + uint32_t napi_id = 0; 227 219 228 220 ys = ynl_sock_create(&ynl_netdev_family, &yerr); 229 221 if (!ys) ··· 285 277 * here 286 278 */ 287 279 epoll_params.busy_poll_usecs = cfg_busy_poll_usecs; 288 - epoll_params.busy_poll_budget = (uint16_t)cfg_busy_poll_budget; 289 - epoll_params.prefer_busy_poll = (uint8_t)cfg_prefer_busy_poll; 280 + epoll_params.busy_poll_budget = cfg_busy_poll_budget; 281 + epoll_params.prefer_busy_poll = cfg_prefer_busy_poll; 290 282 epoll_params.__pad = 0; 291 283 292 284 val = 1; ··· 350 342 parse_opts(argc, argv); 351 343 setup_queue(); 352 344 run_poller(); 345 + 346 + if (cfg_outfile) 347 + free(cfg_outfile); 348 + 353 349 return 0; 354 350 }