--- /dev/null
+From ef85a057b5ffa75faeb5ffc8aa9bcf0b96b65f59 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 1 Jun 2020 13:08:05 -0700
+Subject: f2fs: avoid utf8_strncasecmp() with unstable name
+
+From: Eric Biggers <ebiggers@google.com>
+
+[ Upstream commit fc3bb095ab02b9e7d89a069ade2cead15c64c504 ]
+
+If the dentry name passed to ->d_compare() fits in dentry::d_iname, then
+it may be concurrently modified by a rename. This can cause undefined
+behavior (possibly out-of-bounds memory accesses or crashes) in
+utf8_strncasecmp(), since fs/unicode/ isn't written to handle strings
+that may be concurrently modified.
+
+Fix this by first copying the filename to a stack buffer if needed.
+This way we get a stable snapshot of the filename.
+
+Fixes: 2c2eb7a300cd ("f2fs: Support case-insensitive file name lookups")
+Cc: <stable@vger.kernel.org> # v5.4+
+Cc: Al Viro <viro@zeniv.linux.org.uk>
+Cc: Daniel Rosenberg <drosen@google.com>
+Cc: Gabriel Krisman Bertazi <krisman@collabora.co.uk>
+Signed-off-by: Eric Biggers <ebiggers@google.com>
+Reviewed-by: Chao Yu <yuchao0@huawei.com>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/f2fs/dir.c | 16 ++++++++++++++++
+ 1 file changed, 16 insertions(+)
+
+diff --git a/fs/f2fs/dir.c b/fs/f2fs/dir.c
+index 44eb12a00cd0e..54e90dbb09e78 100644
+--- a/fs/f2fs/dir.c
++++ b/fs/f2fs/dir.c
+@@ -1076,11 +1076,27 @@ static int f2fs_d_compare(const struct dentry *dentry, unsigned int len,
+ const struct inode *dir = READ_ONCE(parent->d_inode);
+ const struct f2fs_sb_info *sbi = F2FS_SB(dentry->d_sb);
+ struct qstr entry = QSTR_INIT(str, len);
++ char strbuf[DNAME_INLINE_LEN];
+ int res;
+
+ if (!dir || !IS_CASEFOLDED(dir))
+ goto fallback;
+
++ /*
++ * If the dentry name is stored in-line, then it may be concurrently
++ * modified by a rename. If this happens, the VFS will eventually retry
++ * the lookup, so it doesn't matter what ->d_compare() returns.
++ * However, it's unsafe to call utf8_strncasecmp() with an unstable
++ * string. Therefore, we have to copy the name into a temporary buffer.
++ */
++ if (len <= DNAME_INLINE_LEN - 1) {
++ memcpy(strbuf, str, len);
++ strbuf[len] = 0;
++ entry.name = strbuf;
++ /* prevent compiler from optimizing out the temporary buffer */
++ barrier();
++ }
++
+ res = utf8_strncasecmp(sbi->s_encoding, name, &entry);
+ if (res >= 0)
+ return res;
+--
+2.25.1
+
--- /dev/null
+From c451a515920bdc58e07752bf901ffc02bc8594d9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 7 May 2020 00:59:03 -0700
+Subject: f2fs: split f2fs_d_compare() from f2fs_match_name()
+
+From: Eric Biggers <ebiggers@google.com>
+
+[ Upstream commit f874fa1c7c7905c1744a2037a11516558ed00a81 ]
+
+Sharing f2fs_ci_compare() between comparing cached dentries
+(f2fs_d_compare()) and comparing on-disk dentries (f2fs_match_name())
+doesn't work as well as intended, as these actions fundamentally differ
+in several ways (e.g. whether the task may sleep, whether the directory
+is stable, whether the casefolded name was precomputed, whether the
+dentry will need to be decrypted once we allow casefold+encrypt, etc.)
+
+Just make f2fs_d_compare() implement what it needs directly, and rework
+f2fs_ci_compare() to be specialized for f2fs_match_name().
+
+Signed-off-by: Eric Biggers <ebiggers@google.com>
+Reviewed-by: Chao Yu <yuchao0@huawei.com>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/f2fs/dir.c | 70 +++++++++++++++++++++++++-------------------------
+ fs/f2fs/f2fs.h | 5 ----
+ 2 files changed, 35 insertions(+), 40 deletions(-)
+
+diff --git a/fs/f2fs/dir.c b/fs/f2fs/dir.c
+index 44bfc464df787..44eb12a00cd0e 100644
+--- a/fs/f2fs/dir.c
++++ b/fs/f2fs/dir.c
+@@ -107,36 +107,28 @@ static struct f2fs_dir_entry *find_in_block(struct inode *dir,
+ /*
+ * Test whether a case-insensitive directory entry matches the filename
+ * being searched for.
+- *
+- * Returns: 0 if the directory entry matches, more than 0 if it
+- * doesn't match or less than zero on error.
+ */
+-int f2fs_ci_compare(const struct inode *parent, const struct qstr *name,
+- const struct qstr *entry, bool quick)
++static bool f2fs_match_ci_name(const struct inode *dir, const struct qstr *name,
++ const struct qstr *entry, bool quick)
+ {
+- const struct f2fs_sb_info *sbi = F2FS_SB(parent->i_sb);
++ const struct f2fs_sb_info *sbi = F2FS_SB(dir->i_sb);
+ const struct unicode_map *um = sbi->s_encoding;
+- int ret;
++ int res;
+
+ if (quick)
+- ret = utf8_strncasecmp_folded(um, name, entry);
++ res = utf8_strncasecmp_folded(um, name, entry);
+ else
+- ret = utf8_strncasecmp(um, name, entry);
+-
+- if (ret < 0) {
+- /* Handle invalid character sequence as either an error
+- * or as an opaque byte sequence.
++ res = utf8_strncasecmp(um, name, entry);
++ if (res < 0) {
++ /*
++ * In strict mode, ignore invalid names. In non-strict mode,
++ * fall back to treating them as opaque byte sequences.
+ */
+- if (f2fs_has_strict_mode(sbi))
+- return -EINVAL;
+-
+- if (name->len != entry->len)
+- return 1;
+-
+- return !!memcmp(name->name, entry->name, name->len);
++ if (f2fs_has_strict_mode(sbi) || name->len != entry->len)
++ return false;
++ return !memcmp(name->name, entry->name, name->len);
+ }
+-
+- return ret;
++ return res == 0;
+ }
+
+ static void f2fs_fname_setup_ci_filename(struct inode *dir,
+@@ -188,10 +180,10 @@ static inline bool f2fs_match_name(struct f2fs_dentry_ptr *d,
+ if (cf_str->name) {
+ struct qstr cf = {.name = cf_str->name,
+ .len = cf_str->len};
+- return !f2fs_ci_compare(parent, &cf, &entry, true);
++ return f2fs_match_ci_name(parent, &cf, &entry, true);
+ }
+- return !f2fs_ci_compare(parent, fname->usr_fname, &entry,
+- false);
++ return f2fs_match_ci_name(parent, fname->usr_fname, &entry,
++ false);
+ }
+ #endif
+ if (fscrypt_match_name(fname, d->filename[bit_pos],
+@@ -1080,17 +1072,25 @@ const struct file_operations f2fs_dir_operations = {
+ static int f2fs_d_compare(const struct dentry *dentry, unsigned int len,
+ const char *str, const struct qstr *name)
+ {
+- struct qstr qstr = {.name = str, .len = len };
+ const struct dentry *parent = READ_ONCE(dentry->d_parent);
+- const struct inode *inode = READ_ONCE(parent->d_inode);
+-
+- if (!inode || !IS_CASEFOLDED(inode)) {
+- if (len != name->len)
+- return -1;
+- return memcmp(str, name->name, len);
+- }
+-
+- return f2fs_ci_compare(inode, name, &qstr, false);
++ const struct inode *dir = READ_ONCE(parent->d_inode);
++ const struct f2fs_sb_info *sbi = F2FS_SB(dentry->d_sb);
++ struct qstr entry = QSTR_INIT(str, len);
++ int res;
++
++ if (!dir || !IS_CASEFOLDED(dir))
++ goto fallback;
++
++ res = utf8_strncasecmp(sbi->s_encoding, name, &entry);
++ if (res >= 0)
++ return res;
++
++ if (f2fs_has_strict_mode(sbi))
++ return -EINVAL;
++fallback:
++ if (len != name->len)
++ return 1;
++ return !!memcmp(str, name->name, len);
+ }
+
+ static int f2fs_d_hash(const struct dentry *dentry, struct qstr *str)
+diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
+index 555c84953ea81..5a0f95dfbac2b 100644
+--- a/fs/f2fs/f2fs.h
++++ b/fs/f2fs/f2fs.h
+@@ -3101,11 +3101,6 @@ int f2fs_update_extension_list(struct f2fs_sb_info *sbi, const char *name,
+ bool hot, bool set);
+ struct dentry *f2fs_get_parent(struct dentry *child);
+
+-extern int f2fs_ci_compare(const struct inode *parent,
+- const struct qstr *name,
+- const struct qstr *entry,
+- bool quick);
+-
+ /*
+ * dir.c
+ */
+--
+2.25.1
+
--- /dev/null
+From 2dc42b46d9f30301a974d47aacce2bcfa8091a4e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 1 Jun 2020 19:45:26 +0300
+Subject: net/mlx5: DR, Fix freeing in dr_create_rc_qp()
+
+From: Denis Efremov <efremov@linux.com>
+
+[ Upstream commit 47a357de2b6b706af3c9471d5042f9ba8907031e ]
+
+Variable "in" in dr_create_rc_qp() is allocated with kvzalloc() and
+should be freed with kvfree().
+
+Fixes: 297cccebdc5a ("net/mlx5: DR, Expose an internal API to issue RDMA operations")
+Cc: stable@vger.kernel.org
+Signed-off-by: Denis Efremov <efremov@linux.com>
+Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/steering/dr_send.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_send.c b/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_send.c
+index 18719acb7e547..eff8bb64899d6 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_send.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_send.c
+@@ -181,7 +181,7 @@ static struct mlx5dr_qp *dr_create_rc_qp(struct mlx5_core_dev *mdev,
+ in, pas));
+
+ err = mlx5_core_create_qp(mdev, &dr_qp->mqp, in, inlen);
+- kfree(in);
++ kvfree(in);
+
+ if (err) {
+ mlx5_core_warn(mdev, " Can't create QP\n");
+--
+2.25.1
+