Request for classic confinement: device-tree-compiler

device-tree-compiler (dtc) is a development tool and requires classic confinement to function properly.

it definitely doesnt need classic for me … i can de-compile/compile dtb’s just fine with it under strict confinement …

This request for a different package: device-tree-compiler not devicetree-compiler. See https://github.com/stephanosio/snap-device-tree-compiler

The devicetree-compiler package is broken at so many different levels (from version number to not properly exporting commands, …).

IIUC, with strict confinement, the app is sandboxed and unable to access the host files. For instance, if I use strict confinement with my package, I get the following (which is expected):

stephanos@DOMINUS:~/Dev/xilinx-qemu-devicetrees$ which dtc
/snap/bin/dtc
stephanos@DOMINUS:~/Dev/xilinx-qemu-devicetrees$ make V=1
mkdir -p .//LATEST/SINGLE_ARCH; gcc -E -nostdinc -Iinclude/ -x assembler-with-cpp  -o - board-versal-ps-virt.dts | dtc -q -O dtb -I dts -o LATEST/SINGLE_ARCH/board-versal-ps-virt.dtb - -b 0;
FATAL ERROR: Couldn't open output file LATEST/SINGLE_ARCH/board-versal-ps-virt.dtb: Permission denied
Makefile:69: recipe for target 'LATEST/SINGLE_ARCH/board-versal-ps-virt.dtb' failed
make: *** [LATEST/SINGLE_ARCH/board-versal-ps-virt.dtb] Error 1

well, it fulfills the purpose of disassembling and reassmbling devicetrees, my package was never meant to be integrated into a build system which is why i never asked for an alias … it is a developer tool doing exactly what it says on the tin … if you ship more stuff and integrate better, thats fine, yet i still dont see why it would need classic confinement to do its job…

also note that a classic snap will be unusable on i.e. UbuntuCore (using it there was the main purpose of mine, to be able to add devicetree overlays manually during development)

Unless you are directly invoking /snap/devicetree-compiler/current/bin/dtc (which, to my understanding, you should never do), strict confinement should not work and classic confinement is a must.

The goal of this is to provide a cross-distro device tree compiler package, mainly because the default distro version is often too outdated for use with certain projects (in my case, Zephyr RTOS).

well, it works here …

$ devicetree-compiler --help
Usage: dtc [options] <input file>

Options: -[qI:O:o:V:d:R:S:p:fb:i:H:sW:E:hv]
  -q, --quiet                
	Quiet: -q suppress warnings, -qq errors, -qqq all
  -I, --in-format <arg>      
	Input formats are:
		dts - device tree source text
		dtb - device tree blob
		fs  - /proc/device-tree style directory
  -o, --out <arg>            
	Output file
  -O, --out-format <arg>     
	Output formats are:
		dts - device tree source text
		dtb - device tree blob
		asm - assembler source
  -V, --out-version <arg>    
	Blob version to produce, defaults to %d (for dtb and asm output)
  -d, --out-dependency <arg> 
	Output dependency file
  -R, --reserve <arg>        
	tMake space for <number> reserve map entries (for dtb and asm output)
  -S, --space <arg>          
	Make the blob at least <bytes> long (extra space)
  -p, --pad <arg>            
	Add padding to the blob of <bytes> long (extra space)
  -b, --boot-cpu <arg>       
	Set the physical boot cpu
  -f, --force                
	Try to produce output even if the input tree has errors
  -i, --include <arg>        
	Add a path to search for include files
  -s, --sort                 
	Sort nodes and properties before outputting (useful for comparing trees)
  -H, --phandle <arg>        
	Valid phandle formats are:
		legacy - "linux,phandle" properties only
		epapr  - "phandle" properties only
		both   - Both "linux,phandle" and "phandle" properties
  -W, --warning <arg>        
	Enable/disable warnings (prefix with "no-")
  -E, --error <arg>          
	Enable/disable errors (prefix with "no-")
  -h, --help                 
	Print this help and exit
  -v, --version              
	Print version and exit

and note that i’d happily drop my package in favour of yours, but being able to use it on an UbuntuCore device during board bringup is its most essential feature for me and many UbuntuCore customers,

it does work fine in strict mode for the purpose of compiling/disassembling a dtb or a dtbo during development, it might need some extra bits and pieces (dtc alias, perhaps some extra interfaces) when invoked from make though.

ah, I see that you allowed home directory access for your package:

sure, it will work as long as the dt files are located under your home directory, which may not always be the case for many users (hence, requesting classic confinement for it).

I don’t really know much about UbuntuCore, but your package does seem to have its place, so why not keep both? I will clarify in the package description that it uses classic confinement and cannot be used on UbuntuCore.

because i need to go on maintaining mine then :wink:

anyway, it is up to the reviewers to decide if “i want to build somewhere out of /home, /media or /mnt” is enough to qualify for classic (i personally dont do my builds outside of /home even for esp32’s, kernels or OS images, but i guess that’s a matter of someones development env setup)

TBH you even don’t need to any access any of the special locations. Using stdin/stdout works well with dtc:

$ dtc -I dtb -O dts < bcm2710-rpi-2-b.dtb > decompiled
$ dtc -I dts -O dtb < decompiled > compiled
$ md5sum bcm2710-rpi-2-b.dtb compiled 
867277f9d0d333df78e1a51b9f259467  bcm2710-rpi-2-b.dtb
867277f9d0d333df78e1a51b9f259467  compiled

Though I see how a user unfamiliar with confined apps would blindly pass some path and get a weird error message in return.

That is not really a choice if you are invoking dtc as part of a build system that passes file path.

As per Process for reviewing classic confinement snaps, a user accessing arbitrary files on the system is not typically a justification for classic confinement.

What are typical locations that your users might use that aren’t currently covered by the home and removable-media interfaces?

/usr/src or /usr/local/src wouldn’t be so uncommon.

Shouldn’t this fall under one (or more) of these “supported” categories?

  • compilers
  • programming languages

Atm, the ‘system-trace’ interface does allow access to /usr/src, but this interface allows a lot more than what your snap needs (ie, it allows using kernel tracing facilities).

Furthermore, /usr/src and /usr/local/src are typically root owned and I wouldn’t think a build system or user would have write access to put things there to then use later (but see below).

Compilers and programming languages may be allowed classic if their core functionality requires use of the host’s installed header files (eg, in /usr/include), .so files (eg, in /lib and /usr/lib), etc since the snap’s runtime environment won’t contain these files (/usr/local/src would also fall into this category).

Unless I misunderstand how device-tree-compiler works (please correct me!), device-tree-compiler works on files specified by the user and doesn’t make assumptions about where system header files, libraries, etc are located. Applications like this that are packaged as snaps are expected to use strict confinement (and as the publisher, you may also plugs ‘home’ and ‘removable-media’) and therefore classic confinement is not warranted. (I’ll also mention that classic confinement is typically quite fragile and difficult to maintain across the myriad of distributions that snaps may run on since you can’t easily depend on a stable runtime environment, and, as mentioned, classic confinement precludes use on Ubuntu Core devices).

We could consider adding a new interface to snapd for /usr/src. The LSB defines /usr/src as: “Source code may be placed in this subdirectory, only for reference purposes” and further says “Generally, source should not be built within this hierarchy”. In that light, the interface for /usr/src would be a read-only interface.

In the strictest sense, I’m not sure that dtb files are source code, and (de)compiling from /usr/src doesn’t seem like a natural fit for dtb files, but if the interface was added, you could certainly use it.

@pedronis - as architect, can you comment on if an interface for read-only access to /usr/src is something we should pursue?

unrelated to the devicetree compiler, an interface giving read access to /usr/src would surely get us one step closer to snap support for dkms in ubuntu (since the kernel headers live there)

One of the main uses of dtc is by the Linux kernel build process to compile dts (device tree source) files into dtb (device tree blob/binary) files and, as you may very well understand, it is a norm to keep the kernel source code under /usr/src.

In that sense, a dtc package that cannot access /usr/src might as well be useless for many.

In general, as a developer, the last thing I would want for my command line tools (let alone kernel development tools) is sandboxing, as that would often seriously limit the range of things I can do with it.

If I have a sandboxed (insert cmd line tool name here), I will almost certainly end up uninstalling it and replacing it with an alternative that does not suffer sandboxing, because it simply does not work for the things I usually do with it.

If the sole purpose and goal of snap is to support sandboxed apps, then I am afraid this is not going to work for us, as our goal is to provide distro-independent SDK packages through snap.

For now, I have released device-tree-compiler with strict confinement (home access only):

Ok, this was the missing piece for me. The gives a clear use case for creating an interface for /usr/src. I’ve added this as a todo for the next batch of policy updates. (cc @pedronis)

2 Likes

FYI, https://github.com/snapcore/snapd/pull/8868 (note, the interface name is not finalized).

Hello everyone!

Could you tell me how I can load custom dtbo file to DT, please? Seems that config.txt file has some pre-config list of overlay files.