bpf: switch progs from using 'pin_prefix' to 'pin_location'

Note: I discovered that C considers:
  char s[4] = "abcd";
a valid initialization without a terminating NULL, resulting
in an invalid string.

(Specifically pinned programs had a '\1' as their last char
due to little endian encoding of the next field in the array
of prog def structs)

The simplest workaround appears to be to explicitly add a "\0"

That results in a string/array that ends with 2 NULLs,
and the compiler will at most *strip* the final one.

ie.
  char s[4] = "abcd\0";
fails to compile.

Obviously:
  char s[100] = "abcd\0";
also does the right thing, since it 0-pads with or without the extra null.

Test: TreeHugger
Flag: EXEMPT mainline
Signed-off-by: Maciej Żenczykowski <maze@google.com>
Change-Id: Iaeb8db2cd4750f8521a971382b9f9f9f216195b2
This commit is contained in:
Maciej Żenczykowski 2025-08-04 17:12:35 -07:00
commit 0be5b17e61

View file

@ -1005,7 +1005,7 @@ static int pinProg(const borrowed_fd& fd, const struct bpf_prog_def& progDef,
return 0;
}
static int validateProg(const borrowed_fd& fd, string& progPinLoc,
static int validateProg(const borrowed_fd& fd, const char* const progPinLoc,
const unsigned int bpfloader_ver) {
if (!isAtLeastKernelVersion(4, 14, 0)) {
return 0;
@ -1030,10 +1030,10 @@ static int validateProg(const borrowed_fd& fd, string& progPinLoc,
ALOGE("bpfGetFdXlatProgLen failed, ret: %d", err);
return -err;
}
ALOGI("prog %s id %d len jit:%d xlat:%d", progPinLoc.c_str(), progId, jitLen, xlatLen);
ALOGI("prog %s id %d len jit:%d xlat:%d", progPinLoc, progId, jitLen, xlatLen);
if (!jitLen && bpfloader_ver >= BPFLOADER_MAINLINE_25Q2_VERSION) {
ALOGE("Kernel eBPF JIT failure for %s", progPinLoc.c_str());
ALOGE("Kernel eBPF JIT failure for %s", progPinLoc);
return -ENOTSUP;
}
return 0;
@ -1079,10 +1079,9 @@ static int loadCodeSections(ElfObject& elfObj, vector<codeSection>& cs, const st
name = name.substr(0, name.find_last_of('$'));
bool reuse = false;
string progPinLoc = string(cs[i].prog_def->pin_prefix) + name;
if (access(progPinLoc.c_str(), F_OK) == 0) {
fd.reset(retrieveProgram(progPinLoc.c_str()));
ALOGD("New bpf prog load reusing prog %s, ret: %d (%s)", progPinLoc.c_str(), fd.get(),
if (access(cs[i].prog_def->pin_location, F_OK) == 0) {
fd.reset(retrieveProgram(cs[i].prog_def->pin_location));
ALOGD("New bpf prog load reusing prog %s, ret: %d (%s)", cs[i].prog_def->pin_location, fd.get(),
!fd.ok() ? std::strerror(errno) : "ok");
reuse = true;
} else {
@ -1137,10 +1136,10 @@ static int loadCodeSections(ElfObject& elfObj, vector<codeSection>& cs, const st
if (!fd.ok()) return fd.get();
if (!reuse) {
ret = pinProg(fd, cs[i].prog_def.value(), progPinLoc);
ret = pinProg(fd, cs[i].prog_def.value(), cs[i].prog_def->pin_location);
if (ret) return ret;
}
ret = validateProg(fd, progPinLoc, bpfloader_ver);
ret = validateProg(fd, cs[i].prog_def->pin_location, bpfloader_ver);
if (ret) return ret;
}
@ -1269,17 +1268,16 @@ static int pinProgs(const struct bpf_object * obj,
string name = cs[i].name;
name = name.substr(0, name.find_last_of('$'));
string progPinLoc = string(cs[i].prog_def->pin_prefix) + name;
if (access(progPinLoc.c_str(), F_OK) == 0) {
if (access(cs[i].prog_def->pin_location, F_OK) == 0) {
// TODO: Skip loading lower priority program
ALOGI("Higher priority program is already pinned, skip pinning %s", cs[i].name.c_str());
continue;
}
int fd = bpf_program__fd(prog);
ret = pinProg(fd, cs[i].prog_def.value(), progPinLoc);
ret = pinProg(fd, cs[i].prog_def.value(), cs[i].prog_def->pin_location);
if (ret) return ret;
ret = validateProg(fd, progPinLoc, bpfloader_ver);
ret = validateProg(fd, cs[i].prog_def->pin_location, bpfloader_ver);
if (ret) return ret;
}
return 0;