Skip to content

Commit a362bb9

Browse files
committed
Only Use Result From get_helper_prototype when valid
In the case where the result EbpfHelperPrototype's name is null, do not attempt to use it. Also, remove try/catch protection and make sure that existing users of the get_helper_prototype platform abstraction function do not rely on it. Signed-off-by: Will Hawkins <hawkinsw@obs.cr>
1 parent b24faf5 commit a362bb9

File tree

2 files changed

+23
-20
lines changed

2 files changed

+23
-20
lines changed

src/ir/unmarshal.cpp

Lines changed: 22 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -491,17 +491,18 @@ struct Unmarshaller {
491491
[[nodiscard]]
492492
auto makeCall(const int32_t imm) const -> Call {
493493
const EbpfHelperPrototype proto = info.platform->get_helper_prototype(imm);
494+
auto helper_prototype_name = proto.name ? proto.name : std::to_string(imm);
494495
Call res;
495496
res.func = imm;
496-
res.name = proto.name;
497+
res.name = helper_prototype_name;
497498
auto mark_unsupported = [&](const std::string& why) -> Call {
498499
res.is_supported = false;
499500
res.unsupported_reason = why;
500501
return res;
501502
};
502503
const auto return_info = classify_call_return_type(proto.return_type);
503504
if (!return_info.has_value()) {
504-
return mark_unsupported(std::string("helper prototype is unavailable on this platform: ") + proto.name);
505+
return mark_unsupported(std::string("helper prototype is unavailable on this platform: ") + helper_prototype_name);
505506
}
506507
res.return_ptr_type = return_info->pointer_type;
507508
res.return_nullable = return_info->pointer_nullable;
@@ -514,7 +515,7 @@ struct Unmarshaller {
514515
switch (args[i]) {
515516
case EBPF_ARGUMENT_TYPE_UNSUPPORTED:
516517
return mark_unsupported(std::string("helper argument type is unavailable on this platform: ") +
517-
proto.name);
518+
helper_prototype_name);
518519
case EBPF_ARGUMENT_TYPE_DONTCARE: return res;
519520
case EBPF_ARGUMENT_TYPE_ANYTHING:
520521
case EBPF_ARGUMENT_TYPE_PTR_TO_MAP:
@@ -561,18 +562,18 @@ struct Unmarshaller {
561562
break;
562563
case EBPF_ARGUMENT_TYPE_PTR_TO_CONST_STR:
563564
return mark_unsupported(std::string("helper argument type is unavailable on this platform: ") +
564-
proto.name);
565+
helper_prototype_name);
565566
case EBPF_ARGUMENT_TYPE_CONST_SIZE: {
566567
// Sanity check: This argument should never be seen in isolation.
567568
return mark_unsupported(
568569
std::string("mismatched EBPF_ARGUMENT_TYPE_PTR_TO* and EBPF_ARGUMENT_TYPE_CONST_SIZE: ") +
569-
proto.name);
570+
helper_prototype_name);
570571
}
571572
case EBPF_ARGUMENT_TYPE_CONST_SIZE_OR_ZERO: {
572573
// Sanity check: This argument should never be seen in isolation.
573574
return mark_unsupported(
574575
std::string("mismatched EBPF_ARGUMENT_TYPE_PTR_TO* and EBPF_ARGUMENT_TYPE_CONST_SIZE_OR_ZERO: ") +
575-
proto.name);
576+
helper_prototype_name);
576577
}
577578
case EBPF_ARGUMENT_TYPE_PTR_TO_READABLE_MEM_OR_NULL:
578579
case EBPF_ARGUMENT_TYPE_PTR_TO_READABLE_MEM:
@@ -586,14 +587,14 @@ struct Unmarshaller {
586587
return mark_unsupported(
587588
std::string(
588589
"missing EBPF_ARGUMENT_TYPE_CONST_SIZE or EBPF_ARGUMENT_TYPE_CONST_SIZE_OR_ZERO: ") +
589-
proto.name);
590+
helper_prototype_name);
590591
}
591592
if (args[i + 1] != EBPF_ARGUMENT_TYPE_CONST_SIZE &&
592593
args[i + 1] != EBPF_ARGUMENT_TYPE_CONST_SIZE_OR_ZERO) {
593594
return mark_unsupported(
594595
std::string("Pointer argument not followed by EBPF_ARGUMENT_TYPE_CONST_SIZE or "
595596
"EBPF_ARGUMENT_TYPE_CONST_SIZE_OR_ZERO: ") +
596-
proto.name);
597+
helper_prototype_name);
597598
}
598599
const bool can_be_zero = (args[i + 1] == EBPF_ARGUMENT_TYPE_CONST_SIZE_OR_ZERO);
599600
const bool or_null = args[i] == EBPF_ARGUMENT_TYPE_PTR_TO_READABLE_MEM_OR_NULL ||
@@ -700,18 +701,20 @@ struct Unmarshaller {
700701
.is_supported = false,
701702
.unsupported_reason = "helper function is unavailable on this platform"};
702703
}
703-
if (!info.platform->is_helper_usable(inst.imm)) {
704-
std::string name = std::to_string(inst.imm);
705-
try {
706-
name = info.platform->get_helper_prototype(inst.imm).name;
707-
} catch (const std::exception&) {
708-
}
709-
return Call{.func = inst.imm,
710-
.name = std::move(name),
711-
.is_supported = false,
712-
.unsupported_reason = "helper function is unavailable on this platform"};
704+
if (info.platform->is_helper_usable(inst.imm)) {
705+
return makeCall(inst.imm);
706+
} else {
707+
708+
std::string function_name = std::to_string(inst.imm);
709+
auto function_name_from_helper_prototype = info.platform->get_helper_prototype(inst.imm).name;
710+
if (function_name_from_helper_prototype) {
711+
function_name = function_name_from_helper_prototype;
712+
}
713+
return Call{.func = inst.imm,
714+
.name = std::move(function_name),
715+
.is_supported = false,
716+
.unsupported_reason = "helper function is unavailable on this platform"};
713717
}
714-
return makeCall(inst.imm);
715718
case INST_EXIT:
716719
if ((inst.opcode & INST_CLS_MASK) != INST_CLS_JMP || (inst.opcode & INST_SRC_REG)) {
717720
throw InvalidInstruction(pc, inst.opcode);

src/linux/gpl/spec_prototypes.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2662,7 +2662,7 @@ bool is_helper_usable_linux(const int32_t n) {
26622662

26632663
EbpfHelperPrototype get_helper_prototype_linux(const int32_t n) {
26642664
if (!is_helper_usable_linux(n)) {
2665-
throw std::exception();
2665+
return EbpfHelperPrototype{};
26662666
}
26672667
return prototypes[n];
26682668
}

0 commit comments

Comments
 (0)