Understanding the GPL and Why Audits Matter
The GNU General Public License is the legal and philosophical backbone of open source. It guarantees that anyone who gets the software can study it, change it, and pass it on. For embedded gear—routers, smart TVs, IoT sensors, industrial controllers—the GPL draws a hard line: ship a device with GPL code inside, and you must offer the corresponding source. That’s not a polite request. It’s a condition grounded in copyright law. I’ve spent years cracking open firmware images and chasing compliance gaps, and I can tell you that plenty of vendors either don’t understand the rules or quietly hope nobody checks. A proper audit is the only way to know whether a device actually respects the freedoms the license was built to protect.
Auditing a device for GPL compliance is methodical work. It sits at the intersection of reverse engineering, legal analysis, and obsessive documentation. The goal isn’t to ambush a manufacturer—it’s to defend the collaborative principles that make open source possible. When a vendor ships a product with a Linux kernel, BusyBox, or any other GPL component, they take on a concrete responsibility to their users. The audit simply verifies whether they’ve lived up to it. This guide walks through the technical steps, from first reconnaissance to final report, with an emphasis on practical technique and principled rigor.
Pre-Audit Preparation: Gathering Tools and Information
Before you even power on the device, get your toolkit in order. You’ll need a Linux workstation—a virtual machine is fine—loaded with binwalk for firmware dissection, a hex editor, the strings utility, and a disassembler like Ghidra or IDA Pro. If you plan to go after the hardware directly, a logic analyzer and a JTAG or UART adapter will save you hours. But plenty of audits start and finish with software alone. Also, keep a copy of the GPL text handy, both version 2 and version 3, and read the key clauses: Section 3 (source code provision) and Section 6 (non-source forms) in GPLv3, or the equivalent in GPLv2. You’ll be citing them often.
Next, define your scope. Are you auditing a single firmware image, a specific hardware revision, or an entire product line? For a physical device, you’ll need the device itself, its firmware (pulled from the vendor’s site or extracted from flash), and any documentation the vendor ships. Check the vendor’s website for an “Open Source” or “Legal” page. Some companies post source code offers there. If you find nothing, that’s a warning sign, but not yet proof of a violation—the code might be available through a written offer buried in the manual. Record everything: model numbers, firmware hashes, acquisition dates. This creates a solid baseline so your findings can be reproduced and verified.

Step 1: Firmware Acquisition and Initial Triage
Start by getting the firmware. If the vendor offers a downloadable update, grab it—that’s the easy path. Otherwise, you may need to pull the image straight from the device’s flash memory. That means opening the case, locating the flash chip, and using a programmer or a UART bootloader prompt. Take your time here; a slipped probe can brick the device. Once you have the binary, run file and binwalk to figure out what you’re dealing with. Most firmware images are compressed archives—squashfs, cramfs, JFFS2—wrapped in a vendor-specific header. Binwalk can often spot the layers and extract them automatically.
After extraction, map the file system. Hunt for the usual GPL suspects: the Linux kernel (often in /boot or as a compressed image), BusyBox, the GNU C Library, or networking tools like iptables. Use strings on the binaries to pull out copyright notices and version strings. A command like strings vmlinuz | grep -i "linux version" will usually spit out the kernel version. Note every GPL-licensed binary you find, along with its exact version. That list becomes your compliance checklist—each item demands corresponding source from the distributor.

Step 2: Verifying Source Code Availability
With your list of GPL components in hand, check whether the vendor actually provides complete corresponding source. The GPL defines “corresponding source” as all the code, scripts, and interface definitions needed to generate, install, and run the object code. For the Linux kernel, that means the exact version used, plus any out-of-tree patches and the configuration file. For BusyBox, it’s the full source tree with the vendor’s .config. A link to a public repository isn’t enough—the offer must be valid for at least three years and clearly tied to the specific binary you’re auditing.
If the vendor offers a source download, test it. Download the archive and try to build the components. A common trap is missing build scripts or toolchain details. If the device uses a custom cross-compiler, the vendor has to provide that toolchain or give you precise instructions. Try to reproduce the exact binary from the provided source. If the hashes don’t match, something’s off. When no source is offered at all, send a formal request to the vendor’s designated contact—usually found on their website or in the device documentation. Log the request and every response (or silence) as part of your audit trail.
Checking for License Notices and Derivative Works
Source code isn’t the whole story. The GPL also requires that recipients get a copy of the license and the relevant copyright notices. Check the device’s manual, packaging, and any on-screen displays. Many embedded devices flash a short notice during boot or tuck it into an “About” menu. If those are missing, the distribution is already in violation. Then, look for signs of modification. If a vendor has tweaked GPL code—say, added a custom driver to the kernel—they must provide the modified source, not just a pointer to the upstream project. Use diff to compare the vendor’s source against the original release. Any changes need to be clearly documented.
Step 3: Deep Binary Analysis for Hidden GPL Code
Sometimes vendors include GPL code without realizing it, or they hope nobody will notice. Static linking is a classic trap: if a proprietary application links against a GPL library like glibc or libgcc, the whole work becomes subject to the GPL. Use readelf or objdump to inspect dynamic linking. For example, readelf -d /bin/some_app | grep NEEDED lists shared libraries. If you see libc.so.6 and the application is proprietary, that’s a potential violation—unless the vendor uses the LGPL version or has a separate commercial license. For statically linked binaries, fire up Ghidra and search for GPL-licensed code signatures: function names, error strings, or unique byte patterns.
Kernel modules are another trouble spot. Vendors often ship proprietary drivers as loadable kernel modules. The kernel community generally treats modules as derivative works, even though the legal line is fuzzy. Check for tainted kernel flags: if a module loads without a GPL-compatible license, the kernel marks itself as tainted. On a running device, you can check /proc/sys/kernel/tainted—a non-zero value is a red flag. Use modinfo on the module files to read their license tags. A tag like “proprietary” combined with GPL-only symbols is a strong indicator of non-compliance.

Step 4: Analyzing Scripts and Build Systems
GPL compliance reaches into the build system. If the firmware is built with a Makefile that calls GPL-licensed tools, those scripts have to be provided. Extract the root filesystem and look for build artifacts: Makefiles, .config files, toolchain wrappers. They’re often left in /etc or /usr/src. The absence of these files doesn’t automatically prove a violation, but it’s a strong hint that the vendor hasn’t met their obligations. For BusyBox-based systems, the .config file is essential—without it, reproducing the exact binary is nearly impossible.
Think about “scripts” in the broader sense. If the device uses a GPL-licensed bootloader like U-Boot, the vendor must provide the U-Boot source, including any board-specific tweaks. Check the boot partition for U-Boot images and verify the version. The same goes for a GPL-licensed toolchain: if the device was compiled with a specific version of GCC, the source for that exact version must be available. This step often exposes gaps. Vendors might hand over kernel source but forget the toolchain, which makes the source incomplete—and therefore non-compliant.
Step 5: Documenting and Reporting Findings
An audit lives or dies by its documentation. Build a detailed report that lists every GPL component you found, its version, where the source should be, and whether the vendor provided it. For each missing or incomplete source, explain why it fails the GPL, citing the specific clause. Include hashes of binaries and source archives so your work can be traced. If you tried to build from the provided source, document the process and any failures. Screenshots, logs, and command outputs add weight to your claims.
When you report to the vendor, be direct and principled. Lay out the facts without finger-pointing, but don’t soften the legal reality. Many violations come from confusion, not bad intent, and a clear report can push a company toward fixing the problem. If the vendor ignores you, consider escalating to the copyright holders of the GPL code—often the Free Software Foundation or the Software Freedom Conservancy. These groups have enforcement experience and can pursue compliance through legal channels if needed. The point isn’t to punish. It’s to restore the freedoms the GPL guarantees to every user.
FAQ: Common Questions About GPL Audits
What if the device uses a GPL component but the vendor claims it’s a “system library” exception?
The system library exception is narrow. It only covers libraries that are normally distributed with the operating system and aren’t themselves GPL-licensed. For instance, if a device runs Linux and links against glibc (which is LGPL, not GPL), the exception might apply. But if the library is GPL-licensed—like readline—the exception doesn’t hold. Always check the actual license of each component. Vendors often get this wrong, so verify the library’s license and its role in the system yourself.
How do I audit a device that uses encryption or obfuscation to hide its code?
Encryption and obfuscation don’t erase GPL obligations. If the device contains GPL code, the source must be provided no matter how the binary is wrapped. Start by extracting the firmware through hardware means—JTAG, UART, or flash chip removal—if the update files are encrypted. Once you have the binary, look for decryption routines in the bootloader. Tools like binwalk can sometimes flag encrypted sections. If the vendor refuses to hand over decryption keys, that’s a separate violation: the GPL requires that any keys needed to run modified software on the device be disclosed.
How do I handle a device that uses GPL code but the vendor is no longer in business?
If the vendor has shut down, the GPL obligations technically stick with anyone who distributes the device. But enforcement becomes impractical. In those cases, focus on community-driven solutions. If the device still has a user base, publish your audit findings to help others understand what’s inside. That can let independent developers recreate the source or build alternative firmware. The legal path may be closed, but the spirit of the GPL—ensuring user freedom—can still move forward through transparency and collaborative reverse engineering.