Whamcloud - gitweb
LU-17794 crypto: replace 1-element array in llcrypt_symlink_data 05/56105/2
authorJian Yu <yujian@whamcloud.com>
Wed, 21 Aug 2024 06:48:02 +0000 (23:48 -0700)
committerOleg Drokin <green@whamcloud.com>
Fri, 30 Aug 2024 06:01:08 +0000 (06:01 +0000)
This patch replaces 1-element array with flexible array
in 'struct llcrypt_symlink_data' to resolve the
UBSAN array-index-out-of-bounds runtime warning.

Test-Parameters: trivial mdtcount=4 mdscount=2 \
  testlist=sanity,sanity-sec

Test-Parameters: optional mdtcount=4 mdscount=2 \
  clientdistro=ubuntu2404 testlist=sanity,sanity-sec

Change-Id: Ia28297ade23c6f739f4bf2bc5f7a4c0c2280bb24
Signed-off-by: Jian Yu <yujian@whamcloud.com>
Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/56105
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Yang Sheng <ys@whamcloud.com>
Reviewed-by: Sebastien Buisson <sbuisson@ddn.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
libcfs/libcfs/crypto/hooks.c
libcfs/libcfs/crypto/llcrypt_private.h

index 3639951..6f8579d 100644 (file)
@@ -159,10 +159,10 @@ int __llcrypt_prepare_symlink(struct inode *dir, unsigned int len,
         * for now since filesystems will assume it is there and subtract it.
         */
        if (!llcrypt_fname_encrypted_size(dir, len,
-                                         max_len - sizeof(struct llcrypt_symlink_data),
+                                         max_len - sizeof(struct llcrypt_symlink_data) - 1,
                                          &disk_link->len))
                return -ENAMETOOLONG;
-       disk_link->len += sizeof(struct llcrypt_symlink_data);
+       disk_link->len += sizeof(struct llcrypt_symlink_data) + 1;
 
        disk_link->name = NULL;
        return 0;
@@ -192,7 +192,7 @@ int __llcrypt_encrypt_symlink(struct inode *inode, const char *target,
                if (!sd)
                        return -ENOMEM;
        }
-       ciphertext_len = disk_link->len - sizeof(*sd);
+       ciphertext_len = disk_link->len - sizeof(*sd) - 1;
        sd->len = cpu_to_le16(ciphertext_len);
 
        err = fname_encrypt(inode, &iname, sd->encrypted_path, ciphertext_len);
@@ -276,7 +276,7 @@ const char *llcrypt_get_symlink(struct inode *inode, const void *caddr,
                if (cstr.len == 0)
                        return ERR_PTR(-EUCLEAN);
        } else {
-               if (max_size < sizeof(*sd))
+               if (max_size < sizeof(*sd) + 1)
                        return ERR_PTR(-EUCLEAN);
                sd = caddr;
                cstr.name = (unsigned char *)sd->encrypted_path;
@@ -285,7 +285,7 @@ const char *llcrypt_get_symlink(struct inode *inode, const void *caddr,
                if (cstr.len == 0)
                        return ERR_PTR(-EUCLEAN);
 
-               if (cstr.len + sizeof(*sd) - 1 > max_size)
+               if (cstr.len + sizeof(*sd) > max_size)
                        return ERR_PTR(-EUCLEAN);
        }
 
index c2e7596..0a3cfe8 100644 (file)
@@ -161,7 +161,7 @@ llcrypt_is_direct_key_policy(const union llcrypt_policy *policy)
  */
 struct llcrypt_symlink_data {
        __le16 len;
-       char encrypted_path[1];
+       char encrypted_path[];
 } __packed;
 
 /*