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
parent
872898f768
commit
9744cc7b46
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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:~%"
|
||||||
|
|
Reference in New Issue