me
/
guix
Archived
1
0
Fork 0

pull: Protect against downgrade attacks.

* guix/scripts/pull.scm (%default-options): Add 'validate-pull'.
(%options, show-help): Add '--allow-downgrades'.
(warn-about-backward-updates): New procedure.
(guix-pull): Pass #:current-channels and #:validate-pull to
'latest-channel-instances'.
* guix/channels.scm (ensure-forward-channel-update): Add hint for
when (channel-commit channel) is true.
* doc/guix.texi (Invoking guix pull): Document '--allow-downgrades'.
master
Ludovic Courtès 2020-05-20 23:18:09 +02:00
parent 872898f768
commit 9744cc7b46
No known key found for this signature in database
GPG Key ID: 090B11993D9AEBB5
3 changed files with 66 additions and 18 deletions

View File

@ -3900,6 +3900,21 @@ Use @var{profile} instead of @file{~/.config/guix/current}.
Show which channel commit(s) would be used and what would be built or Show which channel commit(s) would be used and what would be built or
substituted but do not actually do it. substituted but do not actually do it.
@item --allow-downgrades
Allow pulling older or unrelated revisions of channels than those
currently in use.
@cindex downgrade attacks, protection against
By default, @command{guix pull} protects against so-called ``downgrade
attacks'' whereby the Git repository of a channel would be reset to an
earlier or unrelated revision of itself, potentially leading you to
install older, known-vulnerable versions of software packages.
@quotation Note
Make sure you understand its security implications before using
@option{--allow-downgrades}.
@end quotation
@item --system=@var{system} @item --system=@var{system}
@itemx -s @var{system} @itemx -s @var{system}
Attempt to build for @var{system}---e.g., @code{i686-linux}---instead of Attempt to build for @var{system}---e.g., @code{i686-linux}---instead of

View File

@ -246,25 +246,29 @@ This procedure implements a channel update policy meant to be used as a
('ancestor #t) ('ancestor #t)
('self #t) ('self #t)
(_ (_
(raise (apply make-compound-condition (raise (make-compound-condition
(condition (condition
(&message (message (&message (message
(format #f (G_ "\ (format #f (G_ "\
aborting update of channel '~a' to commit ~a, which is not a descendant of ~a") aborting update of channel '~a' to commit ~a, which is not a descendant of ~a")
(channel-name channel) (channel-name channel)
(channel-instance-commit instance) (channel-instance-commit instance)
start)))) start))))
;; Don't show the hint when the user explicitly specified a ;; If the user asked for a specific commit, they might want
;; commit in CHANNEL. ;; that to happen nevertheless, so tell them about the
(if (channel-commit channel) ;; relevant 'guix pull' option.
'() (if (channel-commit channel)
(list (condition (condition
(&fix-hint (&fix-hint
(hint (G_ "This could indicate that the channel has (hint (G_ "Use @option{--allow-downgrades} to force
this downgrade."))))
(condition
(&fix-hint
(hint (G_ "This could indicate that the channel has
been tampered with and is trying to force a roll-back, preventing you from been tampered with and is trying to force a roll-back, preventing you from
getting the latest updates. If you think this is not the case, explicitly getting the latest updates. If you think this is not the case, explicitly
allow non-forward updates."))))))))))) allow non-forward updates."))))))))))
(define* (latest-channel-instances store channels (define* (latest-channel-instances store channels
#:key #:key

View File

@ -81,7 +81,8 @@
(multiplexed-build-output? . #t) (multiplexed-build-output? . #t)
(graft? . #t) (graft? . #t)
(debug . 0) (debug . 0)
(verbosity . 1))) (verbosity . 1)
(validate-pull . ,ensure-forward-channel-update)))
(define (show-help) (define (show-help)
(display (G_ "Usage: guix pull [OPTION]... (display (G_ "Usage: guix pull [OPTION]...
@ -94,6 +95,8 @@ Download and deploy the latest version of Guix.\n"))
--commit=COMMIT download the specified COMMIT")) --commit=COMMIT download the specified COMMIT"))
(display (G_ " (display (G_ "
--branch=BRANCH download the tip of the specified BRANCH")) --branch=BRANCH download the tip of the specified BRANCH"))
(display (G_ "
--allow-downgrades allow downgrades to earlier channel revisions"))
(display (G_ " (display (G_ "
-N, --news display news compared to the previous generation")) -N, --news display news compared to the previous generation"))
(display (G_ " (display (G_ "
@ -158,6 +161,10 @@ Download and deploy the latest version of Guix.\n"))
(option '("branch") #t #f (option '("branch") #t #f
(lambda (opt name arg result) (lambda (opt name arg result)
(alist-cons 'ref `(branch . ,arg) result))) (alist-cons 'ref `(branch . ,arg) result)))
(option '("allow-downgrades") #f #f
(lambda (opt name arg result)
(alist-cons 'validate-pull warn-about-backward-updates
result)))
(option '(#\p "profile") #t #f (option '(#\p "profile") #t #f
(lambda (opt name arg result) (lambda (opt name arg result)
(alist-cons 'profile (canonicalize-profile arg) (alist-cons 'profile (canonicalize-profile arg)
@ -188,6 +195,21 @@ Download and deploy the latest version of Guix.\n"))
%standard-build-options)) %standard-build-options))
(define (warn-about-backward-updates channel start instance relation)
"Warn about non-forward updates of CHANNEL from START to INSTANCE, without
aborting."
(match relation
((or 'ancestor 'self)
#t)
('descendant
(warning (G_ "rolling back channel '~a' from ~a to ~a~%")
(channel-name channel) start
(channel-instance-commit instance)))
('unrelated
(warning (G_ "moving channel '~a' from ~a to unrelated commit ~a~%")
(channel-name channel) start
(channel-instance-commit instance)))))
(define* (display-profile-news profile #:key concise? (define* (display-profile-news profile #:key concise?
current-is-newer?) current-is-newer?)
"Display what's up in PROFILE--new packages, and all that. If "Display what's up in PROFILE--new packages, and all that. If
@ -749,7 +771,9 @@ Use '~/.config/guix/channels.scm' instead."))
(substitutes? (assoc-ref opts 'substitutes?)) (substitutes? (assoc-ref opts 'substitutes?))
(dry-run? (assoc-ref opts 'dry-run?)) (dry-run? (assoc-ref opts 'dry-run?))
(channels (channel-list opts)) (channels (channel-list opts))
(profile (or (assoc-ref opts 'profile) %current-profile))) (profile (or (assoc-ref opts 'profile) %current-profile))
(current-channels (profile-channels profile))
(validate-pull (assoc-ref opts 'validate-pull)))
(cond ((assoc-ref opts 'query) (cond ((assoc-ref opts 'query)
(process-query opts profile)) (process-query opts profile))
((assoc-ref opts 'generation) ((assoc-ref opts 'generation)
@ -766,7 +790,12 @@ Use '~/.config/guix/channels.scm' instead."))
(ensure-default-profile) (ensure-default-profile)
(honor-x509-certificates store) (honor-x509-certificates store)
(let ((instances (latest-channel-instances store channels))) (let ((instances
(latest-channel-instances store channels
#:current-channels
current-channels
#:validate-pull
validate-pull)))
(format (current-error-port) (format (current-error-port)
(N_ "Building from this channel:~%" (N_ "Building from this channel:~%"
"Building from these channels:~%" "Building from these channels:~%"