Subject: Re: Understanding #:substitutable? and #55231

From: Maxime Devos <[email-masked]>
Date: Sun, 9 Feb 2025 22:13:51 +0100

On 9/02/2025 20:37, Ian Eure wrote:

> Hi Maxime,
>
> Maxime Devos <[email-masked]> writes:
>
>> On 9/02/2025 2:06, Ian Eure wrote:
>>
>>> Hi Morgan,
>>>
>>> Morgan Arnold via "Development of GNU Guix and the GNU System
>>> distribution." <[email-masked]> writes:
>>>
>>>> Hello,
>>>>
>>>> If the issue is simply that the patch has not been rebased against a
>>>> new enough version of Guix to be merged, I am happy to do that
>>>> rebasing. Additionally, please correct me if I have made any incorrect
>>>> assertions above.
>>
>> No. See the stuff about #:substitutable?. The reason I didn't answer
>> back then, is that I don't want to keep being a broken record.
>
> Could you help me understand the case where this becomes a problem?  
> Is it:
>
> - If you have one machine with an operating-system which includes  a 
> non-#:substitutable? out-of-tree kernel module in its initrd,  and
> - A second machine with an identical initrd configuration, and
> - The first machine is configured to serve substitutes, and
> - The second machine uses the first as a substitute server
>
> Then the non-#:substitutable? module would be distributed, violating 
> its license?

Yes (assuming typical ZFS+GPL compatibility argument) (and assuming the 
two machines are by different people - if it's by the same person, I 
imagine it may simplify the legalities).

Well, it wouldn't be distributed as the module itself, as it's embedded 
in the initrd. But the initrd is substitutable, so the initrd is 
distributed.

> I’d also find it helpful to understand the line for specific acts and 
> entities in play, on a matrix of: allowing violations, encouraging 
> violations, or committing violations; and by individual Guix users, or 
> by the Guix project itself.  For example, I think the Guix project 
> encouraging or committing a violation is unacceptable.
>
> I think this would help a great deal to make the bounds of the problem 
> clear, which is needed to solve them.

I'd say:

Allowing violations by the Guix project: pretty much never. (Like, 
_maybe_ in some cases it can be determined it's a dead law not worth 
following in jurisdiction X at time [T,T+?), but then this needs to be 
repeated for all the jurisdictions, and may need to be reevaluated 
often, now consider that most of us probably aren't lawyers, let alone 
in a sufficient number of jurisdictions, and that there may be 
disagreements, and that evaluating the situation takes time+effort ... 
Doesn't seem worthwhile.)

Encouraging violations: never. (Encouraging law breaking seems illegal.)

Allowing violations - depends, we're not going to install spyware and 
constantly monitor them or something, so they probably could do things 
out-of-sight. But "hint hint, don't add activate X (whose purpose is to 
make Y), or the illegal substance Y will result" (**) doesn't seem like 
something to have in Guix.

And while documenting "The default configuration of adding X (ZFS) to 
your Y (operating-system kernel-modules) might be illegal, so also 
modify the initrd to mark it as non-substitutable" is worth _something_, 
it's much better to just automatically mark the initrd as 
non-substitutable, as this is an easy pitfall and entirely automatable.

(**): this is reference to prohibition era in US

What I think Guix should (try to) ensure to be the case, is:

If users tag their custom stuff (including from channels) that shouldn't 
be distributed with #:substitutable? #false, and they intentionally 
change things to violate the law, then users can legally run their 
substitute servers without worrying about the particulars of their 
configuration, and without having to look closely at the manual (you 
_should_ read the manual, but you might not known in advance which parts 
you should have read, and might easily miss something). If Guix knows 
that some of this isn't automated in some known situations, then in 
those known situations it should produce some kind of error message, 
such that they know they need to resolve the situation in some matter.

>> If 'make-linux-libre' in the presence of ZFS leads to #:subsitutable?
>> problems, that doesn't mean it's fine to ignore the law for #52231. It
>> means you need to:
>
> Could you please help me understand how `make-linux-libre' is in 
> scope?  I don’t believe any in-tree kernel modules have the 
> problematic license terms, so I think the issue is purely out-of-tree 
> stuff, whether that’s ZFS, nVidia drivers, "endpoint protection" 
> security systems, etc.  Perhaps you meant `make-initrd'?

I meant 'make-linux-libre'. This is a comment about 
<https://lists.gnu.org/archive/html/guix-devel/2025-02/msg00061.html>:

> If the concern is rather that this change makes it easier for someone to
> accidentally redistribute a compiled ZFS kernel module and commit a 
> copyviol, I
> struggle to see how this concern is particular enough to #55231 to be 
> a reason
> not to merge it. It seems to me, at least in principle, that it would 
> be just
> as simple to commit a copyviol by using, say, the `make-linux-libre` 
> function
> (which does not appear to set `#:substitutable? #f` on the resulting
> derivation, unsurprisingly) to build a kernel with the ZFS kernel 
> module built
> in, and then redistributing that. It seems like the only way to 
> completely
> remove this possibility would be to make `#:substitutable?` 
> "poisoning", so to
> speak, in the sense that any derivation taking non-substitutable 
> derivations as
> inputs would be marked non-substitutable itself. This seems to entirely
> eliminate the possibility of substituting something which is 
> non-substitutable,
> but I have no idea if this is practical or even desirable.
>
Going the the above, it might be possible to add nominally out-of-tree 
modules to be compiled from within the tree.

Do note that this is an 'if X then Y' construction, I did not claim that 
'X' is the case.

I do not know whether make-linux-libre supports such a thing.

>> More specifically, ZFS proponents (at least as a group, and when
>> limited to those visible in Guix) tend to be rather incoherent in
>> their positions, in the sense that simultaneously do:
>>
>>  (snip)
>
> I appreciate your perspective, however, I’m more interested in 
> understanding the problems so they can be solved.  Any help in that 
> area would be greatly appreciated.

The incoherency is the problem. If you want ZFS, and your belief ok ZFS 
being legally OK is based on P being true, then it follows you have

  (a) ensure that P is true/rectify !P situations,
  (b) or give up on ZFS
  (c) (third alternative) or find another justification and ensure its 
preconditions are met.

Yet, as a group, people that want ZFS in Guix have added ZFS without (a) 
and (c).

>>> It does seem that #55231 ended up in a place where there was
>>> concensus that it was acceptable, but didn’t get merged for some
>>> reason or other.  I definitely could be wrong, but I suspect the
>>> issue is that when non-#:substitutable? packages are used in places
>>> other than package inputs, the downstream derivations don’t carry
>>> that information.  I believe when used as a package input,
>>> non-#:substitutable? packages do, in fact, poison all downstream
>>> derivations.  Happy to be corrected if I’m wrong here.
>>
>> Not quite - to my understanding, the downstream derivations _also_
>> don't carry that information when it's in package inputs (at least,
>> last time I checked there didn't seem to be any mechanism to set
>> #:substitutable? to #false when any of the inputs are unsubstitutable
>> (whether non-bag(?) derivation inputs, implicit inputs, native-inputs,
>> ...)).
>
> Ah, hmm.  So these kind of violations are implictly prevented by Guix 
> not shipping things in combinations which would violate the license 
> terms?

... no? Guix _does_ ship things in bad combinations(*) (Linux-with-ZFS 
initrd, by users running a substitute server, in the case that this 
combination is in their configuration somewhere), without marking that 
initrd combination as nonsubstitutable (IIRC).

(*) actually, I don't recall whether the Linux is part of the initrd, 
but there also are other similar situations, e.g. system images. Same 
problem.

>>> I think it’s reasonable to merge this after it’s rebased on current
>>> master, and would be willing to do that unless Maxime or Ludo’ raise
>>> an objection.
>>
>> First you say you suspect the issue is that #:substitutable?-related
>> behaviour isn't right yet, and immediately in the next paragraph you
>> say it's reasonable to merge it. Given that the patches haven't been
>> adjusted to solve this, this is rather incongruent.
>
> While I agree that the fundamental #:substitutable? mechanism of Guix 
> could use improvement, I don’t believe these patches need to wait for 
> that work, becasue:
>
> - This is a generic mechanism useful for any out-of-tree module 
>  regardless of license[1].

And one of these out-of-tree modules is ZFS, where it is not useful 
as-is because of the license.

In fact, ZFS support is the purpose of #55231. (Evidence: (1) the 
example in the manual, (2) Kaeylen mentioning plans for using this for ZFS)

> - They won’t cause the Guix project to commit a license violation.
> - They don’t encourage individuals to commit license violations.
It does encourage them ... see, all the previously mentioned stuff about 
substitute servers.
> - While they could /allow/ individuals to commit violations, many 
>  things in Guix already do, because it’s infeasible to forbid.

It's not, and has never been, a matter of forbidding of allowing users 
to do something. It's  a matter of not leading to user (whether project 
or individual user) to _accidentally_ perform a violations.

And it's entirely feasible to prevent this: see, the stuff about 
#:substitutable? changes.

> To the last point:
>
> - Right now, Guix allows a user to make a system image containing 
>  compiled ZFS modules and distribute it.

s/allows an user to/lets an user accidentally/

This is a problem. This should be resolved this by (a) removing ZFS or 
(b) modifying the image producer to mark it as non-substitutable. 
(unlikely option (c): ZFS people adjust license). If people won't do (b) 
yet, it follows that (a) needs to be done for now.

> - Guix ships DVD rippers and programs which can copy files, which  a 
> user can commit copyright violations with.
> - Guix ships numerous programs for file sharing, whose /primary/ 
>  purpose is committing copyright violations.  The nicotine+  package 
> is one example[1].

This argument, essentially, is 'X already does the bad thing 
Y(nicotine+).  So, it's fine to do Z (improper ZFS support) as well.'.

This really doesn't follow. Like, if I were to burn down a house 
(illegal), that doesn't make it legal to steal a chair from the house.

Also, nowhere did I claim that #55231 purpose is committing copyright 
violations.

> I am struggling to square objections to a patch whose intent and 
> primary use would be within the bounds of non-binary-redistribution 
> licenses, but which might enable an individual to (most likely 
> inadvertently) commit a license violation with the significantly 
> riskier things which are already permitted.  If I’m misunderstanding 
> the situation here, I’d appreciate further insight.
>
> Some examples of other modules that could be used with this facility are:
>
> lttng, a GPL’d out-of-tree kernel tracing system
> ddcci, a GPL’d out-of-tree module for controlling monitor settings
> OpenRazer, a GPL’d out-of-tree module to suppot Razer HID hardware
>
> I’m certain there are other cases where it’d be useful.

ZFS _is_ the primary use, see previous remarks. Even if it weren't the 
primary use, it's still a main use, and will likely be advertised as 
such (if not in Guix proper manual, then likely in outside guides). Even 
it it weren't, ZFS is nevertheless a Linux kernel module in Guix, and 
#55231 deals with kernel modules in Guix, so #55231 needs to deal with ZFS.

Just because X has good uses Y1 ... Yn (lttng, etc.), doesn't mean it's 
fine to neglect the currently bad use Y0 (current implementation of 
#55231 + ZFS support).

Best regards,
Maxime Devos