How to Audit a Device for GPL Compliance: A Practical Guide for Embedded Engineers

When you crack open a new embedded Linux gadget—whether it’s a router, a smart camera, or an industrial IoT gateway—you’re not just holding hardware. You’re holding a bundle of open-source software, and a lot of it is covered by the GPL. That license isn’t a suggestion. It’s a binding set of requirements. Yet after years of tearing down consumer and industrial gear, I’ve seen that many manufacturers treat the GPL like an afterthought. This isn’t about legal nitpicking. It’s about supply chain integrity, security, and the right to fix what you own. A proper GPL audit is a technical process, not a philosophical one. Here’s how you do it, step by step, from the first glance at the box to the final compliance report.

Close-up of a circuit board being inspected with a multimeter

Why a GPL Audit Matters for Industrial and Consumer Devices

The GPL isn’t just a legal hoop. It’s the backbone of the Linux ecosystem. For engineers, the “corresponding source” that the GPL demands is the difference between a device you can trust and a black box you’re stuck with. If a vendor won’t give you the source, they’re probably also hiding outdated kernels, sloppy patches, and gaping security holes. An audit forces transparency. It gives you the exact software bill of materials, the kernel config, and the build scripts—everything you need to maintain, patch, or even rebuild the firmware yourself. That’s not just compliance. That’s control.

Phase 1: Reconnaissance—What the Vendor Claims

You don’t need to power anything on yet. Start with what the manufacturer tells you—and what they don’t.

Find the Written Offer

GPLv2 Section 3 and GPLv3 Section 6 are blunt: you either get the complete source with the binary, or you get a written offer to obtain it. That offer might be a slip of paper in the box, a line in the manual, or a URL on a support page. Track it down. A valid offer has to be clear, include real contact details, and stay valid for at least three years. If the link 404s, the email bounces, or the offer simply isn’t there, the device is already non-compliant. Take screenshots. Save everything. I’ve seen industrial IoT vendors and big consumer brands flunk this step more times than I can count.

Pick Apart the Source Package

If you actually get a source archive, don’t trust it. The GPL requires the “complete corresponding source,” and that means the scripts that control compilation and installation, too. Unpack it and look hard at what’s inside:

  • Kernel configuration: You need a full .config file, not a stripped-down defconfig that needs secret sauce to build.
  • Build scripts: Makefiles, shell scripts, Yocto or OpenEmbedded recipes—anything that describes the actual build. A vanilla kernel tarball with one patch and zero instructions? That’s usually a fail.
  • Modified components: Patches and changed source files. The GPL says you must provide the “preferred form for making modifications.” A single giant patch over a stock tarball might technically check a box, but it’s hostile. Look for real version control history or at least clean, commented patches.

Phase 2: Static Firmware Analysis—No Device Required

If the vendor publishes firmware updates, you can learn a lot without ever touching the hardware. This step often uncovers the ugliest surprises.

Extracting the Firmware Image

Firmware comes in all shapes: raw blobs, U-Boot FIT images, weird vendor containers. Start with the file command to figure out what you’re dealing with. Then reach for binwalk. It scans for magic bytes—SquashFS, JFFS2, CPIO, you name it—and lets you carve out the filesystem with dd or its own -e flag. If the image is encrypted or deliberately obfuscated, that’s a red flag by itself. Honest vendors don’t hide their firmware.

Building the Software Bill of Materials

Mount that root filesystem and start cataloging. You’re building an SBOM—a list of every GPL-licensed component. Begin with the kernel. The image (often zImage or uImage) is a composite, but a quick strings uImage | grep "Linux version" pulls out the exact version and build timestamp. Then hunt for the usual suspects: busybox, iptables, gawk, bash, ntpd, and libraries like libc (uClibc or glibc, both LGPL). If there’s a package manager database—opkg, dpkg—use it, but don’t rely on it. Verify manually with strings and check dynamic linking with readelf -d.

A person working on a laptop with a disassembled hard drive and tools on the desk

Phase 3: Dynamic Analysis—Getting Inside the Device

Static analysis shows what’s on disk. Dynamic analysis shows what’s actually running and how it was built. For this, you need a shell.

Getting a Shell

Flip the board over and look for a UART header. Solder on a 3.3V USB-to-serial adapter, fire up minicom or screen, and watch the boot log. U-Boot often gives you an unprotected shell if you smack a key during boot. From there, printenv spills the kernel command line, memory addresses, and boot scripts. If the bootloader is locked down, check for telnet or SSH. Default credentials and backdoor passwords are still depressingly common. Once you’ve got root, the real work starts.

Verifying the Running Kernel and Modules

/proc is your best friend. cat /proc/version should match what you found statically. zcat /proc/config.gz gives you the exact kernel config that built the running kernel. Compare that to whatever .config the vendor shipped. A mismatch is a violation, plain and simple. Then run lsmod. The GPL status of kernel modules is a long-running fight, but the dominant legal view is that any module using symbols exported with EXPORT_SYMBOL (not EXPORT_SYMBOL_GPL) is still a derivative work. If you see a proprietary module—modprobe will often mark it “tainted”—the vendor is on thin ice.

Auditing User-Space Binaries

For every GPL binary in your SBOM, you need to check that the source matches. The gold standard is a reproducible build: take the vendor’s source and scripts, build it yourself, and compare the resulting binary to what’s on the device. If they don’t match, the vendor didn’t give you the complete source. A common dodge is to provide source for a vanilla package but link it against a proprietary, modified library. Catch that with readelf -d on the target binary—check the required shared objects against what’s in the source. Another trick: strip debug symbols and claim the source is for a different version. The version string inside the binary, found with strings, should line up exactly.

Phase 4: The Compliance Report and What Comes Next

An audit without a report is just a hobby. Your report needs to be technical, evidence-based, and free of legal posturing. List every GPL component you found, the evidence for it, the source the vendor provided, and a clear pass/fail. For failures, spell out the technical reason: missing .config, binary mismatch, incomplete build scripts, tainted kernel module. This document does double duty. It’s a direct, actionable list for the vendor. And it’s a public record. Posting it on a site like gpl-devices.org creates a permanent, citable reference that pressures vendors and helps other engineers.

FAQ: Common Questions on GPL Audits

What’s the most common GPL violation you see?

Hands down, it’s the kernel source. Vendors love to ship a vanilla tarball from kernel.org with a single patch, but they leave out the .config, the toolchain, and any build scripts. Without those, it’s not the “preferred form for making modifications,” so it’s non-compliant. A close second: proprietary kernel modules that taint the kernel. That’s a direct hit against the GPL’s copyleft.

Can I audit a device without opening it or voiding the warranty?

Partially, yes. Static analysis on a firmware update file can reveal the kernel version, filesystem layout, and GPL components. But a full audit almost always needs shell access on the running device to check the kernel config, loaded modules, and processes. That usually means a serial console, which often means opening the case. Those “warranty void if removed” stickers? In many places, they’re not enforceable for inspection or repair of your own gear. Still, it’s a legal gray area. Document the device’s state before you open it, and know the risks.

What tools do I need for a firmware audit?

The toolkit is simple and mostly open source. binwalk for extraction, strings for quick binary recon, readelf for ELF inspection, and a hex editor like hexdump or Bless for low-level poking. For dynamic work, a USB-to-serial adapter and a terminal emulator like minicom are essential. If you’re attempting a reproducible build, you’ll need a Linux VM with a full build environment (GCC, binutils, make). But the most important tool is a skeptical mindset. Assume the vendor hasn’t complied until you see complete, buildable source that matches the running binaries.

A person inspecting a green circuit board with a magnifying glass

This audit process isn’t a one-and-done deal. It’s a discipline. Apply it consistently across the devices you deploy or integrate, and you build a body of knowledge that’s hard to ignore. After an audit, the natural next step is a deeper dive into what you found. Uncovered an ancient, unpatched kernel? A follow-up piece could walk through backporting security fixes or building a modern replacement from the vendor’s own board support package. The point isn’t just to catch violations. It’s to push the embedded industry toward a world where compliance is the default, not a surprise.