Whamcloud - gitweb
LU-6020 kerberos: proper sg list initialization 31/13631/3
authorAndrew Perepechko <andrew.perepechko@seagate.com>
Wed, 4 Feb 2015 13:50:10 +0000 (16:50 +0300)
committerOleg Drokin <oleg.drokin@intel.com>
Sun, 8 Mar 2015 11:45:06 +0000 (11:45 +0000)
This patch adds sg_init_table() calls in order
to have proper sg list initialization including
magics, tables sizes, etc.

Without it, when using kernels with CONFIG_DEBUG_SG
option, the following crash can happen:

kernel BUG at include/linux/scatterlist.h:65!
invalid opcode: 0000 [#1] SMP DEBUG_PAGEALLOC
last sysfs file: /sys/devices/system/cpu/online
CPU 0

Pid: 4911, comm: ptlrpcd_3 Not tainted 2.6.32-431 #7                  /D525MWV
RIP: 0010:[<ffffffffa0b60170>]  [<ffffffffa0b60170>] krb5_make_checksum+0x750/0x770 [ptlrpc_gss]

Change-Id: Ic6c52c8b15393d8d7f67f4bf675c1f57cf27004a
Signed-off-by: Andrew Perepechko <andrew.perepechko@seagate.com>
Reviewed-on: http://review.whamcloud.com/13631
Reviewed-by: Andreas Dilger <andreas.dilger@intel.com>
Tested-by: Jenkins
Tested-by: Maloo <hpdd-maloo@intel.com>
Reviewed-by: Nathaniel Clark <nathaniel.l.clark@intel.com>
lustre/ptlrpc/gss/gss_krb5_mech.c

index c6d85d0..9ca5457 100644 (file)
@@ -602,6 +602,7 @@ int krb5_digest_hmac(struct crypto_hash *tfm,
                 if (iovs[i].kiov_len == 0)
                         continue;
 
                 if (iovs[i].kiov_len == 0)
                         continue;
 
+               sg_init_table(sg, 1);
                sg_set_page(&sg[0], iovs[i].kiov_page, iovs[i].kiov_len,
                            iovs[i].kiov_offset);
                crypto_hash_update(&desc, sg, iovs[i].kiov_len);
                sg_set_page(&sg[0], iovs[i].kiov_page, iovs[i].kiov_len,
                            iovs[i].kiov_offset);
                crypto_hash_update(&desc, sg, iovs[i].kiov_len);
@@ -644,6 +645,7 @@ int krb5_digest_norm(struct crypto_hash *tfm,
                 if (iovs[i].kiov_len == 0)
                         continue;
 
                 if (iovs[i].kiov_len == 0)
                         continue;
 
+               sg_init_table(sg, 1);
                sg_set_page(&sg[0], iovs[i].kiov_page, iovs[i].kiov_len,
                            iovs[i].kiov_offset);
                crypto_hash_update(&desc, sg, iovs[i].kiov_len);
                sg_set_page(&sg[0], iovs[i].kiov_page, iovs[i].kiov_len,
                            iovs[i].kiov_offset);
                crypto_hash_update(&desc, sg, iovs[i].kiov_len);
@@ -970,12 +972,14 @@ int krb5_encrypt_bulk(struct crypto_blkcipher *tfm,
 
         /* encrypt clear pages */
         for (i = 0; i < desc->bd_iov_count; i++) {
 
         /* encrypt clear pages */
         for (i = 0; i < desc->bd_iov_count; i++) {
+               sg_init_table(&src, 1);
                sg_set_page(&src, desc->bd_iov[i].kiov_page,
                            (desc->bd_iov[i].kiov_len + blocksize - 1) &
                            (~(blocksize - 1)),
                            desc->bd_iov[i].kiov_offset);
                if (adj_nob)
                        nob += src.length;
                sg_set_page(&src, desc->bd_iov[i].kiov_page,
                            (desc->bd_iov[i].kiov_len + blocksize - 1) &
                            (~(blocksize - 1)),
                            desc->bd_iov[i].kiov_offset);
                if (adj_nob)
                        nob += src.length;
+               sg_init_table(&dst, 1);
                sg_set_page(&dst, desc->bd_enc_iov[i].kiov_page, src.length,
                            src.offset);
 
                sg_set_page(&dst, desc->bd_enc_iov[i].kiov_page, src.length,
                            src.offset);
 
@@ -1094,6 +1098,7 @@ int krb5_decrypt_bulk(struct crypto_blkcipher *tfm,
                 if (desc->bd_enc_iov[i].kiov_len == 0)
                         continue;
 
                 if (desc->bd_enc_iov[i].kiov_len == 0)
                         continue;
 
+               sg_init_table(&src, 1);
                sg_set_page(&src, desc->bd_enc_iov[i].kiov_page,
                            desc->bd_enc_iov[i].kiov_len,
                            desc->bd_enc_iov[i].kiov_offset);
                sg_set_page(&src, desc->bd_enc_iov[i].kiov_page,
                            desc->bd_enc_iov[i].kiov_len,
                            desc->bd_enc_iov[i].kiov_offset);