• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Copyright 2018 Google, Inc
3  *
4  *  Licensed under the Apache License, Version 2.0 (the "License");
5  *  you may not use this file except in compliance with the License.
6  *  You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  *  Unless required by applicable law or agreed to in writing, software
11  *  distributed under the License is distributed on an "AS IS" BASIS,
12  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  *  See the License for the specific language governing permissions and
14  *  limitations under the License.
15  */
16 
17 #ifndef _LIBDM_DMTARGET_H_
18 #define _LIBDM_DMTARGET_H_
19 
20 #include <linux/dm-ioctl.h>
21 #include <stdint.h>
22 
23 #include <string>
24 #include <vector>
25 
26 namespace android {
27 namespace dm {
28 
29 class DmTargetTypeInfo {
30   public:
DmTargetTypeInfo()31     DmTargetTypeInfo() : major_(0), minor_(0), patch_(0) {}
DmTargetTypeInfo(const struct dm_target_versions * info)32     DmTargetTypeInfo(const struct dm_target_versions* info)
33         : name_(info->name),
34           major_(info->version[0]),
35           minor_(info->version[1]),
36           patch_(info->version[2]) {}
37 
name()38     const std::string& name() const { return name_; }
version()39     std::string version() const {
40         return std::to_string(major_) + "." + std::to_string(minor_) + "." + std::to_string(patch_);
41     }
42 
major_version()43     uint32_t major_version() const { return major_; }
minor_version()44     uint32_t minor_version() const { return minor_; }
patch_level()45     uint32_t patch_level() const { return patch_; }
46 
IsAtLeast(uint32_t major,uint32_t minor,uint32_t patch)47     bool IsAtLeast(uint32_t major, uint32_t minor, uint32_t patch) const {
48         if (major_ > major) return true;
49         if (major_ < major) return false;
50         if (minor_ > minor) return true;
51         if (minor_ < minor) return false;
52         return patch_ >= patch;
53     }
54 
55   private:
56     std::string name_;
57     uint32_t major_;
58     uint32_t minor_;
59     uint32_t patch_;
60 };
61 
62 class DmTarget {
63   public:
DmTarget(uint64_t start,uint64_t length)64     DmTarget(uint64_t start, uint64_t length) : start_(start), length_(length) {}
65 
66     virtual ~DmTarget() = default;
67 
68     // Returns name of the target.
69     virtual std::string name() const = 0;
70 
71     // Return the first logical sector represented by this target.
start()72     uint64_t start() const { return start_; }
73 
74     // Returns size in number of sectors when this target is part of
75     // a DmTable, return 0 otherwise.
size()76     uint64_t size() const { return length_; }
77 
78     // Function that converts this object to a string of arguments that can
79     // be passed to the kernel for adding this target in a table. Each target (e.g. verity, linear)
80     // must implement this, for it to be used on a device.
81     std::string Serialize() const;
82 
Valid()83     virtual bool Valid() const { return true; }
84 
85   protected:
86     // Get the parameter string that is passed to the end of the dm_target_spec
87     // for this target type.
88     virtual std::string GetParameterString() const = 0;
89 
90   private:
91     // logical sector number start and total length (in terms of 512-byte sectors) represented
92     // by this target within a DmTable.
93     uint64_t start_, length_;
94 };
95 
96 class DmTargetZero final : public DmTarget {
97   public:
DmTargetZero(uint64_t start,uint64_t length)98     DmTargetZero(uint64_t start, uint64_t length) : DmTarget(start, length) {}
99 
name()100     std::string name() const override { return "zero"; }
101     std::string GetParameterString() const override;
102 };
103 
104 class DmTargetLinear final : public DmTarget {
105   public:
DmTargetLinear(uint64_t start,uint64_t length,const std::string & block_device,uint64_t physical_sector)106     DmTargetLinear(uint64_t start, uint64_t length, const std::string& block_device,
107                    uint64_t physical_sector)
108         : DmTarget(start, length), block_device_(block_device), physical_sector_(physical_sector) {}
109 
name()110     std::string name() const override { return "linear"; }
111     std::string GetParameterString() const override;
block_device()112     const std::string& block_device() const { return block_device_; }
113 
114   private:
115     std::string block_device_;
116     uint64_t physical_sector_;
117 };
118 
119 class DmTargetVerity final : public DmTarget {
120   public:
121     DmTargetVerity(uint64_t start, uint64_t length, uint32_t version,
122                    const std::string& block_device, const std::string& hash_device,
123                    uint32_t data_block_size, uint32_t hash_block_size, uint32_t num_data_blocks,
124                    uint32_t hash_start_block, const std::string& hash_algorithm,
125                    const std::string& root_digest, const std::string& salt);
126 
127     void UseFec(const std::string& device, uint32_t num_roots, uint32_t num_blocks, uint32_t start);
128     void SetVerityMode(const std::string& mode);
129     void IgnoreZeroBlocks();
130     void CheckAtMostOnce();
131 
name()132     std::string name() const override { return "verity"; }
133     std::string GetParameterString() const override;
Valid()134     bool Valid() const override { return valid_; }
135 
136   private:
137     std::vector<std::string> base_args_;
138     std::vector<std::string> optional_args_;
139     bool valid_;
140 };
141 
142 class DmTargetAndroidVerity final : public DmTarget {
143   public:
DmTargetAndroidVerity(uint64_t start,uint64_t length,const std::string & block_device,const std::string & keyid)144     DmTargetAndroidVerity(uint64_t start, uint64_t length, const std::string& block_device,
145                           const std::string& keyid)
146         : DmTarget(start, length), keyid_(keyid), block_device_(block_device) {}
147 
name()148     std::string name() const override { return "android-verity"; }
149     std::string GetParameterString() const override;
150 
151   private:
152     std::string keyid_;
153     std::string block_device_;
154 };
155 
156 // This is the same as DmTargetVerity, but the table may be specified as a raw
157 // string. This code exists only for fs_mgr_verity and should be avoided. Use
158 // DmTargetVerity for new code instead.
159 class DmTargetVerityString final : public DmTarget {
160   public:
DmTargetVerityString(uint64_t start,uint64_t length,const std::string & target_string)161     DmTargetVerityString(uint64_t start, uint64_t length, const std::string& target_string)
162         : DmTarget(start, length), target_string_(target_string) {}
163 
name()164     std::string name() const override { return "verity"; }
GetParameterString()165     std::string GetParameterString() const override { return target_string_; }
Valid()166     bool Valid() const override { return true; }
167 
168   private:
169     std::string target_string_;
170 };
171 
172 // dm-bow is the backup on write target that can provide checkpoint capability
173 // for file systems that do not support checkpoints natively
174 class DmTargetBow final : public DmTarget {
175   public:
DmTargetBow(uint64_t start,uint64_t length,const std::string & target_string)176     DmTargetBow(uint64_t start, uint64_t length, const std::string& target_string)
177         : DmTarget(start, length), target_string_(target_string) {}
178 
SetBlockSize(uint32_t block_size)179     void SetBlockSize(uint32_t block_size) { block_size_ = block_size; }
180 
name()181     std::string name() const override { return "bow"; }
182     std::string GetParameterString() const override;
183 
184   private:
185     std::string target_string_;
186     uint32_t block_size_ = 0;
187 };
188 
189 enum class SnapshotStorageMode {
190     // The snapshot will be persisted to the COW device.
191     Persistent,
192     // The snapshot will be lost on reboot.
193     Transient,
194     // The snapshot will be merged from the COW device into the base device,
195     // in the background.
196     Merge
197 };
198 
199 // Writes to a snapshot device will be written to the given COW device. Reads
200 // will read from the COW device or base device. The chunk size is specified
201 // in sectors.
202 class DmTargetSnapshot final : public DmTarget {
203   public:
DmTargetSnapshot(uint64_t start,uint64_t length,const std::string & base_device,const std::string & cow_device,SnapshotStorageMode mode,uint64_t chunk_size)204     DmTargetSnapshot(uint64_t start, uint64_t length, const std::string& base_device,
205                      const std::string& cow_device, SnapshotStorageMode mode, uint64_t chunk_size)
206         : DmTarget(start, length),
207           base_device_(base_device),
208           cow_device_(cow_device),
209           mode_(mode),
210           chunk_size_(chunk_size) {}
211 
212     std::string name() const override;
213     std::string GetParameterString() const override;
Valid()214     bool Valid() const override { return true; }
215 
216     struct Status {
217         uint64_t sectors_allocated;
218         uint64_t total_sectors;
219         uint64_t metadata_sectors;
220         std::string error;
221     };
222 
223     static double MergePercent(const Status& status, uint64_t sectors_initial = 0);
224     static bool ParseStatusText(const std::string& text, Status* status);
225     static bool ReportsOverflow(const std::string& target_type);
226     static bool GetDevicesFromParams(const std::string& params, std::string* base_device,
227                                      std::string* cow_device);
228 
229   private:
230     std::string base_device_;
231     std::string cow_device_;
232     SnapshotStorageMode mode_;
233     uint64_t chunk_size_;
234 };
235 
236 // snapshot-origin will read/write directly to the backing device, updating any
237 // snapshot devices with a matching origin.
238 class DmTargetSnapshotOrigin final : public DmTarget {
239   public:
DmTargetSnapshotOrigin(uint64_t start,uint64_t length,const std::string & device)240     DmTargetSnapshotOrigin(uint64_t start, uint64_t length, const std::string& device)
241         : DmTarget(start, length), device_(device) {}
242 
name()243     std::string name() const override { return "snapshot-origin"; }
GetParameterString()244     std::string GetParameterString() const override { return device_; }
Valid()245     bool Valid() const override { return true; }
246 
247   private:
248     std::string device_;
249 };
250 
251 class DmTargetCrypt final : public DmTarget {
252   public:
DmTargetCrypt(uint64_t start,uint64_t length,const std::string & cipher,const std::string & key,uint64_t iv_sector_offset,const std::string & device,uint64_t device_sector)253     DmTargetCrypt(uint64_t start, uint64_t length, const std::string& cipher,
254                   const std::string& key, uint64_t iv_sector_offset, const std::string& device,
255                   uint64_t device_sector)
256         : DmTarget(start, length),
257           cipher_(cipher),
258           key_(key),
259           iv_sector_offset_(iv_sector_offset),
260           device_(device),
261           device_sector_(device_sector) {}
262 
AllowDiscards()263     void AllowDiscards() { allow_discards_ = true; }
AllowEncryptOverride()264     void AllowEncryptOverride() { allow_encrypt_override_ = true; }
SetIvLargeSectors()265     void SetIvLargeSectors() { iv_large_sectors_ = true; }
SetSectorSize(uint32_t sector_size)266     void SetSectorSize(uint32_t sector_size) { sector_size_ = sector_size; }
267 
name()268     std::string name() const override { return "crypt"; }
Valid()269     bool Valid() const override { return true; }
270     std::string GetParameterString() const override;
271 
272   private:
273     std::string cipher_;
274     std::string key_;
275     uint64_t iv_sector_offset_;
276     std::string device_;
277     uint64_t device_sector_;
278     bool allow_discards_ = false;
279     bool allow_encrypt_override_ = false;
280     bool iv_large_sectors_ = false;
281     uint32_t sector_size_ = 0;
282 };
283 
284 class DmTargetDefaultKey final : public DmTarget {
285   public:
DmTargetDefaultKey(uint64_t start,uint64_t length,const std::string & cipher,const std::string & key,const std::string & blockdev,uint64_t start_sector)286     DmTargetDefaultKey(uint64_t start, uint64_t length, const std::string& cipher,
287                        const std::string& key, const std::string& blockdev, uint64_t start_sector)
288         : DmTarget(start, length),
289           cipher_(cipher),
290           key_(key),
291           blockdev_(blockdev),
292           start_sector_(start_sector) {}
293 
name()294     std::string name() const override { return kName; }
295     bool Valid() const override;
296     std::string GetParameterString() const override;
SetUseLegacyOptionsFormat()297     void SetUseLegacyOptionsFormat() { use_legacy_options_format_ = true; }
SetSetDun()298     void SetSetDun() { set_dun_ = true; }
SetWrappedKeyV0()299     void SetWrappedKeyV0() { is_hw_wrapped_ = true; }
300 
301   private:
302     inline static const std::string kName = "default-key";
303 
304     std::string cipher_;
305     std::string key_;
306     std::string blockdev_;
307     uint64_t start_sector_;
308     bool use_legacy_options_format_ = false;
309     bool set_dun_ = false;
310     bool is_hw_wrapped_ = false;
311 };
312 
313 class DmTargetUser final : public DmTarget {
314   public:
DmTargetUser(uint64_t start,uint64_t length,std::string control_device)315     DmTargetUser(uint64_t start, uint64_t length, std::string control_device)
316         : DmTarget(start, length), control_device_(control_device) {}
317 
name()318     std::string name() const override { return "user"; }
control_device()319     std::string control_device() const { return control_device_; }
320     std::string GetParameterString() const override;
321 
322   private:
323     std::string control_device_;
324 };
325 
326 class DmTargetError final : public DmTarget {
327   public:
DmTargetError(uint64_t start,uint64_t length)328     DmTargetError(uint64_t start, uint64_t length) : DmTarget(start, length) {}
329 
name()330     std::string name() const override { return "error"; }
GetParameterString()331     std::string GetParameterString() const override { return ""; }
332 };
333 
334 }  // namespace dm
335 }  // namespace android
336 
337 #endif /* _LIBDM_DMTARGET_H_ */
338