When you buy a router, a smart thermostat, or an Android TV box, youâre not just getting a piece of hardware. Youâre getting a software stackâoften a messy, cobbled-together pile of codeâand a big chunk of it is open source. The GPL governs a lot of that code, from the Linux kernel to essential userspace libraries. If youâre a developer or just a technically minded user, checking whether a device actually respects those licenses isnât just a legal box-ticking exercise. Itâs about protecting software freedom and basic engineering honesty. This guide lays out a practical, hands-on method for auditing a device, based on real reverse-engineering work.

What the GPL Actually Demands
Before you crack open a case or fire up a terminal, you need to know what youâre looking for. The GPLâs central requirement is straightforward: if you distribute binaries built from GPL code, you must make the corresponding source code available. For embedded devices, âcorresponding sourceâ means the complete, buildable code for the kernel, any modified GPL libraries, and all the scripts and toolchain bits needed to recompile it and get it running on the hardware. A bare firmware binary dump is a warning sign. A source tarball that compiles but produces a kernel that panics on the target device is also a failure. Compliance means the recipient can genuinely modify the code and run the modified version on the same hardware.
Plenty of manufacturers slap a âsource codeâ link on a support page. Your first move is to download that archive and poke around. Is it just a vanilla kernel tree with no board-specific patches? Are the drivers for the Wi-Fi chip or power management IC missing, with only pre-compiled kernel modules (.ko files) shipped instead? A proper release contains the exact source used to build the firmware image on your device, not a generic upstream snapshot.
Getting the Firmware Off the Device
To compare what the vendor promised with whatâs actually running, you need to extract the firmware. The easiest route is often through a firmware update file published on the manufacturerâs website. These are typically compressed archives that contain a filesystem imageâSquashFS, JFFS2, or UBIFS are common. Use binwalk to scan the binary blob for magic bytes and pull out the filesystem.
binwalk -e firmware_update.bin
If the vendor doesnât offer downloadable firmware, youâll have to go after the flash memory on the device itself. That means physical access. Find the serial console pinsâusually labeled TX, RX, and GNDâand hook up a USB-to-UART adapter. Open a terminal emulator like minicom or screen, interrupt the bootloader (U-Boot is the usual suspect), and drop into its command shell. From there, you can dump each flash partition to a TFTP server or an SD card. Focus on the kernel partition and the root filesystem partition.

Kernel Analysis: Version Strings, Modules, and Hidden Symbols
Once youâve got the kernel imageâusually a compressed zImage or uImageâextract it and start digging. Run strings on the binary to pull out the kernel version string. That tells you the exact upstream release the vendor started from. A compliant source release has to match this version, right down to the sub-level patch number. Next, check for loadable kernel modules. On the extracted root filesystem, look in /lib/modules/. Run modinfo on each .ko file to see its vermagic and any license tags. If a moduleâs license field says âproprietaryâ but it links against GPL-only kernel symbols, thatâs a violation. The kernelâs symbol export mechanism explicitly marks certain functions as off-limits to non-GPL modules. A common trick is to use a shim module or patch the kernel to weaken those export checks. Itâs still non-compliant.
To go deeper, disassemble the kernel and its modules. Look for functions that have been stripped of their GPL-only export status. In the kernel source, functions like dma_buf_export are guarded by EXPORT_SYMBOL_GPL. If the running kernelâs symbol table shows them as plain EXPORT_SYMBOL, the vendor has modified the kernel to let proprietary modules link against them. That modification itself is a GPL violationâit changes the licensing terms of the kernel code.
Userspace Libraries and the GPLâs Long Arm
The kernel gets most of the attention, but userspace isnât off the hook. The GPLâs copyleft effect reaches any program thatâs a derivative work of GPL code. For libraries, the LGPL is more common, but full GPL libraries like readline or certain multimedia frameworks do show up. Use readelf or objdump to examine dynamically linked binaries on the root filesystem. Identify every shared library they link against. Then, for each library, figure out its license. If a binary links to a GPL library, the whole program must be distributed under a GPL-compatible license, and its source code has to be offered.
Hereâs a practical check: look for BusyBox. This single binary packs in a bunch of standard Unix utilities and is GPL-licensed. If the device uses BusyBox, the vendor must provide the exact BusyBox source, including any custom applets they added and the configuration file used to build it. A common dodge is shipping a BusyBox binary with a tweaked configuration that enables or disables features, but only linking to the upstream BusyBox website. That doesnât cut it. The vendor has to provide the precise source that matches the binary on the device.

Verifying Buildability: The Real Test
Having the source code is only half the story. The GPL requires that the source be the âpreferred form of the work for making modifications.â For embedded software, that means the source has to be practically buildable. Set up a cross-compilation environment that matches the deviceâs architectureâARM, MIPS, whateverâand try to build the kernel and root filesystem from the provided source. Does it compile without errors? Does the resulting kernel binary match the one you pulled off the device? A byte-for-byte match is the gold standard, but at a minimum, the functionality has to be identical. If the provided source is missing the correct .config file, device tree blobs, or essential build scripts, it fails the buildability test.
Pay attention to the toolchain. The GPL covers âscripts used to control compilation and installation of the executable.â If the vendor used a specific, patched version of GCC to build the firmware, that toolchain source and the patches have to be provided. A common oversight is offering the source but leaving out the proprietary linker script or the exact compiler flags that make the build work. Without those, the source isnât the preferred form for modificationâitâs an incomplete puzzle.
Documenting What You Find and Taking Action
As you work, keep a detailed audit log. For each potential violation, note the file name, the specific GPL component involved, the evidence (like a kernel module with a proprietary license tag linking to GPL-only symbols), and the steps to reproduce the finding. This documentation does two things. First, it gives you a clear, technical basis for a compliance request to the vendor. Second, if the vendor ignores you, it becomes the foundation for a report to the copyright holders or a community enforcement group.
When you contact the vendor, be precise and professional. State the device model and firmware version. List the GPL components youâve identified. Explain exactly whatâs missing or non-compliant, and reference the specific GPL version text. Offer to verify any corrected source release they provide. A lot of violations come from ignorance or sloppy internal processes, not deliberate malice. A well-documented audit can help a company fix its compliance pipeline and avoid future headaches.
FAQ: Common Questions on GPL Auditing
What if the vendor provides source code, but itâs for a different kernel version?
Thatâs a violation. The GPL requires the source code to correspond exactly to the binary version distributed on the device. A mismatched kernel version means the source canât be used to reproduce or modify the running software. You should request the exact source, including all patches and the specific configuration used for the build.
How can I tell if a kernel module is proprietary?
Use the modinfo command on the extracted module file. Look for the âlicenseâ field. If it says âProprietaryâ or is empty, the module isnât GPL-compatible. Then, check the kernelâs symbol table (often /proc/kallsyms on a running system) to see if that module uses any symbols marked with a âGâ (GPL-only). If it does, the module is in violation. You can also disassemble the module to look for deliberate circumvention of GPL symbol checks.
Does the GPL require vendors to provide the signing keys for secure boot?
This is a tricky area. The GPLv3 explicitly addresses âInstallation Information,â which includes keys and procedures needed to install modified software on the device. But many embedded devices use GPLv2 code (like the Linux kernel), which lacks this explicit requirement. For GPLv2, the consensus in the compliance community is that if the vendor uses code signing to prevent modified versions from running, they must provide the signing keys or a way to disable the signature check. Otherwise, the âpreferred form for modificationâ isnât truly being provided, because modifications canât be practically executed. This remains a contested point, but itâs a strong argument in enforcement discussions.
What if the device uses a GPL library but the main application is proprietary?
If the library is licensed under the full GPL (not LGPL), the application linking to it becomes a derivative work and must also be licensed under the GPL. The vendor has to release the applicationâs source code. If the library is LGPL, the application can stay proprietary, but the vendor must still provide the source for the LGPL library itself, including any modifications, and must allow relinking against modified versions of the library. Check the actual license file included with the library to be sure which version applies.
What tools are essential for a firmware audit?
A minimal toolkit includes binwalk for extracting firmware images, a cross-compilation toolchain for the target architecture, objdump and readelf for binary analysis, and a serial console adapter for physical access. For deeper analysis, a disassembler like Ghidra or IDA Pro is invaluable. A hex editor and familiarity with filesystem structures (SquashFS, JFFS2, UBIFS) are also important. The most critical tool, though, is a thorough understanding of the GPL text and its practical implications.