summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorReepca Russelstein <reepca@russelstein.xyz>2026-06-21 07:28:58 -0500
committerLudovic Courtès <ludo@gnu.org>2026-06-24 15:20:16 +0200
commit247245fbef1923a3bc17a23627e9c016900b4edc (patch)
treeac70e5c649e39ce49b6271e7f30432c1fa50bff4 /tests
parent69b37a8e5d166328fa3d9a7c61b7ca1dfa772552 (diff)
daemon: libstore: reject invalid store paths in importPath.
Previously an authorized substitute server could produce invalid store paths - that is, paths that do denote a top-level file in the store, but that do not obey the syntax restrictions beyond what that implies. Given that an authorized substitute server can already potentially do a lot of damage if it really wanted to, this isn't a major issue, but closing off this opportunity does simplify the analysis somewhat. * nix/libstore/local-store.cc (LocalStore::importPath): use strict readStorePath(s) variants. * tests/store.scm ("import path not in store, unsigned", "import path not in store, signed", "import invalid path, unsigned", "import invalid path, signed" test cases): new test cases. The "not in store" cases succeeded previously, while the "invalid path" cases did not succeed prior to this commit. Fixes: guix/guix#9078 Change-Id: Ib81c19ec1ae0fff5b7c7268f4f7429b16a870996 Signed-off-by: Ludovic Courtès <ludo@gnu.org> Merges: #9434
Diffstat (limited to 'tests')
-rw-r--r--tests/store.scm107
1 files changed, 107 insertions, 0 deletions
diff --git a/tests/store.scm b/tests/store.scm
index 2eb6b778396..a3e67ac7ea4 100644
--- a/tests/store.scm
+++ b/tests/store.scm
@@ -37,7 +37,9 @@
37 #:use-module (guix gexp) 37 #:use-module (guix gexp)
38 #:use-module (gnu packages) 38 #:use-module (gnu packages)
39 #:use-module (gnu packages bootstrap) 39 #:use-module (gnu packages bootstrap)
40 #:use-module (ice-9 binary-ports)
40 #:use-module (ice-9 match) 41 #:use-module (ice-9 match)
42 #:use-module (ice-9 rdelim)
41 #:use-module (ice-9 regex) 43 #:use-module (ice-9 regex)
42 #:use-module (rnrs bytevectors) 44 #:use-module (rnrs bytevectors)
43 #:use-module (rnrs io ports) 45 #:use-module (rnrs io ports)
@@ -1522,6 +1524,111 @@ System: x86_64-linux~%"
1522 (pk 'corrupt-imported imported) 1524 (pk 'corrupt-imported imported)
1523 #f))))) 1525 #f)))))
1524 1526
1527
1528(define* (plain-dump filename contents #:key signed?)
1529 (let* ((contents (if (bytevector? contents)
1530 contents
1531 (string->utf8 contents)))
1532 (item-dump (call-with-bytevector-output-port
1533 (lambda (port)
1534 (call-with-input-bytevector
1535 contents
1536 (lambda (contents-port)
1537 (write-file-tree #t port
1538 #:file-type+size (lambda (_)
1539 (values 'regular
1540 (bytevector-length
1541 contents)))
1542 #:file-port (const contents-port))))
1543 (write-int #x4558494e port) ;%export-magic
1544 (write-string filename port) ;store item
1545 (write-string-list '() port) ;references
1546 (write-string "" port))))) ;deriver
1547 (call-with-bytevector-output-port
1548 (lambda (port)
1549 (write-int 1 port) ;start
1550 (put-bytevector port item-dump)
1551 (write-int (if signed? 1 0) port) ;signed
1552 (when signed?
1553 (let* ((read-canonical-sexp
1554 (compose gcrypt:string->canonical-sexp read-string))
1555 (public-key (call-with-input-file %public-key-file
1556 read-canonical-sexp))
1557 (private-key (call-with-input-file %private-key-file
1558 read-canonical-sexp)))
1559 (write-string (gcrypt:canonical-sexp->string
1560 (signature-sexp
1561 (gcrypt:bytevector->hash-data
1562 (gcrypt:sha256 item-dump)
1563 #:key-type (gcrypt:key-type public-key))
1564 private-key
1565 public-key))
1566 port)))
1567 (write-int 0 port)))))
1568
1569(test-assert "import path not in store, unsigned"
1570 ;; error should be produced before the signature is even considered
1571 (call-with-input-bytevector
1572 (plain-dump (string-append (%store-prefix) "/../../notinstore")
1573 (random-text))
1574 (lambda (port)
1575 (guard (c ((store-protocol-error? c)
1576 (pk 'c c)
1577 (and (not (zero? (store-protocol-error-status c)))
1578 (let ((message (store-protocol-error-message c)))
1579 (pk 'error-message message)
1580 (or (string-contains message "is not a valid store path")
1581 (string-contains message "is not in the store"))))))
1582 (import-paths %store port)
1583 #f))))
1584
1585(test-assert "import path not in store, signed"
1586 (call-with-input-bytevector
1587 (plain-dump (string-append (%store-prefix) "/../../notinstore")
1588 (random-text))
1589 (lambda (port)
1590 (guard (c ((store-protocol-error? c)
1591 (pk 'c c)
1592 (and (not (zero? (store-protocol-error-status c)))
1593 (let ((message (store-protocol-error-message c)))
1594 (pk 'error-message message)
1595 (or (string-contains message "is not a valid store path")
1596 (string-contains message "is not in the store"))))))
1597 (import-paths %store port)
1598 #f))))
1599
1600(test-assert "import invalid path, unsigned"
1601 ;; error should be produced before the signature is even considered
1602 (call-with-input-bytevector
1603 (plain-dump (string-append (%store-prefix)
1604 "/!@#$%^&*()_+=-[]{}\\|';:,<>.")
1605 (random-text))
1606 (lambda (port)
1607 (guard (c ((store-protocol-error? c)
1608 (pk 'c c)
1609 (and (not (zero? (store-protocol-error-status c)))
1610 (let ((message (store-protocol-error-message c)))
1611 (pk 'error-message message)
1612 (string-contains message "is not a valid store path")))))
1613 (import-paths %store port)
1614 #f))))
1615
1616(test-assert "import invalid path, signed"
1617 (call-with-input-bytevector
1618 (plain-dump (string-append (%store-prefix)
1619 "/!@#$%^&*()_+=-[]{}\\|';:,<>.")
1620 (random-text)
1621 #:signed? #t)
1622 (lambda (port)
1623 (guard (c ((store-protocol-error? c)
1624 (pk 'c c)
1625 (and (not (zero? (store-protocol-error-status c)))
1626 (let ((message (store-protocol-error-message c)))
1627 (pk 'error-message message)
1628 (string-contains message "is not a valid store path")))))
1629 (import-paths %store port)
1630 #f))))
1631
1525(test-assert "verify-store" 1632(test-assert "verify-store"
1526 (let* ((text (random-text)) 1633 (let* ((text (random-text))
1527 (file1 (add-text-to-store %store "foo" text)) 1634 (file1 (add-text-to-store %store "foo" text))