4

I have a question about eBPF and linux kernel licensing. Basically, an eBPF module is a small piece of code that is run inside Linux kernel, and can use kernel methods that are marked as GPL-only (eg. bpf_probe_read), in order to use them one must explicitly acknowledge that code is GPL licensed, eg.:

char _license[] SEC("license") = "GPL";

This means that this eBPF module needs to be under GPL license.

My actual question is does a user-space application that uses (but not redistributes or loads) that module also needs to be under GPL-license? And what if the application would distribute compiled EBPF code and will actually load it into the kernel?

In my understanding the user-space application should be also under GPL-license, however, I have seen open-source projects that use (and redistributes compiled) eBPF modules and are under Apache 2.0 license

3
  • What does an eBPF module do and how does a user-space program interact with it? Can an eBPF module be compared to a device driver for example? Feb 20, 2018 at 18:52
  • Basically, it allows inspecting the execution of the kernel and userspace programs through e.g. kprobes (here is a brief introduction weave.works/blog/…). To interact with the eBPF module user-space program usually uses perf_events. However user-space program usually loads eBPF module into kernel Feb 21, 2018 at 12:34
  • In my option, it can be compared to 'regular' kernel-module, however with limited functionality Feb 21, 2018 at 12:41

4 Answers 4

6

I am not a lawyer, but here are my two cents:

"This means that this eBPF module needs to be under GPL license."

Actually, the code needs to be GPL-compatible. This, from the point of view of the kernel, are the following strings in the module info:

  • GPL: GNU Public License v2 or later.
  • GPL v2: GNU Public License v2.
  • GPL and additional rights: GNU Public License v2 rights and more.
  • Dual BSD/GPL: GNU Public License v2 or BSD license choice.
  • Dual MIT/GPL: GNU Public License v2 or MIT license choice.
  • Dual MPL/GPL: GNU Public License v2 or Mozilla license choice.

"My actual question is does a user-space application that uses (but not redistributes or loads) that module also needs to be under GPL-license?"

This is tricky and I'm still struggling with it. The short answer is "it depends".

This is what the FSF says about aggregated programs:

Where's the line between two separate programs, and one program with two parts? This is a legal question, which ultimately judges will decide. We believe that a proper criterion depends both on the mechanism of communication (exec, pipes, rpc, function calls within a shared address space, etc.) and the semantics of the communication (what kinds of information are interchanged).

If the modules are included in the same executable file, they are definitely combined in one program. If modules are designed to run linked together in a shared address space, that almost surely means combining them into one program.

By contrast, pipes, sockets and command-line arguments are communication mechanisms normally used between two separate programs. So when they are used for communication, the modules normally are separate programs. But if the semantics of the communication are intimate enough, exchanging complex internal data structures, that too could be a basis to consider the two parts as combined into a larger program.

An eBPF program usually is developed as the kernel counterpart of a user-space program. The BCC tools and examples have both sources in the same file.

If you develop an eBPF program that is clearly a sub-component of a user-space application, and the "semantics of the communication" (data types for the perf buffers and maps) are "intimate enough" and clearly tailored for this application only, then probably the user-space program should be licensed under the GPL.

If your eBPF program has a very generic API, it could be used by non-GPL programs... If we assume that the shared memory used for maps and perf buffers doesn't count as a shared-memory application.

"And what if the application would distribute compiled EBPF code and will actually load it into the kernel?"

Nice try, but I don't think so. That would be similar to distributing the assembly code of a GPL program written in C. GPL v2 says:

For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable.

GPL v3 says:

The “Corresponding Source” for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities.

Update:

This answer from the FSF FAQ on GPL pretty much settles the debate, in my opinion.

When is a program and its plug-ins considered a single combined program?

It depends on how the main program invokes its plug-ins. If the main program uses fork and exec to invoke plug-ins, and they establish intimate communication by sharing complex data structures, or shipping complex data structures back and forth, that can make them one single combined program. A main program that uses simple fork and exec to invoke plug-ins and does not establish intimate communication between them results in the plug-ins being a separate program.

If the main program dynamically links plug-ins, and they make function calls to each other and share data structures, we believe they form a single combined program, which must be treated as an extension of both the main program and the plug-ins. If the main program dynamically links plug-ins, but the communication between them is limited to invoking the ‘main’ function of the plug-in with some options and waiting for it to return, that is a borderline case.

Using shared memory to communicate with complex data structures is pretty much equivalent to dynamic linking.

In my totally non-expert opinion, this description of a program/plugin is very similar to a Python/eBPF pair. It consists in two programs that communicate through shared memory using complex data structures. In most of the use cases I have seen the eBPF program is effectively a plugin of the Python program.

Using non-GPL eBPF helpers

I have seen that most of the eBPF helpers don't require GPL-compatibility. I think it is perfectly possible to load a non-GPL eBPF program as long as it doesn't use GPL-only helpers.

Examples of GPL-only helpers: bpf_ktime_get_ns, bpf_probe_read, bpf_trace_printk, bpf_ktime_get_ns...

Examples of non-GPL helpers: bpf_tail_call, bpf_map_update_elem, bpf_get_current_comm, bpf_get_prandom_u32...

So I'd recommend looking for all the eBPF helpers that exist, and see if you can accomplish your task without needing GPL-only helpers. For instance, to read some bytes from a network packet, instead of:

ret = bpf_probe_read(data, ((u8)skb) + off, sizeof(data));

you can use the specialized, non-GPL helper:

ret = bpf_skb_load_bytes(skb, off, data, sizeof(data));
5

The eBPF Guide: eBPF and GPL Licensing specifically addresses this.

Regarding eBPF Programs

The kernel eBPF verifier ensures that in case GPL helpers are referenced in your eBPF program, then your eBPF program can only be successfully verified if also declaring your eBPF program to be under the GPL.

What happens if you try to use GPL-only helper in a eBPF not declared as "GPL"?

In-kernel verifier will spit out the bytecode with an error [...]

Regarding User Space interacting with the eBPF Program

As correctly pointed out here in another answer, does a user space program interacting specifically with your GPL'ed eBPF program will also come under GPL? Again, this is specifically addressed in the above mentioned eBPF guide.

What about the user-space code which links with ebpf kernel code using maps?

This is tricky! GPL license says that if the userspace app is tightly coupled with the kernel space app using for e.g, shared memory or dependent APIs then the userspace app must be made available as GPL code. Since the userspace ebpf components interact with the kernel space component using maps and syscalls, doesn't this require userspace ebpf apps to be GPLed too?

There is a twist here! Kernel license makes an exception that any user-space component which interacts with kernel using system calls need not be called a "derived work". Userspace ebpf code interacts or accesses the kernel space bpf maps using system calls and thus may not be tied with GPL licensing.:

NOTE! This copyright does not cover user programs that use kernel services by normal system calls - this is merely considered normal use of the kernel, and does not fall under the heading of "derived work".

1
  • As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.
    – Community Bot
    Aug 13, 2022 at 11:10
4

Note that Linux kernel makes specific exceptions 1 towards userspace apps using GPL kernel services through syscalls.

NOTE! This copyright does not cover user programs that use kernel services by normal system calls - this is merely considered normal use of the kernel, and does not fall under the heading of "derived work". Also note that the GPL below is copyrighted by the Free Software Foundation, but the instance of code that it refers to (the Linux kernel) is copyrighted by me and others who actually wrote it.

Following this, an ebpf userspace app that accesses the bpf maps using syscalls may not need to adhere to GPL. Hence folks are well-within their rights to use Apache 2.0 license for userspace ebpf app code.

1

the answers posted by others actually make sense

but if you came here after you tried compiling your first bpf program and it failed, then it is highly likely that you faced the same problem that I did.

You might have also installed bcc using apt which happens to be a bcc/jammy 0.16.17-3.3 amd64 16-bit x86 C compiler just uninstall that and reinstall the bpfcc-tools because the newer version of bcc has this resolved as discussed in https://github.com/iovisor/bcc/issues/1804

alternatively you can add this line and recompile

char __license[] SEC("license") = "Dual MIT/GPL";

or

char __license[] SEC("license") = "GPL";

basically any license value of your choice

4
  • "16bit x86"version" doesn't seem correct, and OS/2 never had eBPF.
    – TheDiveO
    Jun 17 at 15:02
  • "basically any license of your choice" conflicts with the original question, so being an arbitrary and thus invalid answer.
    – TheDiveO
    Jun 17 at 15:03
  • @TheDiveO sorry for the confussion I meant this one C bcc/jammy 0.16.17-3.3 amd64 16-bit x86 C compiler there are ways to choose other values for that macro as well in linux/module.h C * "GPL" [GNU Public License v2] * "GPL v2" [GNU Public License v2] * "GPL and additional rights" [GNU Public License v2 rights and more] * "Dual BSD/GPL" [GNU Public License v2 * or BSD license choice] * "Dual MIT/GPL" [GNU Public License v2 * or MIT license choice] * "Dual MPL/GPL" [GNU Public License v2 * or Mozilla license choice]
    – Glitchfix
    Jun 18 at 16:23
  • Can you please edit your answer to clarify this? Thank you!
    – TheDiveO
    Jun 18 at 16:37

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.