crypt_reboot 0.1.2 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 90456cf783f95d79186882a7fce00b153b4ff1928a68efd4609fb7e8859d3b04
4
- data.tar.gz: d5fd15cb6705793a7e357666158eaa4f95f5c14d41b22b1d82d087a921fa512c
3
+ metadata.gz: ee0a1d8c466f902cc47c84b3310c899046ae2d2cacc952f184baa76463add807
4
+ data.tar.gz: 6fc17834b241d0822848b84e36fa2277b47a998c77659740a82d0e49d83a16e6
5
5
  SHA512:
6
- metadata.gz: 5c99c3e114727a1236ef3dd9f536a56b1a89639c4447f6387ec5bcd1bd25234f2655a75f306ace56dd78c36a0aadf77da4321ed6626c36c63e38c9852fefefea
7
- data.tar.gz: 37acfc427190670ad362cfb60a8a18ed29bcab338d24ac728ac23f4e3934c6669175db7872836ac46211d09dd16cba861259ec8e99c829050c1a8a3b875b9724
6
+ metadata.gz: 030a74f06349d21c91b05a7ac297ffb927309faad863689a8cd632521587e47059c38995b377e199e5337819f447999796f65aa6dfa17345f7aaca0821458a23
7
+ data.tar.gz: 2f16596ee0b871ecec49b9687da65d3086c66daa41b48e3090d43317452755752443996f5ef5887ac4a73f50f31bd4307ab08254b2869e3219970117ddfcbeee
data/README.md CHANGED
@@ -65,12 +65,24 @@ If you use Debian-based distribution, use this command to install required packa
65
65
  When asked if kexec should handle reboots, answer `yes` (however the answer probably
66
66
  doesn't matter for cryptreboot to work).
67
67
 
68
+ ## Recommendations
69
+
70
+ To protects against saving sensitive data (passphrase, encryption keys) to swap space on a disk, it is recommended to use `memory_locker` ([Rubygems](https://rubygems.org/gems/memory_locker), [Github](https://github.com/phantom-node/memory_locker)).
71
+
72
+ $ sudo gem install memory_locker
73
+
74
+ If you don't want to install it, you will have to specify `--insecure-memory` flag when running cryptreboot.
75
+
68
76
  ## Installation
69
77
 
70
78
  Make sure the required software is installed, then install the gem system-wide by executing:
71
79
 
72
80
  $ sudo gem install crypt_reboot
73
81
 
82
+ To upgrade run:
83
+
84
+ $ sudo gem update crypt_reboot
85
+
74
86
  ## Usage
75
87
 
76
88
  Cryptreboot performs operations normally only available to the root user,
@@ -84,7 +96,7 @@ To see the usage, run:
84
96
 
85
97
  $ cryptreboot --help
86
98
 
87
- ## Resolutions for common issues
99
+ ## Troubleshooting
88
100
 
89
101
  ### LZ4 initramfs compression
90
102
 
@@ -140,9 +152,9 @@ To cancel the change, remove the file:
140
152
 
141
153
  $ sudo rm /etc/systemd/system/systemd-kexec.service.d/override.conf
142
154
 
143
- ### No symlinks to most recent kernel and initramfs
155
+ ### No symlinks to the most recent kernel and initramfs
144
156
 
145
- By default cryptreboot looks for kernel in `/boot/vmlinuz` and for initramfs
157
+ By default, cryptreboot looks for kernel in `/boot/vmlinuz` and for initramfs
146
158
  in `/boot/initrd.img`. If those files are missing in your Linux distribution,
147
159
  cryptreboot will fail, unless you use `--kernel` and `--initramfs` command line
148
160
  options.
@@ -160,6 +172,20 @@ Unfortunately, you need to rerun it after each kernel upgrade, otherwise,
160
172
  cryptreboot is going to boot the old kernel.
161
173
  Upcoming versions of cryptreboot will offer better solutions.
162
174
 
175
+ ### Problems with memory locking
176
+
177
+ If you get:
178
+
179
+ > Locking error: Failed to lock memory
180
+
181
+ it means there was an error while locking memory to prevent a risk of sensitive data ending in a swap space.
182
+
183
+ The best solution is to install `memory_locker` (see [requirements](#requirements) section).
184
+ If it still doesn't help, make sure you have permission to lock memory. Root users do.
185
+ If the problem persists, then please report a bug describing your setup.
186
+
187
+ The solution of last resort is to use `--insecure-memory` flag, which disables memory locking completely.
188
+
163
189
  ## Development
164
190
 
165
191
  After checking out the repo, run `bundle install` to install
data/lib/basic_loader.rb CHANGED
@@ -8,13 +8,13 @@ require 'crypt_reboot/cli'
8
8
  require 'crypt_reboot/concatenator'
9
9
  require 'crypt_reboot/instantiable_config'
10
10
  require 'crypt_reboot/config'
11
+ require 'crypt_reboot/elastic_memory_locker'
11
12
  require 'crypt_reboot/files_generator'
12
13
  require 'crypt_reboot/files_writer'
13
14
  require 'crypt_reboot/gziper'
14
15
  require 'crypt_reboot/initramfs_patch_squeezer'
15
16
  require 'crypt_reboot/kexec_patching_loader'
16
17
  require 'crypt_reboot/lazy_config'
17
- require 'crypt_reboot/memory_locker'
18
18
  require 'crypt_reboot/passphrase_asker'
19
19
  require 'crypt_reboot/patched_initramfs_generator'
20
20
  require 'crypt_reboot/rebooter'
@@ -90,6 +90,12 @@ module CryptReboot
90
90
  'algorithm to a more robust one.'
91
91
  end
92
92
 
93
+ flag :insecure_memory do
94
+ short '-s'
95
+ long '--insecure-memory'
96
+ desc 'Do not lock memory. WARNING: there is a risk your secrets will leak to swap.'
97
+ end
98
+
93
99
  flag :debug do
94
100
  short '-d'
95
101
  long '--debug'
@@ -5,7 +5,6 @@ module CryptReboot
5
5
  # Interprets parameters, executes everything and returns callable object
6
6
  class ParamsParsingExecutor
7
7
  def call(raw_params)
8
- locker.call
9
8
  params = parser.call(raw_params)
10
9
  handle_action_params!(params) or configure_and_exec(params)
11
10
  rescue StandardError, Interrupt => e
@@ -22,6 +21,7 @@ module CryptReboot
22
21
 
23
22
  def configure_and_exec(params)
24
23
  config_updater.call(**params)
24
+ locker.call
25
25
  loader.call
26
26
  rebooter
27
27
  end
@@ -58,7 +58,7 @@ module CryptReboot
58
58
  rebooter: Rebooter.new,
59
59
  happy_exiter_class: HappyExiter,
60
60
  sad_exiter_class: SadExiter,
61
- locker: MemoryLocker.new)
61
+ locker: ElasticMemoryLocker.new)
62
62
  @parser = parser
63
63
  @config_updater = config_updater
64
64
  @loader = loader
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CryptReboot
4
+ # Try to lock memory if configuration allows it
5
+ class ElasticMemoryLocker
6
+ LockingError = Class.new StandardError
7
+
8
+ def call
9
+ return if skip_locking?
10
+
11
+ loader.call
12
+ locker.call
13
+ nil
14
+ rescue load_error, locking_error => e
15
+ raise LockingError, 'Failed to lock memory', cause: e
16
+ end
17
+
18
+ private
19
+
20
+ def skip_locking?
21
+ insecure_memory_checker.call
22
+ end
23
+
24
+ def locking_error
25
+ lazy_locking_error.call
26
+ end
27
+
28
+ attr_reader :insecure_memory_checker, :loader, :load_error, :locker, :lazy_locking_error
29
+
30
+ def initialize(insecure_memory_checker: LazyConfig.insecure_memory,
31
+ loader: -> { require 'memory_locker' },
32
+ load_error: LoadError,
33
+ locker: -> { MemoryLocker.call },
34
+ lazy_locking_error: -> { MemoryLocker::Error })
35
+ @insecure_memory_checker = insecure_memory_checker
36
+ @loader = loader
37
+ @load_error = load_error
38
+ @locker = locker
39
+ @lazy_locking_error = lazy_locking_error
40
+ end
41
+ end
42
+ end
@@ -8,7 +8,7 @@ module CryptReboot
8
8
  attr_reader :initramfs, :cmdline, :kernel, :patch_save_path, :cat_path, :cpio_path,
9
9
  :unmkinitramfs_path, :kexec_path, :cryptsetup_path, :reboot_path,
10
10
  :mount_path, :umount_path, :strace_path, :grep_path,
11
- :debug, :prepare_only, :skip_lz4_check
11
+ :debug, :prepare_only, :skip_lz4_check, :insecure_memory
12
12
 
13
13
  def update!(**settings)
14
14
  settings.each do |name, value|
@@ -25,6 +25,7 @@ module CryptReboot
25
25
  end
26
26
 
27
27
  # rubocop:disable Metrics/MethodLength
28
+ # rubocop:disable Metrics/AbcSize
28
29
  def initialize
29
30
  # Options
30
31
  @initramfs = '/boot/initrd.img'
@@ -46,7 +47,9 @@ module CryptReboot
46
47
  @debug = false
47
48
  @prepare_only = false
48
49
  @skip_lz4_check = false
50
+ @insecure_memory = false
49
51
  end
52
+ # rubocop:enable Metrics/AbcSize
50
53
  # rubocop:enable Metrics/MethodLength
51
54
  end
52
55
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module CryptReboot
4
- VERSION = '0.1.2'
4
+ VERSION = '0.2.0'
5
5
  end
data/lib/crypt_reboot.rb CHANGED
@@ -7,6 +7,7 @@ rescue LoadError => e
7
7
 
8
8
  require 'zeitwerk'
9
9
  loader = Zeitwerk::Loader.for_gem
10
+ loader.ignore("#{__dir__}/memory_locker.rb") # stub has to be loaded manually
10
11
  loader.setup
11
12
  end
12
13
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: crypt_reboot
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Paweł Pokrywka
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-07-22 00:00:00.000000000 Z
11
+ date: 2023-07-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: tty-command
@@ -38,20 +38,6 @@ dependencies:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0.3'
41
- - !ruby/object:Gem::Dependency
42
- name: ffi
43
- requirement: !ruby/object:Gem::Requirement
44
- requirements:
45
- - - ">="
46
- - !ruby/object:Gem::Version
47
- version: 1.0.0
48
- type: :runtime
49
- prerelease: false
50
- version_requirements: !ruby/object:Gem::Requirement
51
- requirements:
52
- - - ">="
53
- - !ruby/object:Gem::Version
54
- version: 1.0.0
55
41
  description:
56
42
  email:
57
43
  - pepawel@users.noreply.github.com
@@ -85,6 +71,7 @@ files:
85
71
  - lib/crypt_reboot/crypt_tab/keyfile_locator.rb
86
72
  - lib/crypt_reboot/crypt_tab/luks_to_plain_converter.rb
87
73
  - lib/crypt_reboot/crypt_tab/serializer.rb
74
+ - lib/crypt_reboot/elastic_memory_locker.rb
88
75
  - lib/crypt_reboot/files_generator.rb
89
76
  - lib/crypt_reboot/files_writer.rb
90
77
  - lib/crypt_reboot/gziper.rb
@@ -107,7 +94,6 @@ files:
107
94
  - lib/crypt_reboot/luks/dumper/luks_v2_parser.rb
108
95
  - lib/crypt_reboot/luks/key_fetcher.rb
109
96
  - lib/crypt_reboot/luks/version_detector.rb
110
- - lib/crypt_reboot/memory_locker.rb
111
97
  - lib/crypt_reboot/passphrase_asker.rb
112
98
  - lib/crypt_reboot/patched_initramfs_generator.rb
113
99
  - lib/crypt_reboot/rebooter.rb
@@ -1,33 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'ffi'
4
-
5
- module CryptReboot
6
- # Lock process memory, so it won't be swapped by the kernel.
7
- # It is implemented as a one-way operation: there is no unlock.
8
- # That's because it's hard to properly clean memory in Ruby.
9
- class MemoryLocker
10
- Error = Class.new StandardError
11
-
12
- def call
13
- return if Libc.mlockall(Libc::MCL_CURRENT | Libc::MCL_FUTURE).zero?
14
-
15
- raise Error, "Failed to lock memory: #{FFI.errno}"
16
- end
17
-
18
- # Low level interface to libc
19
- module Libc
20
- extend FFI::Library
21
- ffi_lib 'libc.so.6'
22
-
23
- # define mlockall constants
24
- MCL_CURRENT = 1
25
- MCL_FUTURE = 2
26
- MCL_ONFAULT = 4
27
-
28
- # declare mlockall function
29
- attach_function :mlockall, [:int], :int
30
- end
31
- private_constant :Libc
32
- end
33
- end