From 1a9dd4849310c7901d67d7291192de2466a81258 Mon Sep 17 00:00:00 2001
From: Martin Teichmann <martin.teichmann@xfel.eu>
Date: Wed, 6 Nov 2024 11:13:11 +0100
Subject: [PATCH] automatically mangle names of ebpf programs

---
 ebpfcat/bpf.py  | 4 ++++
 ebpfcat/ebpf.py | 6 ++++--
 2 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/ebpfcat/bpf.py b/ebpfcat/bpf.py
index 14bab08..1ffd84f 100644
--- a/ebpfcat/bpf.py
+++ b/ebpfcat/bpf.py
@@ -18,6 +18,7 @@
 """\
 A module that wraps the `bpf` system call in Python, using `ctypes`.
 """
+import string
 from ctypes import CDLL, c_int, get_errno, cast, c_void_p, create_string_buffer, c_char_p, addressof, c_char
 from enum import Enum, Flag
 from struct import pack, unpack
@@ -127,6 +128,8 @@ def update_elem(fd, key, value, flags):
 def delete_elem(fd, key):
     return bpf(3, "IQ", fd, addrof(key))[0]
 
+allowed_chars = set(string.ascii_letters + string.digits + "-_")
+
 def prog_load(prog_type, insns, license,
               log_level=0, log_size=4096, kern_version=0, flags=0,
               name="", ifindex=0, attach_type=0):
@@ -137,6 +140,7 @@ def prog_load(prog_type, insns, license,
         the_logbuf = create_string_buffer(log_size)
         log_buf = addrof(the_logbuf)
     license = license.encode("utf8")
+    assert len(name) < 16 and set(name) <= allowed_chars, f'wrong name {name}'
     try:
         fd, _ = bpf(5, "IIQQIIQII16sII", prog_type.value, int(len(insns) // 8),
                     addrof(insns), addrof(license), log_level, log_size,
diff --git a/ebpfcat/ebpf.py b/ebpfcat/ebpf.py
index 87ed97f..51a064a 100644
--- a/ebpfcat/ebpf.py
+++ b/ebpfcat/ebpf.py
@@ -1247,7 +1247,7 @@ class EBPF:
         self.kern_version = kern_version
         if name is None:
             if self.name is None:
-                self.name = self.__class__.__name__[:16]
+                self.name = self.__class__.__name__
         else:
             self.name = name
         self.loaded = load_maps is not None
@@ -1319,9 +1319,11 @@ class EBPF:
 
     def load(self, log_level=0, log_size=10 * 4096):
         """load the program into the kernel"""
+        name = ''.join(c if c in bpf.allowed_chars else '_'
+                       for c in self.name[:15])
         fd, log = bpf.prog_load(self.prog_type, self.assemble(), self.license,
                                 log_level, log_size, self.kern_version,
-                                name=self.name)
+                                name=name)
         self.loaded = True
         self.file_descriptor = fd
 
-- 
GitLab