When you buy a router, a smart home hub, or an industrial controller, you’re not just getting a box of silicon. You’re picking up a whole stack of software that makes the hardware do anything useful. In the embedded Linux space, a big chunk of that software sits under the GNU General Public License. The GPL gives you the freedom to run, study, share, and modify the code—but only if the vendor actually follows through. Most of the time, they don’t. This guide lays out a methodical, no-nonsense audit to figure out whether a device respects the GPL, written from the perspective of an engineer who has spent years peeling back the layers of consumer and industrial firmware.
Why GPL Compliance Audits Matter
The GPL isn’t a polite suggestion; it’s a legally enforceable contract built on one straightforward condition: if you distribute a binary that contains GPL-covered code, you have to provide the corresponding source code. When a manufacturer ignores that, they’re not just breaking a licence—they’re shutting users out from inspecting, repairing, and improving the software that runs on hardware they own. For engineers and security researchers, a compliance audit is the first real step toward clawing back that right. It also drags supply-chain negligence, hidden proprietary blobs, and sometimes outright copyright infringement into the light.
Auditing a device isn’t about springing a “gotcha” on vendors. It’s about checking whether the freedoms the GPL promises are actually delivered. A clean audit builds trust; a failed one signals that the vendor either doesn’t understand their obligations or is actively dodging them. Either way, the community deserves to know.
Pre-Audit Preparation: What You’ll Need
Before you even power on the device, gather your tools and set up a controlled environment. A proper audit is systematic, not ad-hoc. Here’s what I keep on my bench:
- Hardware: The target device, a USB-to-serial adapter (3.3V and 5V tolerant), a logic analyser, a microSD card reader, and a Linux workstation with at least 16 GB of RAM.
- Software: A recent Linux distribution (I use Debian stable),
binwalk,strings,hexdump,dd,unsquashfs,jeffersonfor JFFS2 filesystems, thedevice-tree-compilerpackage, and a cross-compilation toolchain matching the device’s architecture (ARM, MIPS, etc.). - Reference material: The exact GPL version(s) that apply—usually GPLv2 for the Linux kernel, GPLv2 or LGPLv2.1 for libraries—and a copy of the Free Software Foundation’s GPL compliance guide.
- Patience: Firmware analysis is detail work. Rushing leads to missed components and false conclusions.

Step 1: Physical Reconnaissance
Before touching any software, open the device. Remove the enclosure carefully—many consumer devices use snap-fit cases that you can pry apart without damage. Document everything: the main SoC, flash memory chip, RAM, and any conspicuous unpopulated headers. UART pads are your best friend; they often give you a serial console that spills boot logs and kernel messages. Use a multimeter to identify ground, VCC, TX, and RX pins. Connect your USB-to-serial adapter, fire up a terminal emulator like minicom or screen at 115200 baud (common, but try others), and power on the device.
The boot log is a goldmine. It tells you the kernel version, the bootloader (U-Boot, Barebox, or something proprietary), the flash layout, and which filesystems are mounted. Look for lines like Linux version 4.9.84 or U-Boot 2018.03. If the bootloader is locked with a password or the serial console is disabled, you’ll need to move to direct flash extraction. That’s a bigger hurdle, but not insurmountable.
Extracting Firmware Without a Console
If the serial port stays silent, you have a few options. Many devices expose a recovery mode via a button combination or a pin short on the board. Others use an unsecured bootloader that you can interrupt with a keystroke during a narrow window. As a last resort, desolder the flash chip and read it with an external programmer like a CH341A or a Dediprog. This is destructive in the sense that you’ll need to resolder the chip, but it’s often the only way with heavily locked-down hardware. Once you have a raw dump, use binwalk to identify partitions and filesystems.
Step 2: Firmware Acquisition and Unpacking
If the manufacturer provides a firmware update file on their website, start there. It’s usually a compressed archive containing a monolithic binary image. Download it and run binwalk -Me firmware.bin. The -M flag tells binwalk to recursively extract known file types. You’ll often end up with a directory tree containing a SquashFS root filesystem, a JFFS2 overlay, and sometimes a separate kernel image.
For devices that don’t offer public firmware, you’ll need to pull the image directly from the flash chip. Once you have the raw dump, the same binwalk process applies. Pay attention to the partition table—many embedded Linux systems use a fixed layout defined in the kernel command line or device tree. The root filesystem is your primary target; it holds the bulk of the GPL-licensed userspace components.

Step 3: Cataloguing GPL-Covered Components
With the root filesystem mounted or extracted, begin a systematic inventory. The kernel is the most obvious GPLv2 component. Check /lib/modules/ for loadable kernel modules—each one is a derivative work of the kernel and must have source available. Next, scan the filesystem for common GPL-licensed binaries and libraries: BusyBox, GNU C Library (glibc), GNU Coreutils, util-linux, ffmpeg, and any GPL-licensed wireless drivers. Use the strings command on individual binaries to find copyright notices and licence references. For example:
strings /path/to/binary | grep -i "GPL\|General Public License\|Free Software Foundation"
Don’t stop at the obvious. Many embedded devices include GPL-licensed components that are statically linked into proprietary binaries. If a vendor ships a monolithic application that incorporates a GPL library, the entire application must be released under the GPL. Use readelf -d to check dynamic linking, and look for signs of static linking by searching for library function signatures in the binary’s symbol table. Tools like lddtree can map the shared library dependencies, but static linking requires deeper forensic work—disassembly and string cross-referencing.
Special Case: The Linux Kernel
The kernel is the most common GPL violation vector. Vendors often ship a stock kernel with proprietary loadable modules, believing that this circumvents the GPL. It doesn’t. The kernel’s licence explicitly states that modules using kernel symbols are derivative works. If you find .ko files without corresponding source code, that’s a red flag. Check the kernel configuration by looking for /proc/config.gz on a running device or by extracting the config from the kernel image itself (scripts/extract-ikconfig from the kernel source). A vendor that strips the config is often hiding something.
Step 4: Verifying Source Code Availability
The GPL requires that the “complete corresponding source code” be provided. This isn’t just a tarball of the kernel tree—it includes any modifications, build scripts, and toolchain information necessary to reproduce the binary. Start by checking the vendor’s website for a source code offer. Many include a written offer in the device’s documentation or on a settings page. If you find a download, verify its completeness:
- Kernel source: Does it include the exact version used? Are there patches for board-specific changes? Is the
.configfile present? - Userspace source: Are all GPL-licensed binaries accounted for? Check BusyBox, uClibc, wireless tools, and any custom daemons that link against GPL libraries.
- Build scripts: Can you actually compile the source and produce a working image? The GPL requires “scripts used to control compilation and installation.”
If no source is offered, send a formal request to the vendor. The GPL requires them to provide source on physical media for a nominal fee. Document your request and the response (or lack thereof). Silence is a common answer, and it’s a clear violation.
Step 5: Checking for Licence Notices
The GPL also requires that the device’s documentation or user interface include a copy of the licence and a conspicuous notice of where to obtain the source. Check the user manual, the “About” or “Legal” section of the web interface, and any printed materials in the box. If the device has a display, the notice should appear on-screen. For headless devices, it should be in the documentation or accessible via a command-line tool. Missing notices are a technical violation, but they often signal deeper non-compliance—if a vendor can’t be bothered to include the required text, they probably haven’t prepared the source code either.
Step 6: Analysing Proprietary Blobs and Derivative Works
Embedded devices frequently mix GPL code with proprietary binaries. This is allowed, but the boundaries must be clear. A proprietary application that communicates with GPL processes via documented interfaces (pipes, sockets, command-line arguments) is generally considered an “aggregate,” not a derivative work. However, if that application links to a GPL library—even dynamically—it becomes a derivative work and must be released under the GPL. Use ldd on the target’s binaries to map shared library dependencies. If a proprietary binary links to libreadline (GPLv3) or libgpl, the vendor must release the application’s source.
Kernel modules are a special case. The GPLv2 licence on the Linux kernel explicitly states that modules using kernel symbols are derivative works. Some vendors try to evade this by using a shim layer or by claiming their module is “generic,” but courts and the Free Software Foundation have consistently rejected these arguments. If you find a proprietary .ko file, it’s almost certainly a violation.

Step 7: Documenting and Reporting Findings
An audit is only as good as its documentation. Create a detailed report that includes:
- Device identification: Model, hardware revision, firmware version.
- Extraction method: How the firmware was obtained and unpacked.
- Component inventory: A table of all GPL-licensed binaries, libraries, and kernel modules, with version numbers and licence types.
- Source availability: Whether source was offered, where it was found, and a completeness assessment.
- Licence notice check: Where notices were found or missing.
- Violations: Specific, factual descriptions of each non-compliance, with file paths and checksums.
If you find violations, consider reporting them to the copyright holders. The Free Software Foundation and the Software Freedom Conservancy both run compliance programmes and can engage vendors on behalf of the community. Public disclosure is also an option, but weigh the risks—some vendors have retaliated with legal threats. A principled approach means standing behind your findings, but also being precise and fair. False accusations harm the community’s credibility.
Common Pitfalls and How to Avoid Them
Auditing embedded devices is full of traps. Here are a few I’ve learned to watch for:
- Assuming a tarball is complete: Vendors sometimes provide source that compiles but omits key modifications. Compare the built binaries against the shipped ones using checksums.
- Ignoring the bootloader: U-Boot is GPLv2. If the vendor modified it, they must provide source. Dump the bootloader partition and look for custom strings.
- Overlooking firmware blobs: Many devices load proprietary firmware onto Wi-Fi or GPU chips at runtime. While the firmware itself may not be GPL-licensed, the kernel driver that loads it is. The driver’s source must be provided.
- Trusting “GPL source” links: Some vendors link to a generic kernel.org tarball with no patches. That’s not compliance—it’s a lazy attempt to appear compliant.
- Neglecting build scripts: Without the exact build configuration, you can’t reproduce the binary. The GPL requires “the scripts used to control compilation and installation.”
FAQ: GPL Compliance Audits in Practice
What if the vendor claims the GPL doesn’t apply to their device?
This is a common deflection, especially from smaller manufacturers. The GPL applies whenever GPL-licensed code is distributed in binary form. If the device runs Linux, BusyBox, or any other GPL component, the licence applies. The vendor’s opinion doesn’t override copyright law. Point them to the licence text and the FSF’s compliance guide. If they persist, escalate to the copyright holders.
How can I tell if a binary is statically linked to a GPL library?
Static linking leaves telltale signs. Use strings to search for copyright strings from known GPL libraries. Check the binary’s size—statically linked binaries are significantly larger. Disassemble the binary with objdump and look for library function names. If you find GPL library code embedded in a proprietary binary, the whole work must be GPL-licensed.
What should I do if the vendor ignores my source request?
Document the request and the lack of response. After a reasonable period (30 days is standard), you can report the violation to the copyright holders. The FSF and Conservancy have formal processes for this. If you’re a copyright holder yourself, you have standing to enforce the licence directly. For most auditors, the goal is to get the vendor to comply, not to punish them—but persistent ignoring is a sign of bad faith.
Is it enough if the vendor provides source on request but not publicly?
The GPL allows written offers for physical media, so a private request mechanism can be compliant. However, the offer must be valid for three years and clearly stated in the documentation. If the vendor only responds to select customers or imposes unreasonable fees, that’s not compliance. The spirit of the GPL is universal access to the source, not gatekeeping.
Conclusion: Auditing as a Community Service
A GPL compliance audit is more than a technical exercise. It’s a defence of the principles that underpin free software. Every device that ships without source code is a small erosion of user freedom. By auditing methodically and reporting responsibly, you help hold vendors accountable and keep the embedded ecosystem honest. The process requires patience, precision, and a willingness to push back against corporate indifference. But the result—a device that truly respects your rights—is worth the effort.