Understanding the GPL and Why Audits Matter
The GNU General Public License is the legal backbone that keeps the open-source world standing. It guarantees that software stays free—free to study, modify, and share. For embedded devices like routers, smart appliances, and industrial controllers, the GPL draws a hard line: ship a product with GPL code inside, and you must provide the corresponding source. This isn’t a polite request. It’s a copyright-backed obligation. I’ve spent years tearing apart firmware and sitting across the table from manufacturers during compliance negotiations, and I can tell you that most slip-ups come from sloppy internal tracking, not deliberate evasion. Still, the result is the same—users get locked out of the code they should rightfully have. A thorough audit is the only way to confirm a device actually respects the freedoms the GPL was built to protect.
Auditing a device for GPL compliance is a grind that mixes legal homework with low-level technical forensics. It’s not enough to spot a source tarball on a vendor’s site; you have to prove that the source matches the binaries humming away on the hardware. This guide lays out the core steps, from early recon to kernel deep-dives, using tools and techniques any seasoned embedded developer can pick up. The aim is to give you a repeatable framework—whether you’re a compliance officer, a curious tinkerer, or a manufacturer double-checking your own supply chain.

Step 1: Identify the Software Stack
Before you even touch a hex editor, figure out what’s supposed to be running on the thing. Start with the product docs, user manuals, and any open-source disclosures the manufacturer provides. A lot of companies bury a “Legal” or “Open Source” section in the settings menu or on a companion website. If they’ve listed components and offered source code, great—that’s your baseline. If not, you’ve already found your first problem.
Next, poke at the device’s network interfaces. Fire up nmap and scan for open ports and services. A typical embedded Linux box might expose SSH, Telnet, HTTP, or some proprietary protocol. Banner grabbing with netcat or curl can spill version strings—say, an HTTP header revealing Server: lighttpd/1.4.33. That’s a GPL-licensed web server, and now you have a specific version to track. Log everything you find; these breadcrumbs will anchor your later analysis.
If you can get a shell—via serial console, USB, or a network service—run uname -a to grab the kernel version. Check /proc/version too, since it sometimes includes the compiler and build date. Many devices run BusyBox, a GPL-licensed multi-tool; just typing busybox often prints its version. These are the heavy hitters of the embedded world, and they’re almost always copylefted. Missing source for the kernel or BusyBox is a slam-dunk violation.
Step 2: Extract and Analyze the Firmware
Now you get your hands dirty. Grab the firmware image from the manufacturer’s download page, or if they won’t give it up, dump it straight from the device’s flash using JTAG, an SPI programmer, or by sniffing an OTA update. Once you have the binary blob, you need to crack it open. Binwalk is your best friend here—it scans for magic bytes and recursively unpacks filesystems, kernels, and compressed archives. It’s not always perfect, but it’ll get you 90% of the way there.
After extraction, you’ll usually find a root filesystem—SquashFS, JFFS2, or ext4 are common. Mount it or use unsquashfs to browse. Now catalog every executable and library. Run file on each binary to identify the architecture (ARM, MIPS, x86) and whether it’s statically or dynamically linked. Then hit it with strings and grep for copyright notices, version strings, and license references. I’ve caught more than one violation just by spotting a binary that says “GPL” in its strings but has no source offered anywhere.
Pay close attention to shared libraries. The GPL’s copyleft reach can extend to anything that links against a GPL library, depending on how you interpret the license. Use readelf -d or ldd (on a matching architecture) to list shared library dependencies. If a proprietary app links to libreadline (GPLv3) or libcrypto from OpenSSL (which has its own license requirements), you might have a compliance headache. Document every binary, its dependencies, and the license of each component. This spreadsheet becomes your evidence log.

Step 3: Verify Source Code Availability and Completeness
Listing GPL components is only half the job. The GPL demands “complete corresponding source code”—the exact source used to build the binaries, plus any modifications, build scripts, and configuration files. Start by formally requesting the source from the manufacturer, citing the specific GPL version and device model. Keep a paper trail of every email and letter. A slow, incomplete, or nonexistent response is itself a compliance failure.
When you get the source, compare it against your firmware findings. Version numbers must match. For the Linux kernel, the source should include the exact .config file used to build it. You can verify this by extracting the kernel image and checking /proc/config.gz if it’s enabled, or by hunting for embedded configuration symbols in the binary. A mismatch between the provided config and the running kernel is a classic violation—and it’s surprisingly common.
For other components, try a reproducible build. Set up a cross-compilation toolchain that matches the device’s architecture, compile the provided source with the same build flags, and compare the resulting binary to the one on the device. Diffoscope is great for highlighting differences. Even if you can’t get a bit-for-bit match due to timestamps or toolchain quirks, functional equivalence should be obvious. If the provided source won’t compile, or spits out a binary with different features, the vendor isn’t compliant. Period.
Step 4: Check for License Notices and Attribution
GPL compliance isn’t just about source code—it’s also about proper notice. The license requires that users be told about their rights, usually through a copy of the license text and a written offer for source. On the device itself, check the UI, printed manuals, and packaging. Many products have a “Legal Information” screen that lists open-source components and a URL for source downloads. If that’s missing, the distributor is already in breach.
Inside the firmware, look for license files in standard spots like /usr/share/doc or /licenses. Each GPL-licensed package should include its license text. Also check for copyright attribution. The GPL requires that modified versions carry prominent notices stating that changes were made. If a vendor has tweaked a GPL component—say, added custom drivers to the kernel—those modifications must be clearly marked in the source and, ideally, in any accompanying docs.
Don’t ignore scripts and interpreted code. If a device uses GPL-licensed shell scripts or Python code, those are also subject to copyleft. The source must be provided in the preferred form for modification, which for scripts is the script itself. Obfuscated or minified versions don’t cut it. Use grep to scan the firmware for GPL-licensed code snippets that might have been incorporated without proper attribution. I’ve found entire GPL libraries dumped into proprietary binaries with no acknowledgment.

Step 5: Document and Report Findings
An audit is only as good as its paper trail. Build a detailed report that maps each binary to its source package, license, and compliance status. A spreadsheet works, but tools like FOSSology can help track licenses and copyrights at scale. For each violation, note the specific GPL clause that’s been breached, the evidence you gathered, and the steps needed to fix it. This report becomes both a legal record and a roadmap for the vendor to get right.
If you’re auditing on behalf of a copyright holder, the next step is enforcement. That can range from a private notice to the vendor—giving them a chance to correct the issue—to formal legal action. Groups like the Software Freedom Conservancy run established enforcement programs that handle this process. As an auditor, your job is to supply the technical evidence that makes any enforcement action stick.
For manufacturers, a proactive audit is a chance to fix problems before they blow up. Integrate compliance checks into your build pipeline. Use SPDX to document licenses and generate a software bill of materials. Regularly scan your firmware images with license detection tools. The cost of non-compliance—legal fees, injunctions, reputational damage—dwarfs the effort of doing it right from the start. I’ve seen companies learn that the hard way.
Frequently Asked Questions
What is the difference between GPLv2 and GPLv3 compliance?
GPLv3 adds requirements around patent grants, anti-tivoization (preventing hardware restrictions on modified software), and compatibility with other licenses. When auditing, you need to know which version applies to each component. A device using GPLv3 code cannot lock down the hardware to block user-modified software from running—a common trick in consumer electronics. Violations of these extra terms are just as serious as missing source code.
How do I handle proprietary kernel modules?
Proprietary kernel modules sit in a legal gray area. The Linux kernel is GPLv2, and the Free Software Foundation argues that any module loaded into the kernel is a derivative work, so it must be GPL-licensed. Some companies use shim layers or claim modules are separate works. From an audit perspective, flag any non-GPL kernel modules and check if the vendor provides source code. If not, it’s a potential violation that needs legal analysis.
What tools can help automate a GPL compliance audit?
Several open-source tools can speed things up. Binwalk for firmware extraction, FOSSology for license scanning, Buildroot or Yocto for reproducible builds, and diffoscope for binary comparison. For kernel analysis, kconfig-dump can pull the configuration from a running kernel. Always verify automated results by hand—no tool replaces a careful engineering review.