Bug 868509

Summary: LUKS passphrase exposed in storage.log attached to bug report
Product: [Fedora] Fedora Reporter: Steve Tyler <stephent98>
Component: anacondaAssignee: Brian Lane <bcl>
Status: CLOSED ERRATA QA Contact: Fedora Extras Quality Assurance <extras-qa>
Severity: unspecified Docs Contact:
Priority: unspecified    
Version: 18CC: anaconda-maint-list, awilliam, g.kaviyarasu, jonathan, reklov, robatino, stephent98, vanmeeuwen+fedora, vdanen
Target Milestone: ---Keywords: Security
Target Release: ---   
Hardware: Unspecified   
OS: Unspecified   
Whiteboard: AcceptedNTH
Fixed In Version: anaconda-18.22-1 Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2012-11-08 04:32:53 EST Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: ---
Bug Depends On:    
Bug Blocks: 752661, 752664    
Description Flags
proposed patch
anaconda-tb-all-2.log none

Description Steve Tyler 2012-10-20 07:22:25 EDT
Description of problem:

If anaconda crashes after a LUKS passphrase is set, the passphrase appears in plaintext in storage.log. If a bug report is filed, the passphrase is saved in the storage.log attachment.

See: Bug 868505 - ValueError: Cannot remove non-leaf device 'sda3'
     storage.log: Attachment 630417 [details]

03:53:07,409 DEBUG storage.ui:               LUKS.__init__: add_backup_passphrase: False ; escrow_cert: None ; cipher: None ; passphrase: joeblow_secret ; mountpoint: / ;

Version-Release number of selected component (if applicable):

How reproducible:
Presumably always.

Steps to Reproduce:
1. While configuring a disk, enable disk encryption.
2. Crash anaconda.
3. Report a bug.
Actual results:
LUKS passphrase is saved in plaintext in storage.log in the bug report.

Expected results:
No user secrets are exposed.

Additional info:

Introduced in anaconda-18.19-1:

$ diff -u anaconda-18.18-1/pyanaconda/storage/__init__.py anaconda-18.19-1/pyanaconda/storage/__init__.py

@@ -1398,6 +1400,13 @@
         return name
+    def savePassphrase(self, device):
+        """ Save a device's LUKS passphrase in case of reset. """
+        passphrase = device.format._LUKS__passphrase
+        self.__luksDevs[device.format.uuid] = passphrase
+        self.devicetree._DeviceTree__luksDevs[device.format.uuid] = passphrase
+        self.devicetree._DeviceTree__passphrases.append(passphrase)
     def doEncryptionPassphraseRetrofits(self):
         """ Add the global passphrase to all preexisting LUKS devices.
Comment 1 Steve Tyler 2012-10-20 08:03:25 EDT
After a successful, clean install, the passphrase does not appear in any of the files in /var/log/anaconda/. Retitling:
LUKS passphrase exposed in storage.log attached to bug report
Comment 2 Steve Tyler 2012-10-20 13:18:06 EDT
See also:
Bug 868519 - LUKS passphrase exposed in /root/anaconda-ks.cfg
Comment 3 Steve Tyler 2012-10-24 14:33:08 EDT
Adding Security keyword. The code snippet in Comment 0 suggests that the LUKS passphrase is being stored unencrypted in a Python data structure from the time the passphrase is set until the end of the install.
Comment 4 David Lehman 2012-10-24 15:08:09 EDT
I have a patch to keep the passphrase from storage.log.
Comment 5 Steve Tyler 2012-10-24 15:52:12 EDT
(In reply to comment #4)
> I have a patch to keep the passphrase from storage.log.

Thanks, Dave. That sounds good. I believe a keyring is what is used to securely store passwords, but I will defer to the experts on this ...

$ rpm -qi gnome-python2-gnomekeyring
Summary     : Python bindings for interacting with gnome-keyring
Description :
This module contains a wrapper that allows the use of gnome-keyring
via Python.

$ rpm -qi gnome-keyring
Summary     : Framework for managing passwords and other secrets
Description :
The gnome-keyring session daemon manages passwords and other types of
secrets for the user, storing them encrypted with a main password.
Applications can use the gnome-keyring library to integrate with the keyring.

gnome-keyring Reference Manual
Comment 6 Steve Tyler 2012-10-24 16:10:55 EDT
libreport uses gnome-keyring:

$ grep -ril keyring libreport-2.0.17

Comment 7 Vincent Danen 2012-10-24 22:59:56 EDT
This one likely should be resolved in conjunction with bug #868519.  Adam, sorry for cc'ing you on this but since both bugs are related and both in Anaconda, they should really be fixed at the same time.
Comment 8 Adam Williamson 2012-10-24 23:39:06 EDT
Thanks, Vincent, nominating as Beta NTH and final blocker per the precedent we established earlier. Note that storage.log is not just attached to bug reports but is copied to the installed system as /var/log/anaconda/anconda.storage.log , so this is another place the encryption passphrase would be exposed to someone with physical access (if /var is unencrypted) or root credentials.
Comment 9 Adam Williamson 2012-10-24 23:40:17 EDT
steve: libreport uses gnome-keyring to store passwords you give it directly - usually, your bugzilla login. not, afaik, for data it passes through. that would just be a case of a fix to anaconda not to write the passphrase into the log file in the first place, which dlehman apparently already has a patch for.
Comment 10 Steve Tyler 2012-10-25 00:10:51 EDT
In Comment 1, I reported that the LUKS passphrase was not written to /var/log/anaconda/storage.log. I believe that anaconda dumps more for a crash report than what is written to the storage.log file.

My suggestion re using a keyring was based on the assumption saving an unecrypted password in process memory for an extended time is a security risk. 

Dave: Could you confirm (or not) that the unencrypted LUKS password is to be stored in a data structure in the anaconda process from the time password is set until anaconda exits?

Vincent: If so, is that a security risk?
Comment 11 Adam Williamson 2012-10-25 00:21:43 EDT
ah, sorry, I missed that part.
Comment 12 Vincent Danen 2012-10-25 10:37:04 EDT
By itself, no, I don't think it's a security _flaw_ but obviously there is some risk.  However, at this stage (installation) I think it's a pretty low risk.  You would need a flaw in something like the kernel to start exposing arbitrary bits of memory (or you would need to be root, where all bets are off).  The only way I could see this being any kind of a real-world problem is if you were doing a remote installation (and I have no idea if this is possible, or how it would work if it was).

In short, by itself, I wouldn't be concerned.  If there is a way for a remote user to obtain access to the memory (i.e. using some other flaw in a network-facing component of the installer, if there is one), then it could be possible, but this is a pretty small use-case scenario (if it exists) that my concern is more about what might get dumped to disk or sent to bugzilla.

I don't understand what the "in case of reset" means, so I can't really comment on whether keeping it in memory is something we actually do need.
Comment 13 Steve Tyler 2012-10-25 10:44:15 EDT
Thanks, Vincent. On the Live CD there is no root password and networking is enabled.
Comment 14 Vincent Danen 2012-10-25 11:37:05 EDT
Well, there has to be more to it than that.  Networking may be started, but are there any iptables rules to prevent access?  Is SSH enabled?  "Networking is enabled" is a pretty broad term.  It's been a while since I've used a live CD so I honestly don't know what's enabled and what isn't.
Comment 15 Steve Tyler 2012-10-25 12:03:22 EDT
By default on the Live CD:
1. The firewall allows ssh access.
2. sshd is not running.

From the target, I enabled sshd.
I could not ssh to the target, because a root password is required.
Next, I set a root password on the target.
Then I could ssh to the target as root.
The liveuser account also required a password to be set before I could ssh to the target.

Tested with the target running Fedora-18-Beta-TC6-i686-Live-Desktop.iso.

NB: iptables is being replaced by firewalld, but the iptables command still works.
Comment 16 Vincent Danen 2012-10-25 12:13:03 EDT
Ok, thanks for that explanation.  I don't think we need to be concerned with remote access at all then, so having the unencrypted password in memory is (to me) a non-issue.  You'd have to do a lot of silly things to expose that to random people.

The concern then is what gets sent to bugzilla on a crash (and stored on disk in the crash report), since it doesn't sound like it's written to disk on normal operations.
Comment 17 Steve Tyler 2012-10-25 12:29:48 EDT
OK, thanks.

One other thing I checked while remotely logged in as root:

After configuring an encrypted partition and setting a LUKS passphrase in the installer, I sent anaconda a SIGUSR2 (this is a debugging feature that causes a dump). With anaconda at the main hub, no passphrase was dumped to any of the log files in /tmp.

Dave: Can you suggest a normal state of the installer where sending it a SIGUSR2 would cause the passphrase to be dumped?
Comment 18 Steve Tyler 2012-10-25 13:24:21 EDT
(In reply to comment #17)
> Dave: Can you suggest a normal state of the installer where sending it a
> SIGUSR2 would cause the passphrase to be dumped?

While in the Manual Partitioning spoke:

[root@localhost tmp]# grep joeblow *
anaconda-tb-all.log:    _intf.storage.encryptionPassphrase: joeblow_secret
anaconda-tb-x4fx_U:    _intf.storage.encryptionPassphrase: joeblow_secret
Comment 19 Brian Lane 2012-10-25 20:37:42 EDT
Created attachment 633594 [details]
proposed patch

Give this a try (untested), but should work.
Comment 20 Steve Tyler 2012-10-26 02:08:04 EDT
Thanks, Brian. Your patch appears to prevent the LUKS passphrase from being written to any of the log files in /tmp when SIGUSR2 is sent to the anaconda process.

Test procedure:
1. Configure an encrypted partition and set a LUKS passphrase.
2. Move to the various hubs and spokes.
3. At each, switch to a terminal and run:
   # kill -USR2 `pgrep anaconda`
   # egrep -s 'rootpw|lukspw' /tmp/*
   (anaconda appends to some of the log files,
    so you get more-and-more copies of the passphrase as testing progresses.)

Without your patch:

A dump would contain the passphrase in these dialogs:
1. Manual Partitioning
2. Installation Destination (sometimes)

The passphrase could also be dumped while:
1. Installing software.
2. Waiting for a root password to be set.
3. Waiting for the Reboot button to be clicked.

The passphrase did not get dumped in these dialogs:
1. Installation Summary (main hub)
2. Date & Time
3. Language
4. Keyboard

Tested with:
$ qemu-kvm -m 2048 -hda f18-test-2.img -cdrom ~/xfr/fedora/F18/F18-Beta/TC6/Fedora-18-Beta-TC6-x86_64-Live-Desktop.iso -usb -vga qxl -boot menu=on -usbdevice mouse
Comment 21 David Lehman 2012-10-26 09:20:30 EDT
The other case is kickstart-defined encrypted volumes, in which case the passphrase may be logged to storage.log as part of the kwargs passed to the LUKS class constructor (via log_method_call).
Comment 22 Steve Tyler 2012-10-26 10:09:48 EDT
(In reply to comment #20)
> Test procedure:
>    # kill -USR2 `pgrep anaconda`

On the DVD, there are two anaconda processes, so 'pgrep anaconda' returns the PID of both processes, but the child process exits on SIGUSR2. This command sends SIGUSR2 to the parent process only:

# pkill -USR2 -o anaconda

> The passphrase did not get dumped in these dialogs:
> 1. Installation Summary (main hub)
> 2. Date & Time
> 3. Language
> 4. Keyboard

On the Live CD, if you _return_ to the Manual Partitioning partitioning spoke and then go back back to the Installation Summary, the passphrase is dumped on SIGUSR2 from all of these too.
Comment 23 Steve Tyler 2012-10-26 11:34:25 EDT
Created attachment 633938 [details]

After configuring encryption and sending SIGUSR2 to anaconda, this line appears in the attached anaconda-tb-all.log:

    _intf.storage.encryptionPassphrase: Skipped

This was *without* returning to the Manual Partitioning spoke. Is the skip list getting cleared when the Manual Partitioning spoke is reentered?

NB: This is with stock 18.19-1. It does not have Brian's patch.

Tested with:
$ qemu-kvm -m 2048 -hda f18-test-2.img -cdrom ~/xfr/fedora/F18/F18-Beta/TC6/Fedora-18-Beta-TC6-x86_64-Live-Desktop.iso -usb -vga qxl -boot menu=on -usbdevice mouse
Comment 24 Steve Tyler 2012-10-26 11:57:59 EDT
Created attachment 633942 [details]

The attached anaconda-tb-all-2.log was captured while sending SIGUSR2 twice:
1. After configuring encryption, setting a passphrase, and returning to the Installation Summary.
2. After returning to the Manual Partitioning spoke, and then returning again to the Installation Summary.

$ grep -i encryptionPassphrase anaconda-tb-all-2.log
    _intf.storage.encryptionPassphrase: Skipped
    _intf.storage.encryptionPassphrase: joeblow_secret
Comment 25 Steve Tyler 2012-10-26 14:04:30 EDT
Why is the exception handler maintaining a list of what is secret? The objects themselves should know they are secret, or the secrets should be stored in a keyring object that could not be dumped ...

$ less -N anaconda-18.21-1/pyanaconda/exception.py
    142 def initExceptionHandling(anaconda):
    155     conf = Config(programName="anaconda",
    156                   programVersion=isys.getAnacondaVersion(),
    157                   attrSkipList=["_intf._actions",
    158                                 "_intf.storage.bootloader.password",
    159                                 "_intf.storage.data",
    160                                 "_bootloader.encrypted_password",
    161                                 "_bootloader.password",
    162                                 "payload._groups",
    163                                 "payload._yum"],
    164                   localSkipList=[ "passphrase", "password" ],
    165                   fileList=fileList)
Comment 26 Adam Williamson 2012-10-31 13:51:21 EDT
Discussed at 2012-10-31 NTH review meeting: http://meetbot.fedoraproject.org/fedora-qa/2012-10-31/f18beta-blocker-review-6.2012-10-31-16.00.log.txt . Accepted as NTH as there is a security impact to this bug and it cannot be fixed with an update. To be clear, the thing that gets NTH status is that the passphrase can be passed into bug reports in some cases. We aren't worried about the 'remote access to running install' case.
Comment 27 Fedora Update System 2012-10-31 22:52:30 EDT
anaconda-18.22-1.fc18 has been submitted as an update for Fedora 18.
Comment 28 Fedora Update System 2012-11-01 14:28:23 EDT
Package anaconda-18.22-1.fc18:
* should fix your issue,
* was pushed to the Fedora 18 testing repository,
* should be available at your local mirror within two days.
Update it with:
# su -c 'yum update --enablerepo=updates-testing anaconda-18.22-1.fc18'
as soon as you are able to.
Please go to the following url:
then log in and leave karma (feedback).
Comment 29 Fedora Update System 2012-11-02 00:06:53 EDT
anaconda-18.23-1.fc18 has been submitted as an update for Fedora 18.
Comment 30 Fedora Update System 2012-11-02 21:06:26 EDT
anaconda-18.24-1.fc18 has been submitted as an update for Fedora 18.
Comment 31 Fedora Update System 2012-11-05 20:41:31 EST
anaconda-18.25-1.fc18 has been submitted as an update for Fedora 18.
Comment 32 Fedora Update System 2012-11-06 21:13:39 EST
anaconda-18.26-1.fc18 has been submitted as an update for Fedora 18.
Comment 33 Adam Williamson 2012-11-08 04:32:53 EST
18.26 went stable. Closing. (Bodhi closing of bugs when updates go stable is currently broken).