36e8a3
From a046230cfb7e02938e3ad2ac85515636b319651e Mon Sep 17 00:00:00 2001
36e8a3
From: Dimitri John Ledkov <xnox@ubuntu.com>
36e8a3
Date: Wed, 29 Aug 2018 15:38:09 +0100
36e8a3
Subject: [PATCH] cryptsetup: add support for sector-size= option (#9936)
36e8a3
36e8a3
Bug-Ubuntu: https://launchpad.net/bugs/1776626
36e8a3
36e8a3
Closes #8881.
36e8a3
36e8a3
(cherry picked from commit a9fc640671ef60ac949f1ace6fa687ff242fc233)
36e8a3
36e8a3
Resolves: #1572563
36e8a3
---
36e8a3
 man/crypttab.xml            |  9 +++++++++
36e8a3
 meson.build                 |  6 ++++++
36e8a3
 src/cryptsetup/cryptsetup.c | 30 ++++++++++++++++++++++++++++++
36e8a3
 3 files changed, 45 insertions(+)
36e8a3
36e8a3
diff --git a/man/crypttab.xml b/man/crypttab.xml
36e8a3
index dcaf03d2c..3574ce00d 100644
36e8a3
--- a/man/crypttab.xml
36e8a3
+++ b/man/crypttab.xml
36e8a3
@@ -250,6 +250,15 @@
36e8a3
         option.</para></listitem>
36e8a3
       </varlistentry>
36e8a3
 
36e8a3
+      <varlistentry>
36e8a3
+        <term><option>sector-size=</option></term>
36e8a3
+
36e8a3
+        <listitem><para>Specifies the sector size in bytes. See
36e8a3
+        <citerefentry project='die-net'><refentrytitle>cryptsetup</refentrytitle><manvolnum>8</manvolnum></citerefentry>
36e8a3
+        for possible values and the default value of this
36e8a3
+        option.</para></listitem>
36e8a3
+      </varlistentry>
36e8a3
+
36e8a3
       <varlistentry>
36e8a3
         <term><option>swap</option></term>
36e8a3
 
36e8a3
diff --git a/meson.build b/meson.build
36e8a3
index a0e724070..f308db263 100644
36e8a3
--- a/meson.build
36e8a3
+++ b/meson.build
36e8a3
@@ -927,11 +927,17 @@ if want_libcryptsetup != 'false' and not fuzzer_build
36e8a3
                                    version : '>= 1.6.0',
36e8a3
                                    required : want_libcryptsetup == 'true')
36e8a3
         have = libcryptsetup.found()
36e8a3
+        have_sector = cc.has_member(
36e8a3
+                    'struct crypt_params_plain',
36e8a3
+                    'sector_size',
36e8a3
+                    prefix : '#include <libcryptsetup.h>')
36e8a3
 else
36e8a3
         have = false
36e8a3
+        have_sector = false
36e8a3
         libcryptsetup = []
36e8a3
 endif
36e8a3
 conf.set10('HAVE_LIBCRYPTSETUP', have)
36e8a3
+conf.set10('HAVE_LIBCRYPTSETUP_SECTOR_SIZE', have_sector)
36e8a3
 
36e8a3
 want_libcurl = get_option('libcurl')
36e8a3
 if want_libcurl != 'false' and not fuzzer_build
36e8a3
diff --git a/src/cryptsetup/cryptsetup.c b/src/cryptsetup/cryptsetup.c
36e8a3
index 832168184..87008cb96 100644
36e8a3
--- a/src/cryptsetup/cryptsetup.c
36e8a3
+++ b/src/cryptsetup/cryptsetup.c
36e8a3
@@ -23,10 +23,14 @@
36e8a3
 
36e8a3
 /* internal helper */
36e8a3
 #define ANY_LUKS "LUKS"
36e8a3
+/* as in src/cryptsetup.h */
36e8a3
+#define CRYPT_SECTOR_SIZE 512
36e8a3
+#define CRYPT_MAX_SECTOR_SIZE 4096
36e8a3
 
36e8a3
 static const char *arg_type = NULL; /* ANY_LUKS, CRYPT_LUKS1, CRYPT_LUKS2, CRYPT_TCRYPT or CRYPT_PLAIN */
36e8a3
 static char *arg_cipher = NULL;
36e8a3
 static unsigned arg_key_size = 0;
36e8a3
+static unsigned arg_sector_size = CRYPT_SECTOR_SIZE;
36e8a3
 static int arg_key_slot = CRYPT_ANY_SLOT;
36e8a3
 static unsigned arg_keyfile_size = 0;
36e8a3
 static uint64_t arg_keyfile_offset = 0;
36e8a3
@@ -86,6 +90,29 @@ static int parse_one_option(const char *option) {
36e8a3
 
36e8a3
                 arg_key_size /= 8;
36e8a3
 
36e8a3
+        } else if ((val = startswith(option, "sector-size="))) {
36e8a3
+
36e8a3
+#if HAVE_LIBCRYPTSETUP_SECTOR_SIZE
36e8a3
+                r = safe_atou(val, &arg_sector_size);
36e8a3
+                if (r < 0) {
36e8a3
+                        log_error_errno(r, "Failed to parse %s, ignoring: %m", option);
36e8a3
+                        return 0;
36e8a3
+                }
36e8a3
+
36e8a3
+                if (arg_sector_size % 2) {
36e8a3
+                        log_error("sector-size= not a multiple of 2, ignoring.");
36e8a3
+                        return 0;
36e8a3
+                }
36e8a3
+
36e8a3
+                if (arg_sector_size < CRYPT_SECTOR_SIZE || arg_sector_size > CRYPT_MAX_SECTOR_SIZE) {
36e8a3
+                        log_error("sector-size= is outside of %u and %u, ignoring.", CRYPT_SECTOR_SIZE, CRYPT_MAX_SECTOR_SIZE);
36e8a3
+                        return 0;
36e8a3
+                }
36e8a3
+#else
36e8a3
+                log_error("sector-size= is not supported, compiled with old libcryptsetup.");
36e8a3
+                return 0;
36e8a3
+#endif
36e8a3
+
36e8a3
         } else if ((val = startswith(option, "key-slot="))) {
36e8a3
 
36e8a3
                 arg_type = ANY_LUKS;
36e8a3
@@ -471,6 +498,9 @@ static int attach_luks_or_plain(struct crypt_device *cd,
36e8a3
                 struct crypt_params_plain params = {
36e8a3
                         .offset = arg_offset,
36e8a3
                         .skip = arg_skip,
36e8a3
+#if HAVE_LIBCRYPTSETUP_SECTOR_SIZE
36e8a3
+                        .sector_size = arg_sector_size,
36e8a3
+#endif
36e8a3
                 };
36e8a3
                 const char *cipher, *cipher_mode;
36e8a3
                 _cleanup_free_ char *truncated_cipher = NULL;