Pick up a random router, smart thermostat, or Android-based set-top box, and you’re almost certainly holding a device that runs on Linux and a stack of other GPL-licensed open source components. The GPL gives you the right to study, modify, and share that software. But that right is hollow if the manufacturer never hands over the corresponding source code. I’ve spent years reverse-engineering firmware and having uncomfortable conversations with vendors, and I’ve learned that a rigorous technical audit is the only way to turn a suspicion into a documented case. This isn’t a legal guide; it’s a hands-on, engineer’s approach to verifying whether a device truly respects the GPL.

Why a Technical Audit Is the Only Real Starting Point
Most compliance conversations lean on legal threats or community pressure. Those have their place, but they’re toothless without a factual foundation. If you can’t point to a specific binary and show that it contains GPL code, you’re just guessing. A proper audit turns a hunch into a documented violation. It also helps manufacturers who genuinely lost track of their supply chain—something that happens more often than you’d think. By methodically unpacking the firmware, you can map out exactly which packages are in use, whether the source offer is complete, and whether any obfuscation tricks are hiding proprietary modifications inside GPL components.
Step 1: Get the Firmware and Paper Trail
First, obtain the firmware image. For many consumer devices, the manufacturer posts firmware updates on a support site. If there’s no download, you’ll need to pull the image directly from the device’s flash memory using an SPI programmer or by tapping into a recovery partition. Once you have the binary blob, check the documentation. Does the device ship with a written offer for source code? Is there a URL printed in the manual or buried in the web interface? Save everything. A broken or missing source offer is a violation all by itself, even before you inspect a single line of code.
Unpacking the Root Filesystem
Firmware images usually come wrapped in vendor-specific formats. binwalk is your first tool—it scans for known magic bytes and nested filesystems. A typical workflow:
binwalk -e firmware.bin
cd _firmware.bin.extracted
unsquashfs rootfs.squashfs
If the image uses JFFS2, UBIFS, or YAFFS, you’ll need the matching tools. The aim is to mount or unpack the root filesystem so you can browse its directories exactly as the device sees them at runtime. Don’t ignore the kernel image and any loadable modules. The kernel is almost always under GPLv2, and its exact version string is your first hard data point.

Step 2: Catalog Every GPL Component
With the root filesystem in front of you, start cataloging every executable and library. Lean on file and strings to identify binaries. Look for the usual suspects: the Linux kernel, BusyBox, U-Boot, glibc, iptables, ntpd, and a host of wireless drivers. Check /lib/modules for kernel modules—each one is a derivative work of the kernel and needs source available. Record exact version strings. For BusyBox, run busybox --help inside a chroot or emulated environment. For the kernel, uname -a or cat /proc/version gives you the string. Cross-reference these versions against public repositories. If a module carries proprietary extensions, the vendor still has to release the GPL portions under the same license.
Watching for Copyleft Libraries
Not every open source component is GPL-licensed, but plenty of libraries are LGPL or GPL with linking exceptions. When a proprietary app dynamically links against an LGPL library, the vendor can often comply by offering the library source separately. But static linking, or linking against a full GPL library without an exception, forces the entire application to be released under the GPL. Use readelf -d on binaries to list shared library dependencies. If you spot libgpl.so or something similar, dig into the license. ldd (run inside the target environment) also reveals dynamic links. For statically linked binaries, strings often spills embedded library names and version strings.
Step 3: Verify the Source Code Offer
Now you have a list of GPL components and their versions. Visit the URL the manufacturer provided. Download the source archive. First check: completeness. Does the archive contain source for every GPL component you identified? Missing kernel source, absent BusyBox source, or a tarball that only holds build scripts without the actual upstream code are common red flags. Next, check that the source matches the exact version running on the device. A vendor might toss you a pristine upstream tarball but leave out their own modifications. Diff the provided source against the upstream release. If they patched the kernel, those patches must be included. If they added custom BusyBox applets, those must be present.
Build Reproducibility
The real test is to build the provided source and compare the resulting binaries with what’s on the device. This means matching the toolchain, which the GPL also requires the vendor to disclose if it’s part of the “scripts used to control compilation.” Ask for the exact compiler version, build flags, and any wrapper scripts. Set up a build environment that mirrors theirs. Compile the kernel and key components. Use sha256sum to compare the binaries. Even if timestamps or debug symbols differ, the functional code sections should match. A mismatch suggests the vendor either withheld modifications or gave you source for a different version. Document the discrepancies with hashes and disassembly snippets.

Step 4: Spot Obfuscation and Tivoization
Some manufacturers follow the letter of the GPL but gut its spirit through “Tivoization.” That’s when hardware runs GPL software but uses cryptographic signatures to block any modified version from executing. If you build a modified kernel from the provided source and the device refuses to boot it, the hardware is locked down. Check the bootloader environment. U-Boot often exposes a console; look for signature verification commands. Examine the kernel configuration for CONFIG_MODULE_SIG_FORCE or similar options that enforce module signing. A device that ships with signed boot images and no way to disable signature checking is Tivoized. GPLv2 doesn’t explicitly forbid this, but GPLv3 does. Many Linux components remain under GPLv2, so the legal status varies, but from an engineering ethics standpoint, it’s a clear restriction on user freedom.
Hidden Binaries and Obfuscated Scripts
Look for binaries stripped of symbols and carrying encrypted or compressed payloads. Entropy analysis tools like binwalk -E can highlight high-entropy sections that hint at encryption. If a GPL binary contains an encrypted blob that decrypts at runtime, the decryption key and the source for the decryption routine must be provided. Similarly, shell scripts compiled into binary form with tools like shc obscure the original source. The GPL requires the “preferred form for making modifications,” which for scripts is the human-readable text. A compiled script is not compliant.
Step 5: Document and Report Your Findings
Compile your audit into a clear, factual report. Include the device model, firmware version, list of GPL components, source offer URL, and a detailed account of any missing or incomplete source. Attach hashes, diffs, and build logs. If you found Tivoization or obfuscation, explain the technical mechanism. This report does two things: it gives the manufacturer a precise roadmap to fix the issues, and it provides evidence for enforcement actions if they refuse. Submit the report to the vendor’s open source compliance contact. If none exists, use their general support channel and escalate. Many vendors have a designated compliance officer due to past enforcement actions; search for that contact specifically.
Engaging the Community
If the vendor doesn’t respond or refuses to correct the violations, consider publishing your findings. The Software Freedom Conservancy and the Free Software Foundation both have programs to assist with GPL enforcement. They can provide legal backing, but they need the technical evidence you’ve gathered. A well-documented audit is the foundation of any successful enforcement action. Even without legal escalation, public disclosure often motivates a vendor to comply to avoid reputational damage. Still, always give the vendor a reasonable window to respond before going public.
Common Pitfalls and How to Avoid Them
One frequent mistake is assuming a source offer is complete because it contains a Linux kernel tarball. Always check for other GPL components. A device may use GPL-licensed wireless drivers, audio codecs, or cryptographic libraries that aren’t in the kernel tree. Another pitfall is accepting a source offer that matches a public repository but lacks the vendor’s local modifications. If the binary has features not present in the upstream source, those features represent modifications that must be disclosed. Finally, don’t overlook the toolchain. The GPL requires “scripts used to control compilation,” which includes the compiler configuration, build scripts, and any wrapper tools. Without these, the source may be practically useless for rebuilding.
FAQ
What if the vendor provides source code on a CD but the CD is unreadable?
An unreadable CD is the same as providing no source at all. The GPL requires that the source be on a “medium customarily used for software interchange,” and a damaged or blank CD doesn’t satisfy that. Document the issue, request a replacement, and if the vendor fails to provide one, treat it as a violation.
How do I audit a device that uses encrypted firmware images?
Start by extracting the firmware from the device’s flash memory directly, which often bypasses the encryption layer applied for over-the-air updates. If the firmware is encrypted at rest on the flash, you may need to locate the decryption key in the bootloader or in a secure element. This is technically challenging but sometimes possible through hardware debugging interfaces like JTAG. The presence of encryption does not absolve the vendor of their GPL obligations; they must still provide the complete corresponding source.
Is it a violation if the vendor provides source code but it does not compile?
Yes. The GPL requires that the source code be the “preferred form of the work for making modifications.” If the provided source cannot be compiled into a working binary due to missing files, broken build scripts, or incorrect toolchain information, it fails the standard. The vendor must supply everything necessary to build and install the modified software on the device.
What if the device uses a GPL component but the vendor claims it is proprietary?
This is a direct violation. The GPL does not permit sublicensing or re-licensing of the code. If you can prove the binary contains GPL code—through string analysis, disassembly, or behavioral matching—the vendor’s claim is irrelevant. Document the evidence and report it.