Merge tag 'fixes_for_v4.20-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git...
authorLinus Torvalds <torvalds@linux-foundation.org>
Thu, 29 Nov 2018 17:56:00 +0000 (09:56 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 29 Nov 2018 17:56:00 +0000 (09:56 -0800)
Pull ext2 and udf fixes from Jan Kara:
 "Three small ext2 and udf fixes"

* tag 'fixes_for_v4.20-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs:
  ext2: fix potential use after free
  ext2: initialize opts.s_mount_opt as zero before using it
  udf: Allow mounting volumes with incorrect identification strings

fs/ext2/super.c
fs/ext2/xattr.c
fs/udf/super.c
fs/udf/unicode.c

index cb91baa4275d8150664e05d8a1877ca87fca4ff9..eb11502e3fcd4f10e67fdafdf4f9e7e06e04a5b5 100644 (file)
@@ -892,6 +892,7 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent)
        if (sb->s_magic != EXT2_SUPER_MAGIC)
                goto cantfind_ext2;
 
+       opts.s_mount_opt = 0;
        /* Set defaults before we parse the mount options */
        def_mount_opts = le32_to_cpu(es->s_default_mount_opts);
        if (def_mount_opts & EXT2_DEFM_DEBUG)
index 62d9a659a8ff4e7a3a9556449e35fecc25612e43..dd8f10db82e992da8b8f4fb37699d7bf4a87cf4d 100644 (file)
@@ -612,9 +612,9 @@ skip_replace:
        }
 
 cleanup:
-       brelse(bh);
        if (!(bh && header == HDR(bh)))
                kfree(header);
+       brelse(bh);
        up_write(&EXT2_I(inode)->xattr_sem);
 
        return error;
index 8f2f56d9a1bbfb8b110812d45167ce7e7b456099..e3d684ea320303630f4a75135ed4e4bcc408484c 100644 (file)
@@ -827,16 +827,20 @@ static int udf_load_pvoldesc(struct super_block *sb, sector_t block)
 
 
        ret = udf_dstrCS0toChar(sb, outstr, 31, pvoldesc->volIdent, 32);
-       if (ret < 0)
-               goto out_bh;
-
-       strncpy(UDF_SB(sb)->s_volume_ident, outstr, ret);
+       if (ret < 0) {
+               strcpy(UDF_SB(sb)->s_volume_ident, "InvalidName");
+               pr_warn("incorrect volume identification, setting to "
+                       "'InvalidName'\n");
+       } else {
+               strncpy(UDF_SB(sb)->s_volume_ident, outstr, ret);
+       }
        udf_debug("volIdent[] = '%s'\n", UDF_SB(sb)->s_volume_ident);
 
        ret = udf_dstrCS0toChar(sb, outstr, 127, pvoldesc->volSetIdent, 128);
-       if (ret < 0)
+       if (ret < 0) {
+               ret = 0;
                goto out_bh;
-
+       }
        outstr[ret] = 0;
        udf_debug("volSetIdent[] = '%s'\n", outstr);
 
index 45234791fec281f027cc05b97d9364384d8bc7b8..5fcfa96463ebb820cef33b83460fc8d1a9bea8b2 100644 (file)
@@ -351,6 +351,11 @@ try_again:
        return u_len;
 }
 
+/*
+ * Convert CS0 dstring to output charset. Warning: This function may truncate
+ * input string if it is too long as it is used for informational strings only
+ * and it is better to truncate the string than to refuse mounting a media.
+ */
 int udf_dstrCS0toChar(struct super_block *sb, uint8_t *utf_o, int o_len,
                      const uint8_t *ocu_i, int i_len)
 {
@@ -359,9 +364,12 @@ int udf_dstrCS0toChar(struct super_block *sb, uint8_t *utf_o, int o_len,
        if (i_len > 0) {
                s_len = ocu_i[i_len - 1];
                if (s_len >= i_len) {
-                       pr_err("incorrect dstring lengths (%d/%d)\n",
-                              s_len, i_len);
-                       return -EINVAL;
+                       pr_warn("incorrect dstring lengths (%d/%d),"
+                               " truncating\n", s_len, i_len);
+                       s_len = i_len - 1;
+                       /* 2-byte encoding? Need to round properly... */
+                       if (ocu_i[0] == 16)
+                               s_len -= (s_len - 1) & 2;
                }
        }