Pablo Greco 48fc63
From 063a7a0071a0e6b01426088c8003e24e160937d1 Mon Sep 17 00:00:00 2001
Pablo Greco 48fc63
From: Dimitri John Ledkov <xnox@ubuntu.com>
Pablo Greco 48fc63
Date: Wed, 29 Aug 2018 15:38:09 +0100
Pablo Greco 48fc63
Subject: [PATCH] cryptsetup: add support for sector-size= option (#9936)
Pablo Greco 48fc63
Pablo Greco 48fc63
Bug-Ubuntu: https://launchpad.net/bugs/1776626
Pablo Greco 48fc63
Pablo Greco 48fc63
Closes #8881.
Pablo Greco 48fc63
Pablo Greco 48fc63
(cherry picked from commit a9fc640671ef60ac949f1ace6fa687ff242fc233)
Pablo Greco 48fc63
Pablo Greco 48fc63
Resolves: #1571801
Pablo Greco 48fc63
---
Pablo Greco 48fc63
 configure.ac                |  6 ++++++
Pablo Greco 48fc63
 man/crypttab.xml            |  9 +++++++++
Pablo Greco 48fc63
 src/cryptsetup/cryptsetup.c | 35 ++++++++++++++++++++++++++++++++++-
Pablo Greco 48fc63
 3 files changed, 49 insertions(+), 1 deletion(-)
Pablo Greco 48fc63
Pablo Greco 48fc63
diff --git a/configure.ac b/configure.ac
Pablo Greco 48fc63
index ee147e28eb..19d42602c9 100644
Pablo Greco 48fc63
--- a/configure.ac
Pablo Greco 48fc63
+++ b/configure.ac
Pablo Greco 48fc63
@@ -832,6 +832,12 @@ if test "x$enable_libcryptsetup" != "xno"; then
Pablo Greco 48fc63
         if test "x$have_libcryptsetup" = xno -a "x$enable_libcryptsetup" = xyes; then
Pablo Greco 48fc63
                 AC_MSG_ERROR([*** libcryptsetup support requested but libraries not found])
Pablo Greco 48fc63
         fi
Pablo Greco 48fc63
+        AC_CHECK_MEMBER(
Pablo Greco 48fc63
+                [struct crypt_params_plain.sector_size],
Pablo Greco 48fc63
+                [AC_DEFINE([HAVE_LIBCRYPTSETUP_SECTOR_SIZE], [1], [Define if libcryptsetup supports sector_size param])],
Pablo Greco 48fc63
+                [],
Pablo Greco 48fc63
+                [#include <libcryptsetup.h>]
Pablo Greco 48fc63
+        )
Pablo Greco 48fc63
 fi
Pablo Greco 48fc63
 AM_CONDITIONAL(HAVE_LIBCRYPTSETUP, [test "$have_libcryptsetup" = "yes"])
Pablo Greco 48fc63
 
Pablo Greco 48fc63
diff --git a/man/crypttab.xml b/man/crypttab.xml
Pablo Greco 48fc63
index e4ecab3dcb..df75007072 100644
Pablo Greco 48fc63
--- a/man/crypttab.xml
Pablo Greco 48fc63
+++ b/man/crypttab.xml
Pablo Greco 48fc63
@@ -248,6 +248,15 @@
Pablo Greco 48fc63
         option.</para></listitem>
Pablo Greco 48fc63
       </varlistentry>
Pablo Greco 48fc63
 
Pablo Greco 48fc63
+      <varlistentry>
Pablo Greco 48fc63
+        <term><option>sector-size=</option></term>
Pablo Greco 48fc63
+
Pablo Greco 48fc63
+        <listitem><para>Specifies the sector size in bytes. See
Pablo Greco 48fc63
+        <citerefentry project='die-net'><refentrytitle>cryptsetup</refentrytitle><manvolnum>8</manvolnum></citerefentry>
Pablo Greco 48fc63
+        for possible values and the default value of this
Pablo Greco 48fc63
+        option.</para></listitem>
Pablo Greco 48fc63
+      </varlistentry>
Pablo Greco 48fc63
+
Pablo Greco 48fc63
       <varlistentry>
Pablo Greco 48fc63
         <term><option>swap</option></term>
Pablo Greco 48fc63
 
Pablo Greco 48fc63
diff --git a/src/cryptsetup/cryptsetup.c b/src/cryptsetup/cryptsetup.c
Pablo Greco 48fc63
index 528c36c48b..fd8b9ba9ec 100644
Pablo Greco 48fc63
--- a/src/cryptsetup/cryptsetup.c
Pablo Greco 48fc63
+++ b/src/cryptsetup/cryptsetup.c
Pablo Greco 48fc63
@@ -43,10 +43,14 @@
Pablo Greco 48fc63
 
Pablo Greco 48fc63
 /* internal helper */
Pablo Greco 48fc63
 #define ANY_LUKS "LUKS"
Pablo Greco 48fc63
+/* as in src/cryptsetup.h */
Pablo Greco 48fc63
+#define CRYPT_SECTOR_SIZE 512
Pablo Greco 48fc63
+#define CRYPT_MAX_SECTOR_SIZE 4096
Pablo Greco 48fc63
 
Pablo Greco 48fc63
 static const char *arg_type = NULL; /* ANY_LUKS, CRYPT_LUKS1, CRYPT_LUKS2, CRYPT_TCRYPT or CRYPT_PLAIN */
Pablo Greco 48fc63
 static char *arg_cipher = NULL;
Pablo Greco 48fc63
 static unsigned arg_key_size = 0;
Pablo Greco 48fc63
+static unsigned arg_sector_size = CRYPT_SECTOR_SIZE;
Pablo Greco 48fc63
 static int arg_key_slot = CRYPT_ANY_SLOT;
Pablo Greco 48fc63
 static unsigned arg_keyfile_size = 0;
Pablo Greco 48fc63
 static unsigned arg_keyfile_offset = 0;
Pablo Greco 48fc63
@@ -104,6 +108,31 @@ static int parse_one_option(const char *option) {
Pablo Greco 48fc63
 
Pablo Greco 48fc63
                 arg_key_size /= 8;
Pablo Greco 48fc63
 
Pablo Greco 48fc63
+        } else if (startswith(option, "sector-size=")) {
Pablo Greco 48fc63
+
Pablo Greco 48fc63
+#if HAVE_LIBCRYPTSETUP_SECTOR_SIZE
Pablo Greco 48fc63
+                int r;
Pablo Greco 48fc63
+
Pablo Greco 48fc63
+                r = safe_atou(option+12, &arg_sector_size);
Pablo Greco 48fc63
+                if (r < 0) {
Pablo Greco 48fc63
+                        log_error_errno(r, "Failed to parse %s, ignoring: %m", option);
Pablo Greco 48fc63
+                        return 0;
Pablo Greco 48fc63
+                }
Pablo Greco 48fc63
+
Pablo Greco 48fc63
+                if (arg_sector_size % 2) {
Pablo Greco 48fc63
+                        log_error("sector-size= not a multiple of 2, ignoring.");
Pablo Greco 48fc63
+                        return 0;
Pablo Greco 48fc63
+                }
Pablo Greco 48fc63
+
Pablo Greco 48fc63
+                if (arg_sector_size < CRYPT_SECTOR_SIZE || arg_sector_size > CRYPT_MAX_SECTOR_SIZE) {
Pablo Greco 48fc63
+                        log_error("sector-size= is outside of %u and %u, ignoring.", CRYPT_SECTOR_SIZE, CRYPT_MAX_SECTOR_SIZE);
Pablo Greco 48fc63
+                        return 0;
Pablo Greco 48fc63
+                }
Pablo Greco 48fc63
+#else
Pablo Greco 48fc63
+                log_error("sector-size= is not supported, compiled with old libcryptsetup.");
Pablo Greco 48fc63
+                return 0;
Pablo Greco 48fc63
+#endif
Pablo Greco 48fc63
+
Pablo Greco 48fc63
         } else if (startswith(option, "key-slot=")) {
Pablo Greco 48fc63
 
Pablo Greco 48fc63
                 arg_type = ANY_LUKS;
Pablo Greco 48fc63
@@ -450,7 +479,11 @@ static int attach_luks_or_plain(struct crypt_device *cd,
Pablo Greco 48fc63
         }
Pablo Greco 48fc63
 
Pablo Greco 48fc63
         if ((!arg_type && r < 0) || streq_ptr(arg_type, CRYPT_PLAIN)) {
Pablo Greco 48fc63
-                struct crypt_params_plain params = {};
Pablo Greco 48fc63
+                struct crypt_params_plain params = {
Pablo Greco 48fc63
+#if HAVE_LIBCRYPTSETUP_SECTOR_SIZE
Pablo Greco 48fc63
+                        .sector_size = arg_sector_size,
Pablo Greco 48fc63
+#endif
Pablo Greco 48fc63
+                };
Pablo Greco 48fc63
                 const char *cipher, *cipher_mode;
Pablo Greco 48fc63
                 _cleanup_free_ char *truncated_cipher = NULL;
Pablo Greco 48fc63