diff --git a/fs/hmdfs/inode_local.c b/fs/hmdfs/inode_local.c index 94ff9793d092c5e2ea1f946ebbc2f090d2b7d60c..042f2bf65a0b605d4c8a1d344c3c0d81d95206e7 100644 --- a/fs/hmdfs/inode_local.c +++ b/fs/hmdfs/inode_local.c @@ -746,28 +746,23 @@ int hmdfs_rename_local(struct inode *old_dir, struct dentry *old_dentry, static bool symname_is_allowed(const char *symname) { - char *p; - char *buf = 0; - size_t symname_len; + char *p = NULL; + size_t len; - symname_len = strnlen(symname, PATH_MAX); - if (symname_len >= PATH_MAX) + len = strnlen(symname, PATH_MAX); + if (len >= PATH_MAX) return false; - buf = kzalloc(PATH_MAX + 2, GFP_KERNEL); - if (!buf) + p = strstr(symname, "/../"); + if (p) return false; - buf[0] = '/'; - strncpy(buf + 1, symname, symname_len); - strcat(buf, "/"); - p = strstr(buf, "/../"); - if (p) { - kfree(buf); + if (len == 2u && strncmp(symname, "..", 2u) == 0) + return false; + if (len >= 3u && strncmp(symname, "../", 3u) == 0) + return false; + if (len >= 3u && strncmp(symname + len - 3u, "/..", 3u) == 0) return false; - } - - kfree(buf); return true; }