<feed xmlns='http://www.w3.org/2005/Atom'>
<title>guix/tests/publish.scm, branch master</title>
<subtitle>Transactional package manager, declarative GNU/Linux distribution, reproducible deployment tool, and more! https://guix.gnu.org</subtitle>
<link rel='alternate' type='text/html' href='https://git.vineetk.net/guix/'/>
<entry>
<title>guix: serialization: validate directory entry names in fold-archive [security fix].</title>
<updated>2026-07-02T17:42:47+00:00</updated>
<author>
<name>Reepca Russelstein</name>
<email>reepca@russelstein.xyz</email>
</author>
<published>2026-06-08T05:21:43+00:00</published>
<link rel='alternate' type='text/html' href='https://git.vineetk.net/guix/commit/?id=ed0a9721f8a20d6ddcf6a0495302f502b3f7bb17'/>
<id>ed0a9721f8a20d6ddcf6a0495302f502b3f7bb17</id>
<content type='text'>
Also validate that they are in strictly ascending order, which also ensures
that there are no duplicate names.

When 'guix substitute' fetches a nar, it does so with a validly-signed hash
already known from the narinfo.  But it can't verify that the hash of the nar
it's currently fetching matches until the full nar is downloaded.  Until then,
'download-nar' will extract the nar into the specified destination using
'restore-path', which avoids having to keep a file of unbounded size in
memory.  Critically, this means that the input that 'restore-path' (and by
extension 'fold-archive') is processing is untrusted, since substitute server
TLS certificates aren't verified (the narinfo signatures are supposed to make
it unnecessary).

As such, the scope of harm that can be caused by a malicious nar being
processed by 'restore-file' needs to be minimized.

* guix/serialization.scm (valid-nar-file-name?): new procedure.
  (fold-archive): Use it to verify that directory entry names do not contain
  '/' or '\0', and they are not equal to ".", "..", or "".  Also verify that
  they are in strictly ascending order.
  (call-with-port*): new procedure.
  (dump-file): use O_EXCL and O_NOFOLLOW.  This precaution ensures that even
  if 'restore-file' is somehow tricked into writing to a symlink (not
  currently believed to be possible), it will result in an error.
* guix/store/deduplication.scm (call-with-fresh-output-file): new procedure.
  (dump-file/deduplicate): use it for similar reasons as 'dump-file'.
* tests/nar.scm (call-with-tree-port, port-bad-nar?): new procedures.
  ("write-file-tree + fold-archive, unsorted directory entries",
   "write-file-tree + fold-archive, duplicate directory entries",
   "write-file-tree + fold-archive, invalid directory entries"): new tests.
* tests/publish.scm (call-with-temporary-output-filename): new procedure.
  ("/nar/*", "/nar/gzip/*", "/nar/lzip/*", "/nar/zstd/*", "/nar/ with properly
  encoded '+' sign"): use it in these test cases so that the output filename
  doesn't name an already-existing file.

Change-Id: I41f248c13d7af787233afad5cae102056329a68b
Signed-off-by: Ludovic Courtès &lt;ludo@gnu.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Also validate that they are in strictly ascending order, which also ensures
that there are no duplicate names.

When 'guix substitute' fetches a nar, it does so with a validly-signed hash
already known from the narinfo.  But it can't verify that the hash of the nar
it's currently fetching matches until the full nar is downloaded.  Until then,
'download-nar' will extract the nar into the specified destination using
'restore-path', which avoids having to keep a file of unbounded size in
memory.  Critically, this means that the input that 'restore-path' (and by
extension 'fold-archive') is processing is untrusted, since substitute server
TLS certificates aren't verified (the narinfo signatures are supposed to make
it unnecessary).

As such, the scope of harm that can be caused by a malicious nar being
processed by 'restore-file' needs to be minimized.

* guix/serialization.scm (valid-nar-file-name?): new procedure.
  (fold-archive): Use it to verify that directory entry names do not contain
  '/' or '\0', and they are not equal to ".", "..", or "".  Also verify that
  they are in strictly ascending order.
  (call-with-port*): new procedure.
  (dump-file): use O_EXCL and O_NOFOLLOW.  This precaution ensures that even
  if 'restore-file' is somehow tricked into writing to a symlink (not
  currently believed to be possible), it will result in an error.
* guix/store/deduplication.scm (call-with-fresh-output-file): new procedure.
  (dump-file/deduplicate): use it for similar reasons as 'dump-file'.
* tests/nar.scm (call-with-tree-port, port-bad-nar?): new procedures.
  ("write-file-tree + fold-archive, unsorted directory entries",
   "write-file-tree + fold-archive, duplicate directory entries",
   "write-file-tree + fold-archive, invalid directory entries"): new tests.
* tests/publish.scm (call-with-temporary-output-filename): new procedure.
  ("/nar/*", "/nar/gzip/*", "/nar/lzip/*", "/nar/zstd/*", "/nar/ with properly
  encoded '+' sign"): use it in these test cases so that the output filename
  doesn't name an already-existing file.

Change-Id: I41f248c13d7af787233afad5cae102056329a68b
Signed-off-by: Ludovic Courtès &lt;ludo@gnu.org&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>Revert "publish: Prevent publication of non-substitutable derivation outputs."</title>
<updated>2025-09-21T16:47:23+00:00</updated>
<author>
<name>Ludovic Courtès</name>
<email>ludo@gnu.org</email>
</author>
<published>2025-09-21T16:47:23+00:00</published>
<link rel='alternate' type='text/html' href='https://git.vineetk.net/guix/commit/?id=e1cf791ddd0e27265a163592fd3644ba84805fee'/>
<id>e1cf791ddd0e27265a163592fd3644ba84805fee</id>
<content type='text'>
Fixes guix/guix#2450.

This reverts commit b5745a327e8dae21caaf10b59256dc7b16d54588, which introduced
discrepancies in how substitutes are served; in particular, narinfos of
non-substitutable items would still be served, and likewise for narinfos and
nars of dependents of non-substitutable items.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Fixes guix/guix#2450.

This reverts commit b5745a327e8dae21caaf10b59256dc7b16d54588, which introduced
discrepancies in how substitutes are served; in particular, narinfos of
non-substitutable items would still be served, and likewise for narinfos and
nars of dependents of non-substitutable items.
</pre>
</div>
</content>
</entry>
<entry>
<title>publish: Prevent publication of non-substitutable derivation outputs.</title>
<updated>2025-06-06T16:41:19+00:00</updated>
<author>
<name>Morgan Arnold</name>
<email>morgan.arnold@proton.me</email>
</author>
<published>2025-03-06T10:16:29+00:00</published>
<link rel='alternate' type='text/html' href='https://git.vineetk.net/guix/commit/?id=b5745a327e8dae21caaf10b59256dc7b16d54588'/>
<id>b5745a327e8dae21caaf10b59256dc7b16d54588</id>
<content type='text'>
This commit prevents Guix substitute servers from distributing binaries
which are marked non-substitutable.  This prevents substitute servers
from accidentally committing copyright violations by distributing
binaries that are non-substitutable for copyright reasons.

* guix/scripts/publish.scm (render-nar): Query the derivers of
‘store-path’ and do nothing if one of them does not match
‘substitutable-derivation?’.
* tests/publish.scm ("non-substitutable derivation"): New test.

Change-Id: Iaca81f5bdb430a12a3ad41e9b83e0bcc535af607
Signed-off-by: Ludovic Courtès &lt;ludo@gnu.org&gt;
Modified-by: Ludovic Courtès &lt;ludo@gnu.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
This commit prevents Guix substitute servers from distributing binaries
which are marked non-substitutable.  This prevents substitute servers
from accidentally committing copyright violations by distributing
binaries that are non-substitutable for copyright reasons.

* guix/scripts/publish.scm (render-nar): Query the derivers of
‘store-path’ and do nothing if one of them does not match
‘substitutable-derivation?’.
* tests/publish.scm ("non-substitutable derivation"): New test.

Change-Id: Iaca81f5bdb430a12a3ad41e9b83e0bcc535af607
Signed-off-by: Ludovic Courtès &lt;ludo@gnu.org&gt;
Modified-by: Ludovic Courtès &lt;ludo@gnu.org&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>tests: publish: Constrain guix-publish thread use.</title>
<updated>2025-03-03T20:14:56+00:00</updated>
<author>
<name>Christopher Baines</name>
<email>mail@cbaines.net</email>
</author>
<published>2025-03-03T19:52:04+00:00</published>
<link rel='alternate' type='text/html' href='https://git.vineetk.net/guix/commit/?id=5058b40aba825ab6e7b9e518dd1147d1e35fd7de'/>
<id>5058b40aba825ab6e7b9e518dd1147d1e35fd7de</id>
<content type='text'>
On systems with more than 64 processors. Otherwise starting so many threads
during the test will trip resource limits and lead to a spurious failure with
SIGABRT.

I'm seeing this on a 128 core system running Guix, and limiting to just 64
processors seems sufficient.

* tests/publish.scm: Call setaffinity when the current processor count exceeds
64.

Change-Id: Id4c6d7dcc9ae8dd8dafa2587def98f538061425c
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
On systems with more than 64 processors. Otherwise starting so many threads
during the test will trip resource limits and lead to a spurious failure with
SIGABRT.

I'm seeing this on a 128 core system running Guix, and limiting to just 64
processors seems sufficient.

* tests/publish.scm: Call setaffinity when the current processor count exceeds
64.

Change-Id: Id4c6d7dcc9ae8dd8dafa2587def98f538061425c
</pre>
</div>
</content>
</entry>
<entry>
<title>utils: Don’t re-export ‘call-with-temporary-output-file’.</title>
<updated>2024-04-15T20:36:42+00:00</updated>
<author>
<name>Ludovic Courtès</name>
<email>ludo@gnu.org</email>
</author>
<published>2024-04-01T13:11:40+00:00</published>
<link rel='alternate' type='text/html' href='https://git.vineetk.net/guix/commit/?id=54be7795b5cc2f6cad05f8649121372c9d5af806'/>
<id>54be7795b5cc2f6cad05f8649121372c9d5af806</id>
<content type='text'>
* guix/utils.scm: Remove re-export of ‘call-with-temporary-output-file’.
Autoload a number of modules.
* guix/download.scm, guix/import/hackage.scm,
guix/import/hexpm.scm, guix/import/opam.scm,
guix/import/pypi.scm, tests/cpio.scm, tests/egg.scm,
tests/opam.scm, tests/publish.scm, tests/store-database.scm,
tests/utils.scm: Adjust imports accordingly.

Change-Id: I3f5e94631397996a30be2ea4ff8b50a3371e8ee7
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
* guix/utils.scm: Remove re-export of ‘call-with-temporary-output-file’.
Autoload a number of modules.
* guix/download.scm, guix/import/hackage.scm,
guix/import/hexpm.scm, guix/import/opam.scm,
guix/import/pypi.scm, tests/cpio.scm, tests/egg.scm,
tests/opam.scm, tests/publish.scm, tests/store-database.scm,
tests/utils.scm: Adjust imports accordingly.

Change-Id: I3f5e94631397996a30be2ea4ff8b50a3371e8ee7
</pre>
</div>
</content>
</entry>
<entry>
<title>publish: Send uncached narinfo replies from the main thread.</title>
<updated>2022-04-29T16:07:17+00:00</updated>
<author>
<name>Ludovic Courtès</name>
<email>ludo@gnu.org</email>
</author>
<published>2022-04-29T15:56:30+00:00</published>
<link rel='alternate' type='text/html' href='https://git.vineetk.net/guix/commit/?id=c1719a0adf3fa7611b56ca4d75b3ac8cf5c9c8ac'/>
<id>c1719a0adf3fa7611b56ca4d75b3ac8cf5c9c8ac</id>
<content type='text'>
Fixes &lt;https://issues.guix.gnu.org/54723&gt;.
Reported by Guillaume Le Vaillant &lt;glv@posteo.net&gt;.

Regression introduced in f743f2046be2c5a338ab871ae8666d8f6de7440b.

With commit f743f2046be2c5a338ab871ae8666d8f6de7440b, responses to
pipelined GETs would end up being written concurrently by many threads.
Thus the body of those responses could be interleaved and garbled.

* guix/scripts/publish.scm: Revert
f743f2046be2c5a338ab871ae8666d8f6de7440b.
* tests/publish.scm ("/*.narinfo pipeline"): New test.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Fixes &lt;https://issues.guix.gnu.org/54723&gt;.
Reported by Guillaume Le Vaillant &lt;glv@posteo.net&gt;.

Regression introduced in f743f2046be2c5a338ab871ae8666d8f6de7440b.

With commit f743f2046be2c5a338ab871ae8666d8f6de7440b, responses to
pipelined GETs would end up being written concurrently by many threads.
Thus the body of those responses could be interleaved and garbled.

* guix/scripts/publish.scm: Revert
f743f2046be2c5a338ab871ae8666d8f6de7440b.
* tests/publish.scm ("/*.narinfo pipeline"): New test.
</pre>
</div>
</content>
</entry>
<entry>
<title>publish: Do not sign the URL/Compression/FileSize narinfo fields.</title>
<updated>2022-02-14T10:23:56+00:00</updated>
<author>
<name>Ludovic Courtès</name>
<email>ludo@gnu.org</email>
</author>
<published>2022-02-09T17:36:35+00:00</published>
<link rel='alternate' type='text/html' href='https://git.vineetk.net/guix/commit/?id=6adce1538d2df6fa2d68abc13ae94e2fa826d124'/>
<id>6adce1538d2df6fa2d68abc13ae94e2fa826d124</id>
<content type='text'>
This will allow mirror operators to alter these non-normative bits of a
narinfo without having to resign narinfos.

* guix/scripts/publish.scm (narinfo-string): Remove
URL/Compression/FileSize from BASE-INFO.  Move them after "Signature".
* tests/publish.scm ("/*.narinfo")
("/*.narinfo with properly encoded '+' sign")
("/*.narinfo with lzip + gzip")
("with cache, lzip + gzip"): Adjust accordingly.
* tests/substitute.scm ("query narinfo with signature over relevant subset"):
New test.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
This will allow mirror operators to alter these non-normative bits of a
narinfo without having to resign narinfos.

* guix/scripts/publish.scm (narinfo-string): Remove
URL/Compression/FileSize from BASE-INFO.  Move them after "Signature".
* tests/publish.scm ("/*.narinfo")
("/*.narinfo with properly encoded '+' sign")
("/*.narinfo with lzip + gzip")
("with cache, lzip + gzip"): Adjust accordingly.
* tests/substitute.scm ("query narinfo with signature over relevant subset"):
New test.
</pre>
</div>
</content>
</entry>
<entry>
<title>tests: Adjust to gzip as the default log compression.</title>
<updated>2022-01-19T21:07:54+00:00</updated>
<author>
<name>Ludovic Courtès</name>
<email>ludo@gnu.org</email>
</author>
<published>2022-01-19T18:06:57+00:00</published>
<link rel='alternate' type='text/html' href='https://git.vineetk.net/guix/commit/?id=435ffae2f29ecaa94f3aca835d79e222bc1263d5'/>
<id>435ffae2f29ecaa94f3aca835d79e222bc1263d5</id>
<content type='text'>
This is a followup to 575e52ac2b090fd194086e9c1c53bbf8055acbc2.

* tests/publish.scm ("/log/NAME"): Expect a gzip-encoded log.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
This is a followup to 575e52ac2b090fd194086e9c1c53bbf8055acbc2.

* tests/publish.scm ("/log/NAME"): Expect a gzip-encoded log.
</pre>
</div>
</content>
</entry>
<entry>
<title>publish: Add '--negative-ttl'.</title>
<updated>2021-05-16T21:28:11+00:00</updated>
<author>
<name>Ludovic Courtès</name>
<email>ludo@gnu.org</email>
</author>
<published>2021-05-11T13:01:00+00:00</published>
<link rel='alternate' type='text/html' href='https://git.vineetk.net/guix/commit/?id=938ffcbb0589adc07dc12c79eda3e1e2bb9e7cf8'/>
<id>938ffcbb0589adc07dc12c79eda3e1e2bb9e7cf8</id>
<content type='text'>
* guix/scripts/publish.scm (show-help, %options): Add '--negative-ttl'.
(render-narinfo, render-narinfo/cached, make-request-handler): Add #:negative-ttl
and honor it.
(run-publish-server): Add #:narinfo-negative-ttl and honor it.
(guix-publish): Honor '--negative-ttl'.
* tests/publish.scm ("negative TTL", "no negative TTL"): New tests.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
* guix/scripts/publish.scm (show-help, %options): Add '--negative-ttl'.
(render-narinfo, render-narinfo/cached, make-request-handler): Add #:negative-ttl
and honor it.
(run-publish-server): Add #:narinfo-negative-ttl and honor it.
(guix-publish): Honor '--negative-ttl'.
* tests/publish.scm ("negative TTL", "no negative TTL"): New tests.
</pre>
</div>
</content>
</entry>
<entry>
<title>tests: Make 'publish' test umask-insensitive.</title>
<updated>2021-03-31T13:36:48+00:00</updated>
<author>
<name>Cees de Groot</name>
<email>cg@evrl.com</email>
</author>
<published>2021-03-30T15:11:48+00:00</published>
<link rel='alternate' type='text/html' href='https://git.vineetk.net/guix/commit/?id=c536f0b217714917988d2f412999d978c2f2f495'/>
<id>c536f0b217714917988d2f412999d978c2f2f495</id>
<content type='text'>
Fixes &lt;https://bugs.gnu.org/47239&gt;.
Reported by Konrad Hinsen &lt;konrad.hinsen@fastmail.net&gt;.

* tests/publish.scm ("with cache"): Pass the result of 'stat:perms' to
'logand' to be umask-insensitive.

Signed-off-by: Ludovic Courtès &lt;ludo@gnu.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Fixes &lt;https://bugs.gnu.org/47239&gt;.
Reported by Konrad Hinsen &lt;konrad.hinsen@fastmail.net&gt;.

* tests/publish.scm ("with cache"): Pass the result of 'stat:perms' to
'logand' to be umask-insensitive.

Signed-off-by: Ludovic Courtès &lt;ludo@gnu.org&gt;
</pre>
</div>
</content>
</entry>
</feed>
