How to Audit a Device for GPL Compliance: A Technical Guide

When you pick up a router, smart TV, or IoT gadget, you’re not just getting hardware. You’re also holding a software stack that almost always includes Linux, BusyBox, and other GPL-licensed pieces. The GNU General Public License gives you the right to ask for—and actually receive—the corresponding source code. Plenty of manufacturers pretend that obligation doesn’t exist. I’ve spent years reverse-engineering embedded systems, and along the way I built a methodical approach to auditing devices for GPL compliance. This guide walks through the whole thing, from early reconnaissance down to deep binary analysis, so you can hold vendors accountable when they cut corners.

Close-up of a circuit board with integrated circuits and components

Understanding the GPL’s Source Code Requirement

The GPL—versions 2 and 3 both—says that anyone distributing a binary form of GPL-covered software has to make the complete corresponding source code available. Not a nice-to-have. The source has to be the exact version used to build those binaries, including any modifications, build scripts, and configuration files. For embedded devices, that usually means the whole toolchain, kernel patches, and the glue code that ties proprietary modules to GPL components. A vendor who tosses a vanilla Linux kernel tarball onto their website isn’t compliant if they applied custom patches. I’ve seen that move more times than I can count.

Compliance failures are everywhere. I’ve run into routers shipping with modified GPL code where the vendor’s “source release” was a dead link, a zip file full of unrelated junk, or a kernel source that conveniently left out the driver modifications that made the hardware actually work. The Software Freedom Conservancy and gpl-violations.org have documented hundreds of these cases. Auditing is the first real step toward enforcement.

Phase 1: Pre-Audit Reconnaissance

Before you touch a single binary, gather intelligence. Start with the device’s documentation, FCC filings, and any open-source disclosures on the manufacturer’s website. Here’s what to look for:

  • Firmware update files: Often available as downloadable binaries. These are gold mines for analysis.
  • GPL source offers: Check the user manual, packaging, or a dedicated open-source page. Note the URL and the date of the offer—timestamps matter later.
  • Third-party teardowns: Sites like iFixit or FCC internal photos reveal chipsets. A MediaTek or Broadcom SoC almost certainly runs Linux.
  • Boot logs: If you can get at a serial console (UART), capture the boot messages. They’ll list the kernel version, loaded modules, and BusyBox applets.

Document everything. I keep a spreadsheet with device model, firmware version, claimed GPL components, and the vendor’s source offer URL. That spreadsheet becomes evidence when the offer turns out to be incomplete.

Person examining a small electronic device with a magnifying glass

Phase 2: Firmware Acquisition and Extraction

If the vendor provides a firmware update file, download it. If not, you may need to dump the firmware straight from the device’s flash memory—that takes hardware tools like a flash programmer or JTAG debugger. For a lot of consumer devices, though, the update file is enough to get started.

Identifying the Firmware Format

Firmware files come wrapped in all sorts of ways: raw binary images, vendor-specific headers, compressed archives. Use the file command and binwalk to figure out the structure:

binwalk -e firmware.bin

Binwalk scans for magic bytes and extracts embedded filesystems—SquashFS, JFFS2, YAFFS, and the like—plus kernels and bootloaders. If the firmware is encrypted or obfuscated, you’ll have to dig deeper. Sometimes the key sits in the bootloader or gets derived from hardware identifiers. I’ve spent whole weekends untangling that kind of mess.

Mounting and Exploring the Root Filesystem

Once you’ve extracted things, mount the root filesystem (often SquashFS) with unsquashfs or a loopback mount. Now you’re staring at the actual runtime environment. Key directories to inspect:

  • /bin, /sbin, /usr/bin: Look for BusyBox, bash, coreutils, or other GPL binaries.
  • /lib/modules: Kernel modules (.ko files). These are often proprietary or modified GPL code.
  • /etc/init.d, /etc/rc.d: Startup scripts that reveal how services get launched.
  • /usr/share/doc: Sometimes contains copyright notices or source references.

Run strings on binaries to find version strings, compiler signatures, and copyright notices. For example, strings busybox | grep -i "busybox v" will confirm the exact BusyBox version.

Phase 3: Binary Analysis for GPL Components

Now the real work begins. You need to identify every GPL-licensed binary and verify that the vendor’s source offer actually matches. This means static analysis, symbol examination, and sometimes dynamic tracing.

Identifying GPL Binaries

Not every binary is GPL-licensed, but a lot of common embedded components are. Here are the techniques I rely on:

  • Copyright strings: Run strings on each ELF binary and grep for “GNU”, “GPL”, “Free Software Foundation”, or specific project names like “Linux”, “BusyBox”, “iptables”, “udhcpd”.
  • Symbol tables: Use nm or objdump -T to list symbols. GPL libraries like libc (glibc or uClibc) leave clear fingerprints.
  • Binary hashes: Compare hashes of binaries against known GPL builds. If a binary matches a standard BusyBox build, the vendor probably didn’t modify it—but they still have to provide the source for that exact version.
  • Kernel version: The kernel image itself is GPLv2. Check /proc/version or the kernel string in the binary. Note the exact version and any vendor-specific suffixes (e.g., “2.6.36.4-brcm63xx”).

Detecting Modifications

Vendors often modify GPL code—adding custom drivers, tweaking BusyBox applets, or patching the kernel. Those modifications have to be disclosed. To detect them:

  • Compare against upstream: Download the pristine source for the claimed version. Build it with the same configuration (if you can get it) and compare binaries using radiff2 or bindiff.
  • Look for extra symbols: Custom functions or non-standard symbol names point to patches.
  • Check kernel modules: Proprietary modules often taint the kernel. Look for “Proprietary” in modinfo output or missing GPL-only symbols.
  • Examine build paths: Strings like /home/jenkins/workspace/custom_build suggest a modified build environment that has to be included in the source release.

Screenshot of terminal with code analysis output

Phase 4: Verifying the Vendor’s Source Offer

If the vendor provides a source code archive, you have to verify it’s complete and actually corresponds to the binaries. This is where most vendors stumble. A proper source release includes:

  • The exact source code for all GPL components, including modifications.
  • Build scripts, Makefiles, and configuration files used to produce the binaries.
  • Toolchain information (compiler version, patches to the compiler if any).
  • Instructions sufficient to rebuild the binaries from source.

Common Compliance Failures

I’ve catalogued these recurring issues over the years:

  • Wrong version: Source is for Linux 2.6.35, but the device runs 2.6.36 with vendor patches.
  • Missing components: BusyBox source is included, but not the custom applets the vendor added.
  • No build scripts: A tarball of raw source without the .config file or Makefile modifications is not enough.
  • Obfuscated source: Delivered as a single giant C file with all whitespace stripped—technically source, but not the “preferred form for modification” as the GPL requires.
  • Dead links: The offer URL returns a 404 or redirects to a generic page.

Rebuilding the Binary

The ultimate test: can you rebuild a functionally equivalent binary from the provided source? Set up a cross-compilation environment matching the device’s architecture (ARM, MIPS, etc.). Use the vendor’s provided toolchain or deduce it from binary strings. Run the build scripts. Compare the resulting binary with the original using sha256sum or a deeper diff. If they don’t match, the source is incomplete. I’ve had builds fail on missing header files that were clearly used in the shipped binary—dead giveaway.

Phase 5: Documentation and Reporting

Your audit is only as good as the evidence you present. Create a detailed report that includes:

  • Device identification: Model, firmware version, hardware revision.
  • List of GPL binaries: With version strings and evidence of licensing.
  • Source offer analysis: What was provided, what’s missing, and why it fails the GPL’s requirements.
  • Rebuild attempt: Steps taken, results, and discrepancies.
  • Supporting files: Extracted binaries, strings output, diff reports.

If you intend to pursue enforcement, share the report with organizations like the Software Freedom Conservancy or gpl-violations.org. They have legal resources and established relationships with vendors. You can also file a complaint with the vendor directly, but be ready for stonewalling. I’ve had vendors claim their binary blobs are “not derived from GPL code” despite clear evidence to the contrary. Persistence and public documentation often force action.

Special Cases: Proprietary Modules and Tivoization

Some devices use GPL software but lock down the hardware to stop modified versions from running—a practice called Tivoization. GPLv3 explicitly prohibits this, but many devices still use GPLv2 components where the loophole exists. During your audit, check for:

  • Signed bootloaders: If the bootloader verifies cryptographic signatures before loading the kernel, you may not be able to run your own build even with complete source.
  • Restricted boot modes: Lack of a serial console or JTAG access can indicate intentional locking.
  • Kernel lockdown: Features like module signature verification or disabled /dev/mem prevent runtime modification.

While Tivoization isn’t a GPL violation per se under GPLv2, it undermines the license’s intent. Document these restrictions—they’re valuable for consumer awareness and may violate other regulations.

Tools of the Trade

Here’s my essential toolkit for GPL auditing:

  • Binwalk: Firmware analysis and extraction.
  • Radare2: Binary diffing and reverse engineering.
  • Buildroot: Cross-compilation environment for embedded Linux.
  • QEMU: Emulating binaries for dynamic analysis.
  • UART-to-USB adapter: For accessing serial consoles.
  • Flash programmer (e.g., CH341A): For dumping firmware directly from SPI flash.
  • Ghidra: Deep binary analysis when source is unavailable.

Most of these are open-source themselves—a fitting approach for defending software freedom.

FAQ: Common Questions About GPL Auditing

What if the vendor claims their GPL code is “unmodified” but provides no source?

Even unmodified GPL code requires source distribution. The GPL’s Section 3 says you must provide the source code or a written offer to provide it. If they don’t, they’re in violation regardless of whether they made changes. Demand the exact source for the version they used.

How can I tell if a binary blob is a modified GPL program?

Look for GPL copyright strings, compare symbols against a known clean build, and check for tainted kernel messages. If the binary links to GPL libraries (like libc), it’s likely a derivative work and must be licensed under the GPL. Proprietary blobs that interface with the kernel must respect GPL’s boundary rules—often violated by vendors who statically link proprietary code with GPL modules.

Is it legal to reverse-engineer firmware for a GPL audit?

Yes, in most jurisdictions. Reverse engineering for interoperability and license compliance is generally protected, especially when the software is GPL-licensed. The GPL itself grants you the right to study and modify the code. However, be mindful of local laws regarding circumvention of technical protection measures—though these rarely apply to GPL compliance checks.

What should I do if the vendor ignores my compliance request?

Escalate. File a detailed report with the Software Freedom Conservancy or gpl-violations.org. They have a track record of successful enforcement, including lawsuits in Germany and the U.S. You can also publicize your findings to pressure the vendor. Consumer backlash and negative press often motivate action when legal threats don’t.

Conclusion: Auditing as a Community Responsibility

GPL compliance isn’t just a legal formality—it’s the foundation of the open-source ecosystem that powers modern technology. When vendors ignore their obligations, they exploit the work of thousands of developers and deny users their rights. By auditing devices and demanding source code, you’re not just a consumer; you’re an active participant in software freedom. The process takes technical skill and patience, but the tools and methods are accessible to anyone with a Linux background. Start with a device you own, apply this framework, and contribute to a culture of accountability.