Skip to content
This repository was archived by the owner on Mar 22, 2024. It is now read-only.

Commit 55feb44

Browse files
committed
Search for other free cores when bind fails
Under some circumstances, /proc may transparently lie to us, or we may have cgroups invisibly that prevent us from binding to certain CPUs but not others. In particular this shows up when running inside containers with resource limits applied to them. This patch makes AFL continue to try other CPU cores if the kernel rejects our attempt to bind to an apparently free one, since others may succeed. Signed-off-by: Quentin Young <qlyoung@qlyoung.net>
1 parent db6a240 commit 55feb44

File tree

1 file changed

+48
-15
lines changed

1 file changed

+48
-15
lines changed

afl-fuzz.c

Lines changed: 48 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -488,30 +488,63 @@ static void bind_to_free_cpu(void) {
488488

489489
closedir(d);
490490

491-
for (i = 0; i < cpu_core_count; i++) if (!cpu_used[i]) break;
492491

493-
if (i == cpu_core_count) {
492+
int bound = 0;
493+
int tried_bind = 0;
494+
int saved_errno = 0;
494495

495-
SAYF("\n" cLRD "[-] " cRST
496-
"Uh-oh, looks like all %u CPU cores on your system are allocated to\n"
497-
" other instances of afl-fuzz (or similar CPU-locked tasks). Starting\n"
498-
" another fuzzer on this machine is probably a bad plan, but if you are\n"
499-
" absolutely sure, you can set AFL_NO_AFFINITY and try again.\n",
500-
cpu_core_count);
496+
for (i = 0; i < cpu_core_count; i++) {
497+
498+
if (!cpu_used[i]) {
499+
500+
OKF("Found a free CPU core, attempting bind to #%u.", i);
501+
502+
CPU_ZERO(&c);
503+
CPU_SET(i, &c);
504+
505+
if (sched_setaffinity(0, sizeof(c), &c)) {
501506

502-
FATAL("No more free CPU cores");
507+
saved_errno = errno;
508+
tried_bind++;
509+
WARNF("Binding attempt failed; looking for another core...");
503510

511+
} else {
512+
513+
cpu_aff = i;
514+
bound = 1;
515+
break;
516+
517+
}
518+
}
504519
}
505520

506-
OKF("Found a free CPU core, binding to #%u.", i);
521+
if (!bound) {
507522

508-
cpu_aff = i;
523+
if (tried_bind == 0) {
509524

510-
CPU_ZERO(&c);
511-
CPU_SET(i, &c);
525+
SAYF("\n" cLRD "[-] " cRST
526+
"Uh-oh, looks like all %u CPU cores on your system are allocated to\n"
527+
" other instances of afl-fuzz (or similar CPU-locked tasks). Starting\n"
528+
" another fuzzer on this machine is probably a bad plan, but if you are\n"
529+
" absolutely sure, you can set AFL_NO_AFFINITY and try again.\n\n",
530+
cpu_core_count);
531+
FATAL("No more free CPU cores");
512532

513-
if (sched_setaffinity(0, sizeof(c), &c))
514-
PFATAL("sched_setaffinity failed");
533+
} else {
534+
535+
SAYF("\n" cLRD "[-] " cRST
536+
"Uh-oh, afl-fuzz found %u apparently free CPU cores, but the system\n"
537+
" wouldn't let us bind to any of them. This can happen if we do not\n"
538+
" have CAP_SYS_NICE, or if we are running in a container that is\n"
539+
" restricted to a certain set of CPUs that already have processes bound\n"
540+
" to them. For a quick workaround, set AFL_NO_AFFINITY and try again.\n",
541+
tried_bind);
542+
543+
errno = saved_errno;
544+
PFATAL("sched_setaffinity failed");
545+
546+
}
547+
}
515548

516549
}
517550

0 commit comments

Comments
 (0)