PageSourceSearch

https://ebpf.io/component---src-templates-blog-post-jsx-content-fi…-licensing-index-md-2cea39afdbbbf6b03377.js

js ebpf.io collected 2026-09-24 08:28:13 UTC 18,625 bytes, 2 lines download raw bytes

1"use strict";(self.webpackChunkebpf_gatsby=self.webpackChunkebpf_gatsby||[]).push([[8652],{7447:function(e,t,a){a.r(t),a.d(t,{Head:function(){return v},default:function(){return w}});var n=a(8453),i=a(6540);function l(e){const t=Object.assign({p:"p",em:"em",a:"a",h2:"h2",code:"code",span:"span"},(0,n.RP)(),e.components);return i.createElement(i.Fragment,null,i.createElement(t.p,null,i.createElement(t.em,null,"Disclaimer: We are not lawyers and this is not legal advice. Please contact a lawyer for legal advice.")),"\n",i.createElement(t.p,null,"Authors: Bill Mulligan and Liz Rice"),"\n",i.createElement(t.p,null,"While there is a wide appreciation of the power of eBPF to ",i.createElement(t.a,{href:"https://www.infoq.com/articles/ebpf-cloud-native-platforms/"},"fundamentally change the platforms")," we run our software on, there are some misconceptions in the ecosystem about when eBPF programs need to be licensed under the GPL and how that impacts licensing compliance. Seeing GPL licensed code may give some legal teams pause because eBPF is unfamiliar to them - but it shouldn’t. This blog provides context around why GPL licensed eBPF code exists and lays out why if you are already using Linux in your project, product, or company then using eBPF should not cause any additional concerns. If you are a contributor to a project already using eBPF or looking to add it, or you're unfamiliar with or concerned about eBPF licensing, this blog will walk you through some practical strategies for eBPF licensing and hopefully you’ll learn to stop worrying and love the GPL."),"\n",i.createElement(t.p,null,i.createElement(t.em,null,"Note: this article considers situations where eBPF programs are executed within the Linux kernel, which is the case for the majority of deployed eBPF applications today. It's also possible to run eBPF bytecode in other ways, for example in a ",i.createElement(t.a,{href:"https://eunomia.dev/blogs/userspace-ebpf/"},"userspace eBPF runtime"),", where different licensing models can apply.")),"\n",i.createElement(t.h2,{id:"all-meaningful-linux-kernel-ebpf-programs-are-gpl-licensed"},"All Meaningful Linux Kernel eBPF Programs Are GPL Licensed"),"\n",i.createElement(t.p,null,"Most eBPF-based projects consist of user space code, plus eBPF programs that run in the kernel. Much like kernel modules, eBPF programs have the ability to significantly extend or change kernel behaviors. eBPF programs are dynamically linked with the kernel when they’re loaded into it using the ",i.createElement(t.code,null,"bpf()")," system call."),"\n",i.createElement(t.span,{dangerouslySetInnerHTML:{__html:'<span\n      class="gatsby-resp-image-wrapper"\n      style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 960px; "\n    >\n      <a\n    class="gatsby-resp-image-link"\n    href="/static/b7178444ca34c0ad9fc83820e41db723/5110a/ebpf-overview.png"\n    style="display: block"\n    target="_blank"\n    rel="noopener"\n  >\n    <span\n    class="gatsby-resp-image-background-image"\n    style="padding-bottom: 67.08333333333334%; position: relative; bottom: 0; left: 0; background-image: url(\'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAANCAYAAACpUE5eAAAACXBIWXMAABYlAAAWJQFJUiTwAAACm0lEQVR42oVTXUhTYRg+ExQRGQnaVV3omI4WbdbU6TK9iEpQira5s0kXhj9pWVlad3nTbIusoaQXFV1ETvNnJwVFaptOaGGBVlcRBAVReBGxnZ059/P0nc+0gRMPPHzvd857nvf93uf5GEFYwyZ4XoD4eL0LqK2tg8lkgsFggE6ng1ZbjvLyClRU6FJiaek9EgmASSYMBkOUcGLCBalUCplMhvz8fGRmZoJhmG2QSCRbsdvtof+mJHQ6R6FQKOD3++Hz+TAzM4Pl5WUsLi4iJycHaWlpyMjIoEhPT6fweOa3E/L8P8LhERQUFGB6egrjY2NwOB6A4zhSyImsrKyt7nbsMBQKU4gdxuLAG/8SjPUmGI0mmC0NaGlphd5gpO9Ys2UL5qR45cMnRGMJMIGggM/ffuLrj1V8+f4Lq7+DCArr4IUoQmsxRGLAWjSBKCm0TmJxvx7/j0h043uAj+BPMAwmJM6OqMvzYQQCG0demPeR6mbo9XoolUqo1WrI5XK6qlQqFBUWQlGkIChCaYkGRysr8S5Z5XA4QrE5Q5frJZ3LYU0JOjq7cOVaN7pu3ER1dRWOn6ih+9b2DrR3dmO/TE5zU4qyqTLHTdEkdfER2O/3o88xgIHBIeJJPcznGtHXPwir7R5sjkEoizU0V/TuroS6Y1UYmZjCk+ejmH3txeWr19HY3IZnI+N4+OgpXkxyKC3T7k7o4jaOvDc3DwcOHkKVSgNdSRnqTp8Ba7Ggiah+vqkZbRcv4eSpGupDt9u7M6F4U0TCPAkxMFkv7NkHrTQX/Y+HyHwniU+HqT9FX4r+zM7Oxtzcq1TGFqhSfv9bnCUKG+vrYSDeazCxYAlu9fTAbr8Lm80Oq7UXvb13cNtqBcuyWFn5iHgc+AuYOsS8vNp6igAAAABJRU5ErkJggg==\'); background-size: cover; display: block;"\n  ></span>\n  <picture>\n          <source\n              srcset="/static/b7178444ca34c0ad9fc83820e41db723/4258e/ebpf-overview.webp 240w,\n/static/b7178444ca34c0ad9fc83820e41db723/5bde3/ebpf-overview.webp 480w,\n/static/b7178444ca34c0ad9fc83820e41db723/691bc/ebpf-overview.webp 960w,\n/static/b7178444ca34c0ad9fc83820e41db723/e17a9/ebpf-overview.webp 1240w"\n              sizes="(max-width: 960px) 100v
1w, 960px"\n              type="image/webp"\n            />\n          <source\n            srcset="/static/b7178444ca34c0ad9fc83820e41db723/0da93/ebpf-overview.png 240w,\n/static/b7178444ca34c0ad9fc83820e41db723/532ad/ebpf-overview.png 480w,\n/static/b7178444ca34c0ad9fc83820e41db723/b14d5/ebpf-overview.png 960w,\n/static/b7178444ca34c0ad9fc83820e41db723/5110a/ebpf-overview.png 1240w"\n            sizes="(max-width: 960px) 100vw, 960px"\n            type="image/png"\n          />\n          <img\n            class="gatsby-resp-image-image"\n            src="/static/b7178444ca34c0ad9fc83820e41db723/b14d5/ebpf-overview.png"\n            alt="eBPF program overview diagram"\n            title=""\n            loading="lazy"\n            decoding="async"\n            style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;"\n          />\n        </picture>\n  </a>\n    </span>'}}),"\n",i.createElement(t.p,null,"When an eBPF program is loaded into the Linux kernel, the kernel checks which functions it intends to use. If any function is marked as “GPL only,” the eBPF program has to have a GPL-compatible license from the ",i.createElement(t.a,{href:"https://github.com/torvalds/linux/blob/master/Documentation/process/license-rules.rst"},"licensing scheme documented here"),". The kernel rejects the eBPF program if it does not have a compatible license. The code for establishing this compatibility (",i.createElement(t.code,null,"license_is_gpl_compatible()"),") is defined ",i.createElement(t.a,{href:"https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/linux/license.h"},"this page"),"."),"\n",i.createElement(t.p,null,"Not all eBPF helper functions are marked as “GPL only”, so it is theoretically possible for some eBPF programs not to need GPL-compatible licensing. However, Alexei Staravoitov, co-maintainer of eBPF in the kernel, has ",i.createElement(t.a,{href:"https://lwn.net/ml/linux-kernel/[email protected]
1p.thefacebook.com/"},"stated"),' that "all meaningful eBPF programs are GPL" because key helper functions are GPL-ed. Furthermore, some eBPF program types are required to be GPL compatible even if they don’t use “GPL only” helper functions directly, because they implicitly call EXPORT_SYMBOL_GPL kernel functions and any new eBPF programs backed by ',i.createElement(t.a,{href:"https://docs.kernel.org/bpf/kfuncs.html#introduction"},"kfuncs")," will also need to be GPL licensed. Therefore, it is highly impractical to avoid licensing eBPF bytecode as GPL."),"\n",i.createElement(t.h2,{id:"applying-a-license-to-your-ebpf-program"},"Applying a License to Your eBPF Program"),"\n",i.createElement(t.p,null,"Most projects use a dual license of GPLv2 and a permissive Open Source license such as MIT, BSD-2-Clause, or Apache-2.0. eBPF programs use a line of code such as ",i.createElement(t.code,null,'char _license[] SEC("license") = "Dual BSD/GPL"')," to convey the license string to the kernel. However, this license string is not a substitute for the SPDX identifier in the source file which you need to provide for license auditing purposes."),"\n",i.createElement(t.h2,{id:"why-userspace-executables-dont-need-to-be-gpl-compatible"},"Why Userspace Executables Don’t Need To Be GPL Compatible"),"\n",i.createElement(t.p,null,"If an eBPF program needs to be GPL licensed, what does that mean for your userspace executables? Can a non-GPL'd user space executable bundle/load/interact with GPL licensed eBPF bytecode running inside the kernel? Yes! The intent is for this to be normal, reasonable practice. All of the userspace interactions fall under a Linux kernel syscall API exception. All applications running in user space interact with the kernel using the syscall interface, and the same is true for user space applications that interact with eBPF programs in the kernel."),"\n",i.createElement(t.p,null,"With the GPL ",i.createElement(t.a,{href:"https://copyleft.org/guide/comprehensive-gpl-guide.html"},"derived works"),", external code that is either ",i.createElement(t.a,{href:"https://www.gnu.org/licenses/old-licenses/gpl-2.0-faq.html#LinkingWithGPL"},"linked")," statically at build time or dynamically at runtime, and modular programs (single applications that may execute separately but depend on detailed communication of internal data structures or shared memory), must be distributed in a GPL compatible manner. However, userspace executables that load or interact with eBPF programs are none of the above."),"\n",i.createElement(t.p,null,"The Linux kernel developers have made a very deliberate effort to provide documented intent around the issue of what compromises a derived work of the Linux kernel and what does not. They have designated the set of system calls as the syscall API that can be called from other programs without those programs being considered a derived work of the kernel."),"\n",i.createElement(t.p,null,"A userspace executable and the related eBPF bytecode is generally considered an aggregate of the two pieces of software. They are two separate works that interact via the Linux syscall API to get useful work done and can be packaged together without being considered modular parts of a single application derived from the Linux kernel. Aggregates are a number of separate programs, distributed together that communicate with each other as if they were independent executables on the system (using standard OS provided mechanisms such as pipes or file descriptors). The GPLv2 ",i.createElement(t.a,{href:"https://www.gnu.org/licenses/old-licenses/gpl-2.0-faq.en.html#TOCMereAggregation"},"FAQ")," lays out that the creation and that distribution of an aggregate, of GPL and non-GPL compatible code, should be permitted."),"\n",i.createElement(t.span,{dangerouslySetInnerHTML:{__html:'<span\n      class="gatsby-resp-image-wrapper"\n      style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 960px; "\n    >\n      <a\n    class="gatsby-resp-image-link"\n    href="/static/49be7d31abbda1dbeba64bbe5f65d276/7e3a7/modular-vs-aggregate.png"\n    style="display: block"\n    target="_blank"\n    rel="noopener"\n  >\n    <span\n    class="gatsby-resp-image-background-image"\n    style="padding-bottom: 40.416666666666664%; position: relative; bottom: 0; left: 0; background-image: url(\'data:image/png;
1base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAICAYAAAD5nd/tAAAACXBIWXMAABYlAAAWJQFJUiTwAAACIklEQVR42lWSz0sUYRjH91+ofyAQrYSiQpSgS9CtY1cPQVGYlVDmD6zUEOpQSaGU0SHTsEuBYXoKggLJJNB03d3Z+bU67rrOzO6sOzM7M6t+etVT8H7f9/A87+f5PvCN+V6A7we4ro+cVpBlFVlRWVs1UBUdTVvFMHKipiKl0kiSLOoaxYJDEFTF3/A/xfxwmyDaJQh3UPV1UmmdhKRibFioAiZJCpmMwYqk8TeeYnE5Keoa9paHK8w4Tlm84b68PWAxPos8fI3Uq1bMsTuUJ9opj93GmXpGGERE0TbRDpR/fcYZvUnpYyelsTaKk09Yz2SE+yyh50EUiCOA5pfnLF0+xEJrLdn2Wqzu42x21GE+bKCYW8evVHGF9BfNzDYf5k9LDda9Guy+BlLzP9FUjWnFZ3AxYiHnE7NmhrA7a3EeNWH2NTLwfpKrn1aYfXmLIKvgh7u4fpX82+tkO46R723EfnCawuPzJAVQl2VuzBjUTZQYj3sCODWIdfcIxd4zbIjmS+/mODm9w9fXPVTXkniRWFdc5psrOF1HKQpnhZ4TFAbOkfr9g1VdZ+CbzoVxhalEQaz8fZx8Vz1Wf9P+9KGREbpHp5kbbqNibRysHEL+Qydmdz1m/1nM+6fYfHoRLbFERqTBLvlYWxFlNyBW3nKx1CSWsiIUx0kv4CTnKWUzArbNXqwqAlqybUw5LnoSmOllnJyBaTlkc3k8r0JYOYjNPyk9Fxoy9GjmAAAAAElFTkSuQmCC\'); background-size: cover; display: block;"\n  ></span>\n  <picture>\n          <source\n              srcset="/static/49be7d31abbda1dbeba64bbe5f65d276/4258e/modular-vs-aggregate.webp 240w,\n/static/49be7d31abbda1dbeba64bbe5f65d276/5bde3/modular-vs-aggregate.webp 480w,\n/static/49be7d31abbda1dbeba64bbe5f65d276/691bc/modular-vs-aggregate.webp 960w,\n/static/49be7d31abbda1dbeba64bbe5f65d276/f093e/modular-vs-aggregate.webp 1440w,\n/static/49be7d31abbda1dbeba64bbe5f65d276/c58b7/modular-vs-aggregate.webp 1920w,\n/static/49be7d31abbda1dbeba64bbe5f65d276/5c7ab/modular-vs-aggregate.webp 2024w"\n              sizes="(max-width: 960px) 100vw, 960px"\n              type="image/webp"\n            />\n          <source\n            srcset="/static/49be7d31abbda1dbeba64bbe5f65d276/0da93/modular-vs-aggregate.png 240w,\n/static/49be7d31abbda1dbeba64bbe5f65d276/532ad/modular-vs-aggregate.png 480w,\n/static/49be7d31abbda1dbeba64bbe5f65d276/b14d5/modular-vs-aggregate.png 960w,\n/static/49be7d31abbda1dbeba64bbe5f65d276/7b572/modular-vs-aggregate.png 1440w,\n/static/49be7d31abbda1dbeba64bbe5f65d276/2b73a/modular-vs-aggregate.png 1920w,\n/static/49be7d31abbda1dbeba64bbe5f65d276/7e3a7/modular-vs-aggregate.png 2024w"\n            sizes="(max-width: 960px) 100vw, 960px"\n            type="image/png"\n          />\n          <img\n            class="gatsby-resp-image-image"\n            src="/static/49be7d31abbda1dbeba64bbe5f65d276/b14d5/modular-vs-aggregate.png"\n            alt="modular vs aggregate code"\n            title=""\n            loading="lazy"\n            decoding="async"\n            style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;"\n          />\n        </picture>\n  </a>\n    </span>'}}),"\n",i.createElement(t.p,null,"eBPF programs have no ability to link either statically or dynamically with user space code. User space applications interact with the in-kernel eBPF program exclusively through the syscall interface, in the same way they interact with any other aspect of the kernel, and thus are not derivative works. This is expressly described in the ",i.createElement(t.a,{href:"https://github.com/torvalds/linux/blob/master/LICENSES/exceptions/Linux-syscall-note"},"Linux syscall note")," and further clarified in the eBPF licensing ",i.createElement(t.a,{href:"https://docs.kernel.org/bpf/bpf_licensing.html"},"section")," “Generally, proprietary-licensed applications and GPL licensed BPF programs written for the Linux kernel in the same package can co-exist because they are separate executable processes.”"),"\n",i.createElement(t.h2,{id:"ebpf--gpl-compatible-userspace--as-you-wish"},"eBPF = GPL Compatible, Userspace = As You Wish"),"\n",i.createElement(t.p,null,"While eBPF licensing may seem complex, understanding GPL compatibility and the distinction between kernel space and user space components clarifies compliance strategies. The delineation between eBPF bytecode in the kernel and userspace executables helps mitigate concerns about GPL compatibility, affirming the flexibility of picking a license for userspace applications. Ultimately, with more clarity on licensing and a shared understanding of best practices, the eBPF ecosystem can continue to evolve and drive the ",i.createElement(t.a,{href:"https://www.infoq.com/articles/ebpf-cloud-native-platforms/"},"silent platform revolution"),"."),"\n",i.createElement(t.p,null,"If you want to learn more about this topic, please also check the KubeCon + CloudNativeCon ",i.createElement(t.a,{href:"https://www.youtube.com/watch?v=cxyDEdzNdH8"},"talk")," and for other runtimes check out the ",i.createElement(t.a,{href:"https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/bpf/bpf_licensing.rst"},"kernel documentation"),"."))}
1var r=function(e){void 0===e&&(e={});const{wrapper:t}=Object.assign({},(0,n.RP)(),e.components);return t?i.createElement(t,e,i.createElement(l,e)):l(e)},s=a(4164),o=a(5588),c=a(6350),d=a(8433),m=a(8353),p=a(6676),b=a(3798),g=a(1964),u=a(5382),h=a(2172),f=a.n(h);const y=e=>{var t,a,n,l,r,o;let{data:{mdx:{frontmatter:{title:g,description:h,date:y,toc:w,path:v},fields:{author:A},tableOfContents:k}},children:E}=e;const P="https://ebpf.io"+v,x=w&&(null==k?void 0:k.items.length)>0;return i.createElement(b.A,null,i.createElement("article",{className:"safe-paddings mb-36 mt-16 xl:mb-32 lg:mb-28 md:mb-20 md:mt-14"},i.createElement("div",{className:"container grid-gap-x grid grid-cols-12"},i.createElement("div",{className:"col-span-8 md:col-span-full"},i.createElement("h1",{className:"heading-8xl font-semibold leading-tight"},g),i.createElement("div",{className:"mt-6 inline-flex items-center text-sm leading-none"},A&&i.createElement("span",{className:"inline-flex items-center pr-3"},(null===(t=f()[A])||void 0===t?void 0:t.photo)&&i.createElement("img",{className:"mr-3 rounded-full",src:null===(a=f()[A])||void 0===a?void 0:a.photo,alt:null===(n=f()[A])||void 0===n?void 0:n.name,width:36,height:36,loading:"eager"}),i.createElement("span",{className:"font-medium"},(null===(l=f()[A])||void 0===l?void 0:l.name)||A)),i.createElement("time",{className:(0,s.A)({"border-l border-gray-90 pl-3":(null===(r=f()[A])||void 0===r?void 0:r.name)||A})},y)))),i.createElement("div",{className:"container grid-gap-x grid grid-cols-12 md:grid-cols-1"},x&&i.createElement(m.A,{className:"hidden md:col-span-full md:mt-6 md:block",items:k.items}),i.createElement(p.A,{className:"prose-blog col-span-8 mt-8 md:col-span-full md:mt-4",content:E}),i.createElement("aside",{className:"col-start-10 col-end-13 mt-8 md:col-span-full md:hidden"},i.createElement("div",{className:"sticky bottom-10 top-10 max-h-[calc(100vh-80px)] overflow-y-auto overflow-x-hidden "},x&&i.createElement(m.A,{items:k.items}),i.createElement(d.A,{className:(0,s.A)({"mt-9":x}),url:P,excerpt:h,title:g}))),i.createElement(d.A,{className:"hidden border-dashed border-gray-80 md:mt-4 md:flex md:items-center md:space-x-4 md:border-t md:pt-8 sm:flex-col sm:space-x-0 sm:space-y-3",url:P,excerpt:h,title:g}),A&&(null===(o=f()[A])||void 0===o?void 0:o.bio)&&i.createElement(c.A,{className:"col-span-8 md:col-span-full",author:A}),i.createElement(u.A,{className:"col-span-full mt-28 lg:mt-24 md:mt-20 sm:mt-16",size:"md"}))))};function w(e){return i.createElement(y,e,i.createElement(r,e))}const v=e=>{let{data:{mdx:{frontmatter:{title:t,path:a,description:n,ogImage:l}}}}=e;const r=(0,o.d)(null==l?void 0:l.childImageSharp);return i.createElement(g.A,{title:t,pathname:a,description:n,image:r})}}}]);
2//# sourceMappingURL=component---src-templates-blog-post-jsx-content-file-path-content-blog-posts-2024-06-13-ebpf-licensing-index-md-2cea39afdbbbf6b03377.js.map

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.