From unknown Tue Jul 08 16:23:23 2025 Content-Disposition: inline Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 X-Mailer: MIME-tools 5.509 (Entity 5.509) Content-Type: text/plain; charset=utf-8 From: bug#36699 <36699@debbugs.gnu.org> To: bug#36699 <36699@debbugs.gnu.org> Subject: Status: [PATCH 0/4] Strengthen '.guix-channel' file handling Reply-To: bug#36699 <36699@debbugs.gnu.org> Date: Tue, 08 Jul 2025 23:23:23 +0000 retitle 36699 [PATCH 0/4] Strengthen '.guix-channel' file handling reassign 36699 guix-patches submitter 36699 Ludovic Court=C3=A8s severity 36699 normal tag 36699 patch thanks From debbugs-submit-bounces@debbugs.gnu.org Tue Jul 16 19:20:30 2019 Received: (at submit) by debbugs.gnu.org; 16 Jul 2019 23:20:30 +0000 Received: from localhost ([127.0.0.1]:51291 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hnWkH-0003Mp-UV for submit@debbugs.gnu.org; Tue, 16 Jul 2019 19:20:30 -0400 Received: from lists.gnu.org ([209.51.188.17]:52778) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hnWkD-0003Me-TD for submit@debbugs.gnu.org; Tue, 16 Jul 2019 19:20:26 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:58539) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hnWkD-0005Ez-1S for guix-patches@gnu.org; Tue, 16 Jul 2019 19:20:25 -0400 X-Spam-Checker-Version: SpamAssassin 3.3.2 (2011-06-06) on eggs.gnu.org X-Spam-Level: X-Spam-Status: No, score=-0.2 required=5.0 tests=ALL_TRUSTED,BAYES_50 autolearn=disabled version=3.3.2 Received: from fencepost.gnu.org ([2001:470:142:3::e]:48154) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1hnWkC-0008BC-UL; Tue, 16 Jul 2019 19:20:24 -0400 Received: from [2a01:e0a:1d:7270:af76:b9b:ca24:c465] (port=60140 helo=gnu.org) by fencepost.gnu.org with esmtpsa (TLS1.2:DHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.82) (envelope-from ) id 1hnWkC-0002aV-GB; Tue, 16 Jul 2019 19:20:24 -0400 From: =?UTF-8?q?Ludovic=20Court=C3=A8s?= To: guix-patches@gnu.org Subject: [PATCH 0/4] Strengthen '.guix-channel' file handling Date: Wed, 17 Jul 2019 01:20:16 +0200 Message-Id: <20190716232016.16559-1-ludo@gnu.org> X-Mailer: git-send-email 2.22.0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Spam-Score: -2.3 (--) X-Debbugs-Envelope-To: submit Cc: =?UTF-8?q?Ludovic=20Court=C3=A8s?= X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -3.3 (---) Hello Guix, These patches change ‘.guix-channel’ parsing and handling following the same pattern as /read-manifest/profile-manifest and other places where we deal with serialized data structures. The last patch addresses a potential security issue with the ‘directory’ field of ‘.guix-channel’ that hadn’t occurred to me while reviewing it. Thoughts? Ludo’. Ludovic Courtès (4): channels: Strictly check the version of '.guix-channel'. channels: Remove unneeded 'version' field of . channels: Always provide a record. channels: Reject directories with '..' in '.guix-channel' file. guix/channels.scm | 102 +++++++++++++++++++++++++++++---------------- tests/channels.scm | 81 +++++++++++++++++++++++++---------- 2 files changed, 124 insertions(+), 59 deletions(-) -- 2.22.0 From debbugs-submit-bounces@debbugs.gnu.org Tue Jul 16 19:24:52 2019 Received: (at 36699) by debbugs.gnu.org; 16 Jul 2019 23:24:52 +0000 Received: from localhost ([127.0.0.1]:51298 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hnWoV-0003Te-H8 for submit@debbugs.gnu.org; Tue, 16 Jul 2019 19:24:52 -0400 Received: from eggs.gnu.org ([209.51.188.92]:47534) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hnWoT-0003TD-B0 for 36699@debbugs.gnu.org; Tue, 16 Jul 2019 19:24:49 -0400 Received: from fencepost.gnu.org ([2001:470:142:3::e]:48206) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1hnWoO-0002X3-6H; Tue, 16 Jul 2019 19:24:44 -0400 Received: from [2a01:e0a:1d:7270:af76:b9b:ca24:c465] (port=60146 helo=gnu.org) by fencepost.gnu.org with esmtpsa (TLS1.2:DHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.82) (envelope-from ) id 1hnWoN-0002ms-Gj; Tue, 16 Jul 2019 19:24:44 -0400 From: =?UTF-8?q?Ludovic=20Court=C3=A8s?= To: 36699@debbugs.gnu.org Subject: [PATCH 1/4] channels: Strictly check the version of '.guix-channel'. Date: Wed, 17 Jul 2019 01:24:30 +0200 Message-Id: <20190716232433.16789-1-ludo@gnu.org> X-Mailer: git-send-email 2.22.0 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Spam-Score: -2.3 (--) X-Debbugs-Envelope-To: 36699 Cc: =?UTF-8?q?Ludovic=20Court=C3=A8s?= X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -3.3 (---) Until now the 'version' field in '.guix-channel' could be omitted, or it could be any value. * guix/channels.scm (read-channel-metadata): Rename to... (channel-instance-metadata): ... this. (channel-instance-dependencies): Adjust accordingly. (read-channel-metadata): New procedure. Use 'match' to require a 'version' field. Provide proper error handling when the channel sexp is malformed or when given an unsupported version number. (read-channel-metadata-from-source): Use 'catch' and 'system-error-errno' instead of 'file-exists?'. * tests/channels.scm (instance--unsupported-version): New variable. (read-channel-metadata): Rename to... (channel-instance-metadata): ... this. Rename tests accordingly. ("channel-instance-metadata rejects unsupported version"): New test. --- guix/channels.scm | 69 ++++++++++++++++++++++++++++++---------------- tests/channels.scm | 29 +++++++++++++------ 2 files changed, 67 insertions(+), 31 deletions(-) diff --git a/guix/channels.scm b/guix/channels.scm index bfe6963418..e92148abf2 100644 --- a/guix/channels.scm +++ b/guix/channels.scm @@ -121,32 +121,55 @@ (#f `(branch . ,(channel-branch channel))) (commit `(commit . ,(channel-commit channel))))) +(define (read-channel-metadata port) + "Read from PORT channel metadata in the format expected for the +'.guix-channel' file. Return a record, or raise an error +if valid metadata could not be read from PORT." + (match (read port) + (('channel ('version 0) properties ...) + (let ((directory (and=> (assoc-ref properties 'directory) first)) + (dependencies (or (assoc-ref properties 'dependencies) '()))) + (channel-metadata + version + directory + (map (lambda (item) + (let ((get (lambda* (key #:optional default) + (or (and=> (assoc-ref item key) first) default)))) + (and-let* ((name (get 'name)) + (url (get 'url)) + (branch (get 'branch "master"))) + (channel + (name name) + (branch branch) + (url url) + (commit (get 'commit)))))) + dependencies)))) + ((and ('channel ('version version) _ ...) sexp) + (raise (condition + (&message (message "unsupported '.guix-channel' version")) + (&error-location + (location (source-properties->location + (source-properties sexp))))))) + (sexp + (raise (condition + (&message (message "invalid '.guix-channel' file")) + (&error-location + (location (source-properties->location + (source-properties sexp))))))))) + (define (read-channel-metadata-from-source source) "Return a channel-metadata record read from channel's SOURCE/.guix-channel description file, or return #F if SOURCE/.guix-channel does not exist." - (let ((meta-file (string-append source "/.guix-channel"))) - (and (file-exists? meta-file) - (let* ((raw (call-with-input-file meta-file read)) - (version (and=> (assoc-ref raw 'version) first)) - (directory (and=> (assoc-ref raw 'directory) first)) - (dependencies (or (assoc-ref raw 'dependencies) '()))) - (channel-metadata - version - directory - (map (lambda (item) - (let ((get (lambda* (key #:optional default) - (or (and=> (assoc-ref item key) first) default)))) - (and-let* ((name (get 'name)) - (url (get 'url)) - (branch (get 'branch "master"))) - (channel - (name name) - (branch branch) - (url url) - (commit (get 'commit)))))) - dependencies)))))) + (catch 'system-error + (lambda () + (call-with-input-file (string-append source "/.guix-channel") + read-channel-metadata)) + (lambda args + (if (= ENOENT (system-error-errno args)) + #f + (apply throw args))))) -(define (read-channel-metadata instance) +(define (channel-instance-metadata instance) "Return a channel-metadata record read from the channel INSTANCE's description file, or return #F if the channel instance does not include the file." @@ -155,7 +178,7 @@ file." (define (channel-instance-dependencies instance) "Return the list of channels that are declared as dependencies for the given channel INSTANCE." - (match (read-channel-metadata instance) + (match (channel-instance-metadata instance) (#f '()) (($ version directory dependencies) dependencies))) diff --git a/tests/channels.scm b/tests/channels.scm index 8540aef435..1f1357fca7 100644 --- a/tests/channels.scm +++ b/tests/channels.scm @@ -26,8 +26,12 @@ #:use-module (guix derivations) #:use-module (guix sets) #:use-module (guix gexp) + #:use-module ((guix utils) + #:select (error-location? error-location location-line)) #:use-module (srfi srfi-1) #:use-module (srfi srfi-26) + #:use-module (srfi srfi-34) + #:use-module (srfi srfi-35) #:use-module (srfi srfi-64) #:use-module (ice-9 match)) @@ -46,6 +50,9 @@ #:name name)) (define instance--boring (make-instance)) +(define instance--unsupported-version + (make-instance #:spec + '(channel (version 42) (dependencies whatever)))) (define instance--no-deps (make-instance #:spec '(channel @@ -78,24 +85,30 @@ (name test-channel) (url "https://example.com/test-channel-elsewhere")))))) -(define read-channel-metadata - (@@ (guix channels) read-channel-metadata)) +(define channel-instance-metadata + (@@ (guix channels) channel-instance-metadata)) -(test-equal "read-channel-metadata returns #f if .guix-channel does not exist" +(test-equal "channel-instance-metadata returns #f if .guix-channel does not exist" #f - (read-channel-metadata instance--boring)) + (channel-instance-metadata instance--boring)) -(test-assert "read-channel-metadata returns " +(test-equal "channel-instance-metadata rejects unsupported version" + 1 ;line number in the generated '.guix-channel' + (guard (c ((and (message-condition? c) (error-location? c)) + (location-line (error-location c)))) + (channel-instance-metadata instance--unsupported-version))) + +(test-assert "channel-instance-metadata returns " (every (@@ (guix channels) channel-metadata?) - (map read-channel-metadata + (map channel-instance-metadata (list instance--no-deps instance--simple instance--with-dupes)))) -(test-assert "read-channel-metadata dependencies are channels" +(test-assert "channel-instance-metadata dependencies are channels" (let ((deps ((@@ (guix channels) channel-metadata-dependencies) - (read-channel-metadata instance--simple)))) + (channel-instance-metadata instance--simple)))) (match deps (((? channel? dep)) #t) (_ #f)))) -- 2.22.0 From debbugs-submit-bounces@debbugs.gnu.org Tue Jul 16 19:24:54 2019 Received: (at 36699) by debbugs.gnu.org; 16 Jul 2019 23:24:54 +0000 Received: from localhost ([127.0.0.1]:51301 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hnWoY-0003Ty-5X for submit@debbugs.gnu.org; Tue, 16 Jul 2019 19:24:54 -0400 Received: from eggs.gnu.org ([209.51.188.92]:47542) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hnWoU-0003TF-Il for 36699@debbugs.gnu.org; Tue, 16 Jul 2019 19:24:50 -0400 Received: from fencepost.gnu.org ([2001:470:142:3::e]:48207) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1hnWoP-0002XR-4i; Tue, 16 Jul 2019 19:24:45 -0400 Received: from [2a01:e0a:1d:7270:af76:b9b:ca24:c465] (port=60146 helo=gnu.org) by fencepost.gnu.org with esmtpsa (TLS1.2:DHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.82) (envelope-from ) id 1hnWoO-0002ms-I2; Tue, 16 Jul 2019 19:24:44 -0400 From: =?UTF-8?q?Ludovic=20Court=C3=A8s?= To: 36699@debbugs.gnu.org Subject: [PATCH 2/4] channels: Remove unneeded 'version' field of . Date: Wed, 17 Jul 2019 01:24:31 +0200 Message-Id: <20190716232433.16789-2-ludo@gnu.org> X-Mailer: git-send-email 2.22.0 In-Reply-To: <20190716232433.16789-1-ludo@gnu.org> References: <20190716232433.16789-1-ludo@gnu.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Spam-Score: -2.3 (--) X-Debbugs-Envelope-To: 36699 Cc: =?UTF-8?q?Ludovic=20Court=C3=A8s?= X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -3.3 (---) The idea is that 'read-channel-metadata' will take care of converting possibly older versions to the current data type. Thus, storing the version number is unnecessary. * guix/channels.scm ()[version]: Remove. (read-channel-metadata, channel-instance-dependencies): Adjust accordingly. --- guix/channels.scm | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/guix/channels.scm b/guix/channels.scm index e92148abf2..87ad729a70 100644 --- a/guix/channels.scm +++ b/guix/channels.scm @@ -108,9 +108,8 @@ (checkout channel-instance-checkout)) (define-record-type - (channel-metadata version directory dependencies) + (channel-metadata directory dependencies) channel-metadata? - (version channel-metadata-version) (directory channel-metadata-directory) (dependencies channel-metadata-dependencies)) @@ -130,7 +129,6 @@ if valid metadata could not be read from PORT." (let ((directory (and=> (assoc-ref properties 'directory) first)) (dependencies (or (assoc-ref properties 'dependencies) '()))) (channel-metadata - version directory (map (lambda (item) (let ((get (lambda* (key #:optional default) @@ -180,7 +178,7 @@ file." channel INSTANCE." (match (channel-instance-metadata instance) (#f '()) - (($ version directory dependencies) + (($ directory dependencies) dependencies))) (define* (latest-channel-instances store channels #:optional (previous-channels '())) -- 2.22.0 From debbugs-submit-bounces@debbugs.gnu.org Tue Jul 16 19:24:54 2019 Received: (at 36699) by debbugs.gnu.org; 16 Jul 2019 23:24:55 +0000 Received: from localhost ([127.0.0.1]:51303 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hnWoY-0003U0-EV for submit@debbugs.gnu.org; Tue, 16 Jul 2019 19:24:54 -0400 Received: from eggs.gnu.org ([209.51.188.92]:47544) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hnWoV-0003TI-Bw for 36699@debbugs.gnu.org; Tue, 16 Jul 2019 19:24:51 -0400 Received: from fencepost.gnu.org ([2001:470:142:3::e]:48208) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1hnWoQ-0002Xn-1I; Tue, 16 Jul 2019 19:24:46 -0400 Received: from [2a01:e0a:1d:7270:af76:b9b:ca24:c465] (port=60146 helo=gnu.org) by fencepost.gnu.org with esmtpsa (TLS1.2:DHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.82) (envelope-from ) id 1hnWoP-0002ms-Gk; Tue, 16 Jul 2019 19:24:45 -0400 From: =?UTF-8?q?Ludovic=20Court=C3=A8s?= To: 36699@debbugs.gnu.org Subject: [PATCH 3/4] channels: Always provide a record. Date: Wed, 17 Jul 2019 01:24:32 +0200 Message-Id: <20190716232433.16789-3-ludo@gnu.org> X-Mailer: git-send-email 2.22.0 In-Reply-To: <20190716232433.16789-1-ludo@gnu.org> References: <20190716232433.16789-1-ludo@gnu.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Spam-Score: -2.3 (--) X-Debbugs-Envelope-To: 36699 Cc: =?UTF-8?q?Ludovic=20Court=C3=A8s?= X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -3.3 (---) This simplifies the code since one no longer needs to think about whether '.guix-channel' was present. * guix/channels.scm (read-channel-metadata): Always pass a string as the first argument to 'channel-metadata'. (read-channel-metadata-from-source): Always return a record. (channel-instance-dependencies): Remove now unneeded 'match'. (standard-module-derivation): Assume DIRECTORY is never #f and contains a leading slash. * tests/channels.scm (channel-metadata-directory) (channel-metadata-dependencies): New procedures. ("channel-instance-metadata returns #f if .guix-channel does not exist"): Remove. ("channel-instance-metadata returns default if .guix-channel does not exist"): New test. (make-instance): Use 'write' instead of 'display' when creating '.guix-channel'. (instance--no-deps): Remove dependencies. (instance--sub-directory): New variable. ("channel-instance-metadata and default dependencies") ("channel-instance-metadata and directory"): New tests. ("latest-channel-instances excludes duplicate channel dependencies"): Expect 'channel-commit' to return a string and adjust accordingly. --- guix/channels.scm | 27 ++++++++++++--------------- tests/channels.scm | 45 +++++++++++++++++++++++++++++---------------- 2 files changed, 41 insertions(+), 31 deletions(-) diff --git a/guix/channels.scm b/guix/channels.scm index 87ad729a70..415246cbd1 100644 --- a/guix/channels.scm +++ b/guix/channels.scm @@ -110,8 +110,8 @@ (define-record-type (channel-metadata directory dependencies) channel-metadata? - (directory channel-metadata-directory) - (dependencies channel-metadata-dependencies)) + (directory channel-metadata-directory) ;string with leading slash + (dependencies channel-metadata-dependencies)) ;list of (define (channel-reference channel) "Return the \"reference\" for CHANNEL, an sexp suitable for @@ -129,7 +129,9 @@ if valid metadata could not be read from PORT." (let ((directory (and=> (assoc-ref properties 'directory) first)) (dependencies (or (assoc-ref properties 'dependencies) '()))) (channel-metadata - directory + (cond ((not directory) "/") + ((string-prefix? "/" directory) directory) + (else (string-append "/" directory))) (map (lambda (item) (let ((get (lambda* (key #:optional default) (or (and=> (assoc-ref item key) first) default)))) @@ -157,29 +159,26 @@ if valid metadata could not be read from PORT." (define (read-channel-metadata-from-source source) "Return a channel-metadata record read from channel's SOURCE/.guix-channel -description file, or return #F if SOURCE/.guix-channel does not exist." +description file, or return the default channel-metadata record if that file +doesn't exist." (catch 'system-error (lambda () (call-with-input-file (string-append source "/.guix-channel") read-channel-metadata)) (lambda args (if (= ENOENT (system-error-errno args)) - #f + (channel-metadata "/" '()) (apply throw args))))) (define (channel-instance-metadata instance) "Return a channel-metadata record read from the channel INSTANCE's -description file, or return #F if the channel instance does not include the -file." +description file or its default value." (read-channel-metadata-from-source (channel-instance-checkout instance))) (define (channel-instance-dependencies instance) "Return the list of channels that are declared as dependencies for the given channel INSTANCE." - (match (channel-instance-metadata instance) - (#f '()) - (($ directory dependencies) - dependencies))) + (channel-metadata-dependencies (channel-instance-metadata instance))) (define* (latest-channel-instances store channels #:optional (previous-channels '())) "Return a list of channel instances corresponding to the latest checkouts of @@ -261,7 +260,7 @@ objects. The assumption is that SOURCE contains package modules to be added to '%package-module-path'." (let* ((metadata (read-channel-metadata-from-source source)) - (directory (and=> metadata channel-metadata-directory))) + (directory (channel-metadata-directory metadata))) (define build ;; This is code that we'll run in CORE, a Guix instance, with its own @@ -281,9 +280,7 @@ to '%package-module-path'." (string-append #$output "/share/guile/site/" (effective-version))) - (let* ((subdir (if #$directory - (string-append "/" #$directory) - "")) + (let* ((subdir #$directory) (source (string-append #$source subdir))) (compile-files source go (find-files source "\\.scm$")) (mkdir-p (dirname scm)) diff --git a/tests/channels.scm b/tests/channels.scm index 1f1357fca7..e83b5437d3 100644 --- a/tests/channels.scm +++ b/tests/channels.scm @@ -42,9 +42,9 @@ (commit "cafebabe") (spec #f)) (define instance-dir (mkdtemp! "/tmp/checkout.XXXXXX")) - (and spec - (with-output-to-file (string-append instance-dir "/.guix-channel") - (lambda _ (format #t "~a" spec)))) + (when spec + (call-with-output-file (string-append instance-dir "/.guix-channel") + (lambda (port) (write spec port)))) (checkout->channel-instance instance-dir #:commit commit #:name name)) @@ -55,12 +55,10 @@ '(channel (version 42) (dependencies whatever)))) (define instance--no-deps (make-instance #:spec - '(channel - (version 0) - (dependencies - (channel - (name test-channel) - (url "https://example.com/test-channel")))))) + '(channel (version 0)))) +(define instance--sub-directory + (make-instance #:spec + '(channel (version 0) (directory "modules")))) (define instance--simple (make-instance #:spec '(channel @@ -87,11 +85,26 @@ (define channel-instance-metadata (@@ (guix channels) channel-instance-metadata)) +(define channel-metadata-directory + (@@ (guix channels) channel-metadata-directory)) +(define channel-metadata-dependencies + (@@ (guix channels) channel-metadata-dependencies)) -(test-equal "channel-instance-metadata returns #f if .guix-channel does not exist" - #f - (channel-instance-metadata instance--boring)) +(test-equal "channel-instance-metadata returns default if .guix-channel does not exist" + '("/" ()) + (let ((metadata (channel-instance-metadata instance--boring))) + (list (channel-metadata-directory metadata) + (channel-metadata-dependencies metadata)))) + +(test-equal "channel-instance-metadata and default dependencies" + '() + (channel-metadata-dependencies (channel-instance-metadata instance--no-deps))) + +(test-equal "channel-instance-metadata and directory" + "/modules" + (channel-metadata-directory + (channel-instance-metadata instance--sub-directory))) (test-equal "channel-instance-metadata rejects unsupported version" 1 ;line number in the generated '.guix-channel' @@ -141,7 +154,7 @@ ("test" (values test-dir 'whatever)) (_ (values "/not-important" 'not-important))))) (let ((instances (latest-channel-instances #f (list channel)))) - (and (eq? 2 (length instances)) + (and (= 2 (length instances)) (lset= eq? '(test test-channel) (map (compose channel-name channel-instance-channel) @@ -152,9 +165,9 @@ (and (eq? (channel-name (channel-instance-channel instance)) 'test-channel) - (eq? (channel-commit - (channel-instance-channel instance)) - 'abc1234))) + (string=? (channel-commit + (channel-instance-channel instance)) + "abc1234"))) instances)))))) (test-assert "channel-instances->manifest" -- 2.22.0 From debbugs-submit-bounces@debbugs.gnu.org Tue Jul 16 19:24:59 2019 Received: (at 36699) by debbugs.gnu.org; 16 Jul 2019 23:24:59 +0000 Received: from localhost ([127.0.0.1]:51305 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hnWoc-0003UH-UZ for submit@debbugs.gnu.org; Tue, 16 Jul 2019 19:24:59 -0400 Received: from eggs.gnu.org ([209.51.188.92]:47551) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hnWoX-0003TN-I9 for 36699@debbugs.gnu.org; Tue, 16 Jul 2019 19:24:53 -0400 Received: from fencepost.gnu.org ([2001:470:142:3::e]:48209) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1hnWoR-0002Y8-8p; Tue, 16 Jul 2019 19:24:48 -0400 Received: from [2a01:e0a:1d:7270:af76:b9b:ca24:c465] (port=60146 helo=gnu.org) by fencepost.gnu.org with esmtpsa (TLS1.2:DHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.82) (envelope-from ) id 1hnWoQ-0002ms-DD; Tue, 16 Jul 2019 19:24:46 -0400 From: =?UTF-8?q?Ludovic=20Court=C3=A8s?= To: 36699@debbugs.gnu.org Subject: [PATCH 4/4] channels: Reject directories with '..' in '.guix-channel' file. Date: Wed, 17 Jul 2019 01:24:33 +0200 Message-Id: <20190716232433.16789-4-ludo@gnu.org> X-Mailer: git-send-email 2.22.0 In-Reply-To: <20190716232433.16789-1-ludo@gnu.org> References: <20190716232433.16789-1-ludo@gnu.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Spam-Score: -2.3 (--) X-Debbugs-Envelope-To: 36699 Cc: =?UTF-8?q?Ludovic=20Court=C3=A8s?= X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -3.3 (---) * guix/channels.scm (read-channel-metadata)[sexp, location]: New variables. [sane-directory]: New procedure. Call it when DIRECTORY is true. * tests/channels.scm (instance--fishy-directory): New variable. ("channel-instance-metadata and fishy directory"): New test. --- guix/channels.scm | 30 ++++++++++++++++++++---------- tests/channels.scm | 11 +++++++++++ 2 files changed, 31 insertions(+), 10 deletions(-) diff --git a/guix/channels.scm b/guix/channels.scm index 415246cbd1..641dee8dbb 100644 --- a/guix/channels.scm +++ b/guix/channels.scm @@ -124,14 +124,28 @@ "Read from PORT channel metadata in the format expected for the '.guix-channel' file. Return a record, or raise an error if valid metadata could not be read from PORT." - (match (read port) + (define sexp + (read port)) + + (define location + (source-properties->location (source-properties sexp))) + + (define (sane-directory directory) + ;; If DIRECTORY contains '..', raise an error; otherwise return it. + (when (member ".." (string-split directory #\/)) + (raise (condition + (&message (message "channel sub-directory must not contain '..'")) + (&error-location (location location))))) + directory) + + (match sexp (('channel ('version 0) properties ...) (let ((directory (and=> (assoc-ref properties 'directory) first)) (dependencies (or (assoc-ref properties 'dependencies) '()))) (channel-metadata (cond ((not directory) "/") - ((string-prefix? "/" directory) directory) - (else (string-append "/" directory))) + ((string-prefix? "/" directory) (sane-directory directory)) + (else (string-append "/" (sane-directory directory)))) (map (lambda (item) (let ((get (lambda* (key #:optional default) (or (and=> (assoc-ref item key) first) default)))) @@ -144,18 +158,14 @@ if valid metadata could not be read from PORT." (url url) (commit (get 'commit)))))) dependencies)))) - ((and ('channel ('version version) _ ...) sexp) + (('channel ('version version) _ ...) (raise (condition (&message (message "unsupported '.guix-channel' version")) - (&error-location - (location (source-properties->location - (source-properties sexp))))))) + (&error-location (location location))))) (sexp (raise (condition (&message (message "invalid '.guix-channel' file")) - (&error-location - (location (source-properties->location - (source-properties sexp))))))))) + (&error-location (location location))))))) (define (read-channel-metadata-from-source source) "Return a channel-metadata record read from channel's SOURCE/.guix-channel diff --git a/tests/channels.scm b/tests/channels.scm index e83b5437d3..402025dea3 100644 --- a/tests/channels.scm +++ b/tests/channels.scm @@ -59,6 +59,11 @@ (define instance--sub-directory (make-instance #:spec '(channel (version 0) (directory "modules")))) +(define instance--fishy-directory + (make-instance #:spec + '(channel (version 0) + (directory "../../../../../etc")))) + (define instance--simple (make-instance #:spec '(channel @@ -106,6 +111,12 @@ (channel-metadata-directory (channel-instance-metadata instance--sub-directory))) +(test-assert "channel-instance-metadata and fishy directory" + (guard (c ((and (message-condition? c) (error-location? c)) + #t)) + (channel-instance-metadata instance--fishy-directory) + #f)) + (test-equal "channel-instance-metadata rejects unsupported version" 1 ;line number in the generated '.guix-channel' (guard (c ((and (message-condition? c) (error-location? c)) -- 2.22.0 From debbugs-submit-bounces@debbugs.gnu.org Tue Jul 16 19:29:49 2019 Received: (at 36699) by debbugs.gnu.org; 16 Jul 2019 23:29:49 +0000 Received: from localhost ([127.0.0.1]:51312 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hnWtI-0003bO-M4 for submit@debbugs.gnu.org; Tue, 16 Jul 2019 19:29:48 -0400 Received: from eggs.gnu.org ([209.51.188.92]:48755) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hnWtG-0003bA-P4 for 36699@debbugs.gnu.org; Tue, 16 Jul 2019 19:29:47 -0400 Received: from fencepost.gnu.org ([2001:470:142:3::e]:48243) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1hnWtB-0004fU-Ke for 36699@debbugs.gnu.org; Tue, 16 Jul 2019 19:29:41 -0400 Received: from [2a01:e0a:1d:7270:af76:b9b:ca24:c465] (port=60150 helo=ribbon) by fencepost.gnu.org with esmtpsa (TLS1.2:RSA_AES_256_CBC_SHA1:256) (Exim 4.82) (envelope-from ) id 1hnWtB-0002fW-5a for 36699@debbugs.gnu.org; Tue, 16 Jul 2019 19:29:41 -0400 From: =?utf-8?Q?Ludovic_Court=C3=A8s?= To: 36699@debbugs.gnu.org Subject: Re: [bug#36699] [PATCH 4/4] channels: Reject directories with '..' in '.guix-channel' file. References: <20190716232433.16789-1-ludo@gnu.org> <20190716232433.16789-4-ludo@gnu.org> Date: Wed, 17 Jul 2019 01:29:39 +0200 In-Reply-To: <20190716232433.16789-4-ludo@gnu.org> ("Ludovic \=\?utf-8\?Q\?Cou\?\= \=\?utf-8\?Q\?rt\=C3\=A8s\=22's\?\= message of "Wed, 17 Jul 2019 01:24:33 +0200") Message-ID: <87blxteexo.fsf@gnu.org> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/26.2 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Spam-Score: -2.3 (--) X-Debbugs-Envelope-To: 36699 X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -3.3 (---) Ludovic Court=C3=A8s skribis: > + (define (sane-directory directory) > + ;; If DIRECTORY contains '..', raise an error; otherwise return it. > + (when (member ".." (string-split directory #\/)) > + (raise (condition > + (&message (message "channel sub-directory must not contain= '..'")) > + (&error-location (location location))))) > + directory) On second thought, it=E2=80=99s probably kind of useless since the only pla= ce where =E2=80=98directory=E2=80=99 is used is in the derivation that builds = the channel, which is normally running in a chroot: (let* ((subdir #$directory) (source (string-append #$source subdir))) (compile-files source go (find-files source "\\.scm$")) (mkdir-p (dirname scm)) (symlink (string-append #$source subdir) scm)) So I guess we can drop this patch. Thoughts? Ludo=E2=80=99. From debbugs-submit-bounces@debbugs.gnu.org Thu Jul 18 05:58:52 2019 Received: (at 36699) by debbugs.gnu.org; 18 Jul 2019 09:58:52 +0000 Received: from localhost ([127.0.0.1]:53464 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1ho3Bc-0007zk-JW for submit@debbugs.gnu.org; Thu, 18 Jul 2019 05:58:52 -0400 Received: from dd26836.kasserver.com ([85.13.145.193]:33436) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1ho3Bb-0007zb-7K for 36699@debbugs.gnu.org; Thu, 18 Jul 2019 05:58:51 -0400 Received: from localhost (178.112.215.129.wireless.dyn.drei.com [178.112.215.129]) by dd26836.kasserver.com (Postfix) with ESMTPSA id 6C7A33362146; Thu, 18 Jul 2019 11:58:48 +0200 (CEST) Date: Thu, 18 Jul 2019 11:58:41 +0200 From: Danny Milosavljevic To: Ludovic =?ISO-8859-1?Q?Court=E8s?= Subject: Re: [bug#36699] [PATCH 4/4] channels: Reject directories with '..' in '.guix-channel' file. Message-ID: <20190718115841.4660810e@scratchpost.org> In-Reply-To: <87blxteexo.fsf@gnu.org> References: <20190716232433.16789-1-ludo@gnu.org> <20190716232433.16789-4-ludo@gnu.org> <87blxteexo.fsf@gnu.org> X-Mailer: Claws Mail 3.17.3 (GTK+ 2.24.32; x86_64-unknown-linux-gnu) MIME-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha256; boundary="Sig_/MGOSEpI4f6EAaGvk3JgQtdu"; protocol="application/pgp-signature" X-Spam-Score: -0.7 (/) X-Debbugs-Envelope-To: 36699 Cc: 36699@debbugs.gnu.org X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.7 (-) --Sig_/MGOSEpI4f6EAaGvk3JgQtdu Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Hi Ludo, On Wed, 17 Jul 2019 01:29:39 +0200 Ludovic Court=C3=A8s wrote: > Ludovic Court=C3=A8s skribis: >=20 > > + (define (sane-directory directory) > > + ;; If DIRECTORY contains '..', raise an error; otherwise return it. > > + (when (member ".." (string-split directory #\/)) > > + (raise (condition > > + (&message (message "channel sub-directory must not conta= in '..'")) > > + (&error-location (location location))))) > > + directory) =20 >=20 > On second thought, it=E2=80=99s probably kind of useless since the only p= lace > where =E2=80=98directory=E2=80=99 is used is in the derivation that build= s the channel, > which is normally running in a chroot: >=20 > (let* ((subdir #$directory) > (source (string-append #$source subdir))) > (compile-files source go (find-files source "\\.scm$")) > (mkdir-p (dirname scm)) > (symlink (string-append #$source subdir) scm)) >=20 > So I guess we can drop this patch. Thoughts? I generally don't like weird name matching like this. The Linux VFS can do arbitrary things (which would complicate the situation) to the name tree. Even now, a symlink "x" to ".." would work and not be caught. To say nothi= ng of what a custom file system could do. Why single out this one way? It gives the illusion of security. Containers are better indeed. Except when the match is not for security but only for usability, then I'm fine with it (and then it should be a warning - who knows, maybe ".." means "current directory" in WeirdFS :->). --Sig_/MGOSEpI4f6EAaGvk3JgQtdu Content-Type: application/pgp-signature Content-Description: OpenPGP digital signature -----BEGIN PGP SIGNATURE----- iQEzBAEBCAAdFiEEds7GsXJ0tGXALbPZ5xo1VCwwuqUFAl0wQtEACgkQ5xo1VCww uqWg0QgAhVfIyJlqI4znAGOP/qL1WPq+YD2w7ovjbj/PkwxT8Uf/msQmfakk+GI1 PvTZU/B0IlR1QIkn6ZUbumRSuCBXTw8oWX2VBjEUKSGHDWrrTWeYQiGGSa2tgtrQ KiDeoDg+nvi6aLTvdk96rnKd8cZvXT40AyFo9L04lUuZm2sXgl+0k9uOk7SJVFcK KL+5N/St1fbz/PLmrgHRTtBuOb3VZ3vnOUdqJgq22LB1a3kchlj/SkK6MTQfM7Ru LQ917d9erzeDavj88XVX8foUh6kjZozwpGFieKERSVD1Z7mcSJeqSZKKT9Y62mGT L6yEbw7sJAaHQTauKb755G+sra5yGQ== =mgSM -----END PGP SIGNATURE----- --Sig_/MGOSEpI4f6EAaGvk3JgQtdu-- From debbugs-submit-bounces@debbugs.gnu.org Thu Jul 18 09:44:48 2019 Received: (at 36699) by debbugs.gnu.org; 18 Jul 2019 13:44:48 +0000 Received: from localhost ([127.0.0.1]:53634 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1ho6iF-0000xq-UI for submit@debbugs.gnu.org; Thu, 18 Jul 2019 09:44:48 -0400 Received: from eggs.gnu.org ([209.51.188.92]:54552) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1ho6iE-0000xc-7A for 36699@debbugs.gnu.org; Thu, 18 Jul 2019 09:44:46 -0400 Received: from fencepost.gnu.org ([2001:470:142:3::e]:55928) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ho6i8-000164-8x; Thu, 18 Jul 2019 09:44:40 -0400 Received: from [2001:660:6102:320:e120:2c8f:8909:cdfe] (port=42774 helo=ribbon) by fencepost.gnu.org with esmtpsa (TLS1.2:RSA_AES_256_CBC_SHA1:256) (Exim 4.82) (envelope-from ) id 1ho6i7-0006Dg-Rk; Thu, 18 Jul 2019 09:44:40 -0400 From: =?utf-8?Q?Ludovic_Court=C3=A8s?= To: Danny Milosavljevic Subject: Re: [bug#36699] [PATCH 4/4] channels: Reject directories with '..' in '.guix-channel' file. References: <20190716232433.16789-1-ludo@gnu.org> <20190716232433.16789-4-ludo@gnu.org> <87blxteexo.fsf@gnu.org> <20190718115841.4660810e@scratchpost.org> X-URL: http://www.fdn.fr/~lcourtes/ X-Revolutionary-Date: 30 Messidor an 227 de la =?utf-8?Q?R=C3=A9volution?= X-PGP-Key-ID: 0x090B11993D9AEBB5 X-PGP-Key: http://www.fdn.fr/~lcourtes/ludovic.asc X-PGP-Fingerprint: 3CE4 6455 8A84 FDC6 9DB4 0CFB 090B 1199 3D9A EBB5 X-OS: x86_64-pc-linux-gnu Date: Thu, 18 Jul 2019 15:44:36 +0200 In-Reply-To: <20190718115841.4660810e@scratchpost.org> (Danny Milosavljevic's message of "Thu, 18 Jul 2019 11:58:41 +0200") Message-ID: <875znzfoe3.fsf@gnu.org> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/26.2 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Spam-Score: -2.3 (--) X-Debbugs-Envelope-To: 36699 Cc: 36699@debbugs.gnu.org X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -3.3 (---) Hi, Danny Milosavljevic skribis: > On Wed, 17 Jul 2019 01:29:39 +0200 > Ludovic Court=C3=A8s wrote: > >> Ludovic Court=C3=A8s skribis: >>=20 >> > + (define (sane-directory directory) >> > + ;; If DIRECTORY contains '..', raise an error; otherwise return i= t. >> > + (when (member ".." (string-split directory #\/)) >> > + (raise (condition >> > + (&message (message "channel sub-directory must not cont= ain '..'")) >> > + (&error-location (location location))))) >> > + directory)=20=20 >>=20 >> On second thought, it=E2=80=99s probably kind of useless since the only = place >> where =E2=80=98directory=E2=80=99 is used is in the derivation that buil= ds the channel, >> which is normally running in a chroot: >>=20 >> (let* ((subdir #$directory) >> (source (string-append #$source subdir))) >> (compile-files source go (find-files source "\\.scm$")) >> (mkdir-p (dirname scm)) >> (symlink (string-append #$source subdir) scm)) >>=20 >> So I guess we can drop this patch. Thoughts? > > I generally don't like weird name matching like this. The Linux VFS can = do > arbitrary things (which would complicate the situation) to the name tree. > Even now, a symlink "x" to ".." would work and not be caught. To say not= hing > of what a custom file system could do. > > Why single out this one way? It gives the illusion of security. > > Containers are better indeed. Yes, and since that=E2=80=99s what we have, we can forget about this patch. I definitely agree with everything you wrote; it=E2=80=99s just that the ke= rnel Linux being what it is, one sometimes have to resort to hacks like this. Fortunately, that was misguided here, so let=E2=80=99s forget about this. = :-) Ludo=E2=80=99. From debbugs-submit-bounces@debbugs.gnu.org Fri Jul 19 05:55:01 2019 Received: (at 36699-done) by debbugs.gnu.org; 19 Jul 2019 09:55:01 +0000 Received: from localhost ([127.0.0.1]:55143 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hoPbR-0007D0-Ce for submit@debbugs.gnu.org; Fri, 19 Jul 2019 05:55:01 -0400 Received: from eggs.gnu.org ([209.51.188.92]:60934) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hoPbN-0007Cj-GW for 36699-done@debbugs.gnu.org; Fri, 19 Jul 2019 05:54:57 -0400 Received: from fencepost.gnu.org ([2001:470:142:3::e]:47014) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1hoPbI-0005bY-8E for 36699-done@debbugs.gnu.org; Fri, 19 Jul 2019 05:54:52 -0400 Received: from [2001:660:6102:320:e120:2c8f:8909:cdfe] (port=60334 helo=ribbon) by fencepost.gnu.org with esmtpsa (TLS1.2:RSA_AES_256_CBC_SHA1:256) (Exim 4.82) (envelope-from ) id 1hoPbH-000509-S9 for 36699-done@debbugs.gnu.org; Fri, 19 Jul 2019 05:54:52 -0400 From: =?utf-8?Q?Ludovic_Court=C3=A8s?= To: 36699-done@debbugs.gnu.org Subject: Re: [bug#36699] [PATCH 0/4] Strengthen '.guix-channel' file handling References: <20190716232016.16559-1-ludo@gnu.org> Date: Fri, 19 Jul 2019 11:54:49 +0200 In-Reply-To: <20190716232016.16559-1-ludo@gnu.org> ("Ludovic \=\?utf-8\?Q\?Cou\?\= \=\?utf-8\?Q\?rt\=C3\=A8s\=22's\?\= message of "Wed, 17 Jul 2019 01:20:16 +0200") Message-ID: <87h87ie4d2.fsf@gnu.org> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/26.2 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Spam-Score: -2.3 (--) X-Debbugs-Envelope-To: 36699-done X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -3.3 (---) Hello, Ludovic Court=C3=A8s skribis: > Ludovic Court=C3=A8s (4): > channels: Strictly check the version of '.guix-channel'. > channels: Remove unneeded 'version' field of . > channels: Always provide a record. > channels: Reject directories with '..' in '.guix-channel' file. I pushed the first three patches and discarded the last one, as discussed with Danny. Ludo=E2=80=99. From unknown Tue Jul 08 16:23:23 2025 Received: (at fakecontrol) by fakecontrolmessage; To: internal_control@debbugs.gnu.org From: Debbugs Internal Request Subject: Internal Control Message-Id: bug archived. Date: Fri, 16 Aug 2019 11:24:09 +0000 User-Agent: Fakemail v42.6.9 # This is a fake control message. # # The action: # bug archived. thanks # This fakemail brought to you by your local debbugs # administrator