Subject: Re: bug#38498: Fontconfig does not find fonts in non-default profiles

From: Bengt Richter <[email-masked]>
Date: Sun, 15 Dec 2019 14:14:06 -0800

Hi Guix,

On +2019-12-13 14:11:13 +0100, Pierre Neidhardt wrote:
> Just read this:
> https://gitlab.freedesktop.org/fontconfig/fontconfig/issues/126
> 
> Could we do the following: use a profile hook to generate a config file
> and set the environment variable FONTCONFIG_FILE to this file?
> 
> (I feel that we can't do that because the path of the hook-generated
> cannot be known in advance.)
> 
> 
> I looked at what NixOS does in
> nixpkgs/pkgs/development/libraries/fontconfig/default.nix:
> 
> >  - NixOS creates /etc/fonts/${configVersion}/fonts.conf link to $out/etc/fonts/fonts.conf,
> >     and other modifications should go to /etc/fonts/${configVersion}/conf.d
> 
┌─────────────────────────────────────────────────────────────────────────┐
│ > We don't have a global font folder and we probably don't want to have │
│ > one, so I guess this is not ideal.                                    │
└─────────────────────────────────────────────────────────────────────────┘

How about an interplanetary font folder? cf. IPLD[1] :-)

I'm thinking fonts might be a good use case as content-addressable items
identified by what I call vbr's (Verifiable Blob References). A poc vbr
implementation is demoed below.

[1] git clone https://github.com/ipld/specs.git

> The <dir> fontconfig setting in Nix is
> 
> --8<---------------cut here---------------start------------->8---
>       <!-- nix user profile -->
>       <dir>~/.nix-profile/lib/X11/fonts</dir>
>       <dir>~/.nix-profile/share/fonts</dir>
>       <!-- nix default profile -->
>       <dir>/nix/var/nix/profiles/default/lib/X11/fonts</dir>
>       <dir>/nix/var/nix/profiles/default/share/fonts</dir>
> --8<---------------cut here---------------end--------------->8---
> 
> so it probably suffers from the same issue.
>

I have been working on my own spin on content-addressability
by way of what I call a vbr -- Verifiable Blob Reference.
It is a name that can be used for a symbolic link or a filename.

It is formed by a prefix followed by a guix hash followed by a
single hyphen followed by the basename of the file (or -bnam opt), like
prefix-hash-basename -- but the final guix hash you see in the final name
is not the guix hash of the file bytes, though that is used to form
an intermediate name string ("prefix-hashOfFileBytes-basename").
The final hash in the final name is a guix hash of the intermediate
name string per se, and _that_ hash is placed between "prefix-" and
"-basename" to form the final name so that the final name is
"prefix-hashOfIntermediateNameString-basename"

So the final name's hash is dependent on both the source bytes
and characters of the name. I'm hoping it will be hard to modify
source file bytes to produce the same final name.

I'm thinking is kind of like the old trick of taking the CRC32
of a packet with the CRC slot set to a known value and stuffing
the resulting CRC back in that slot.

I am not a crypto expert by any means, so comments on weaknesses
are appreciated. The above describes one variant. There is also
a self-referential version where the vbr text can be embedded in
the file, but that requires a substitution trick in the file byte
stream feeding the hash so the self-reference slot(s) can be
fixed value(s) during hashing. Still a wip but a single slot in
first or last pages of a file is not too bad :-) This in turn
has text vs binary variations. I've seen similar to the latter
described, but not my repeat hash vbr method, though I wouldn't
be that surprised if someone says, "Yeah, that's called frobulation."
or something.

I am re-inventing wheels I notice every time a scan the internet,
but hope to contribute something useful, eventually :)

Since this started with fonts, I'll start with a sample
┌──────────────────────────────────────────────────────────────────────────────────────────┐
│     this shows verifiable blob reference (vbr) names for duplicated 12x22 font files     │
├──────────────────────────────────────────────────────────────────────────────────────────┤
│ $ find /gnu -type f -iname '*12x22*'|while read x;do vbr GxFont12x22- $x;done            │
│ GxFont12x22-0jhp0cswgvpg4awc7cnadi9jymglnfryj0l9fcg1z7wd5sw8210a-sun12x22.psfu.gz        │
│ GxFont12x22-0ylkkdlwhzfw3dadsqhhh021xafz97zajc3qcgrbv6vmdlk3chpn-LatGrkCyr-12x22.psfu.gz │
│ GxFont12x22-0awqnypd4np6zpjy12wd2fq5ri9ifamapadfmn1h9k2vjjnndwpd-iso01-12x22.psfu.gz     │
│ GxFont12x22-1hy97l5n7363q5w5x19f7c8klabbprrpx5r1ki4swbn372326jgl-iso02-12x22.psfu.gz     │
│ GxFont12x22-1zrlk9zvpkmhcl0cyxy5pnm6mqy7qranx40gz5gy3wvf0cnpm6dp-README.12x22            │
│ $                                                                                        │
│ $ find /usr -type f -iname '*12x22*'|while read x;do vbr GxFont12x22- $x;done            │
│ find: ?/usr/share/polkit-1/rules.d?: Permission denied                                   │
│ GxFont12x22-0jhp0cswgvpg4awc7cnadi9jymglnfryj0l9fcg1z7wd5sw8210a-sun12x22.psfu.gz        │
│ GxFont12x22-0ylkkdlwhzfw3dadsqhhh021xafz97zajc3qcgrbv6vmdlk3chpn-LatGrkCyr-12x22.psfu.gz │
│ GxFont12x22-0awqnypd4np6zpjy12wd2fq5ri9ifamapadfmn1h9k2vjjnndwpd-iso01-12x22.psfu.gz     │
│ GxFont12x22-1hy97l5n7363q5w5x19f7c8klabbprrpx5r1ki4swbn372326jgl-iso02-12x22.psfu.gz     │
│ GxFont12x22-1zrlk9zvpkmhcl0cyxy5pnm6mqy7qranx40gz5gy3wvf0cnpm6dp-README.12x22            │
└──────────────────────────────────────────────────────────────────────────────────────────┘
Potentially, the store could contain vbr names naming links to the foreign versions
in /usr and which could be verified any time desired for integrity and identity, and
presence: if absent, it would be optional to go to a substitutes repo or anywhere on
the web to refresh a local cache. If you find the name you can verify that the referenced
blob is identical to any other with the same name and dereferencing. More discussion below.

The names are made so that the hash part is dependent on both the file bytes
and the name itself as axplained below.

Following is an example poc vbr session. Pretty simple so far, but bigger dreams afoot ;-)

The commands are (others are wip, not shown :)
    vbr prefix- filepath  # prefix includes single trailing - for now
    vbr -ck [ vbr-link | vbr-file-name ]

The rest made this a monster post, so if vbr and potential uses is
of interest, perhaps someone could copy this as the seed of a new thread
in a more appropriate list for discussing guix architectural evolution
and factoring out of minimalist components for use separately and/or
in minimal environments?

Also the guile language tower interests me :)

The following is an example of a possible format for sharing embedded snippets
simply and bitwise unambiguously. Lots of other possibilities exist ;-)
┌─────────────────────────────────────────────────────────────────────────┐
│   v1Snippet-1mzfvrqhllz92siajm2rq7h7a67hg486wnyjwxznhc0zmzxg9n2v-xxx    │
├─────────────────────────────────────────────────────────────────────────┤
│ Among other things, I discuss using vbr's as verifiable blob references │
│ for what UEFI bios reads from /boot and so for what a boot loader sees, │
│ and so forth. Also the role of vbr's in casual but unambigous sharing   │
│ of snippets within emails and docs, for automatic search and validated  │
│ extraction.                                                             │
└─────────────────────────────────────────────────────────────────────────┘
The above could be cleanly automated but was done ad hoc by selecting the
five lines of box content before boxing it, and then executing

--8<---------------cut here---------------start------------->8---
cat > /tmp/xxx;cat /tmp/xxx|boxit -title "$(vbr v1Snippet- /tmp/xxx)"
--8<---------------cut here---------------end--------------->8---

as a shell filter command on the region. The part after -title
put the vbr in title above the boxed content. So a search on v1Snippet-...
in e.g. this email lists archives in mbox format would allow automated
extraction of the box content and checking that the vbr was correct.

Of course you could do a vbr for a base64 part of an email too,
before or after decoding.

I think vbr is simple enough to integrate easily into the guix architeture.
Or WDYT, Ludo ;-)

Ok, this is getting long again ;-/

Can't resist including the /boot use:

Here is a use case re booting images.

for f in /boot/*{x,g};do vbr v1Boot- "$f";done
┌──────────────────────────────────────────────────────────────────────────────────────────┐
│               veebers for what UEFI sees, which it could keep as whitelist               │
├──────────────────────────────────────────────────────────────────────────────────────────┤
│ v1Boot-0c9w9bjwbhn8hn7w427qar8wgdbyic7xv88pjs4yji79n9f2433v-vmlinuz-linux                │
│ v1Boot-1dp21vvpx99nqjy2z8s239f8bgiqh43lzxm91j7a3n2867ngadj0-initramfs-linux-fallback.img │
│ v1Boot-1bxpkf7i3w7q3c4ziasp2vgg17xq5j3vdqp9y633l5212ddypj8d-initramfs-linux.img          │
│ v1Boot-02yla7mv6qg16j0zw0dyy339zdn827xlv964hbinx7hnhi5ax3kk-intel-ucode.img              │
└──────────────────────────────────────────────────────────────────────────────────────────┘

This would enable safe booting via TFPT, without signatures, assuming you checked and
trusted the vbr when you efibootmgr'd it. The UEFI could load speculatively and display
a computed vbr for an image it loaded and didn't recognize. The user could then check
the the web for a trusted opinion and bail or proceed (given UEFI password) to accept
the new image and white-list it with one-shot trial boot if desired.

This would also be a nice way to validate a boot-to-guile image ;-)

-- 
Regards,
Bengt Richter