|
Kmods SIG |
63c143 |
From 4dbe8e4413d70ac4f163592d69eef74d7824783a Mon Sep 17 00:00:00 2001
|
|
Kmods SIG |
63c143 |
From: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
|
|
Kmods SIG |
63c143 |
Date: Mon, 4 Oct 2021 18:59:55 +0300
|
|
Kmods SIG |
63c143 |
Subject: [Backport 4dbe8e4413d7] src: Refactor ntfs_readlink_hlp
|
|
Kmods SIG |
63c143 |
|
|
Kmods SIG |
63c143 |
Rename some variables.
|
|
Kmods SIG |
63c143 |
Returned err by default is EINVAL.
|
|
Kmods SIG |
63c143 |
|
|
Kmods SIG |
63c143 |
Signed-off-by: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
|
|
Kmods SIG |
63c143 |
---
|
|
Kmods SIG |
63c143 |
src/inode.c | 91 +++++++++++++++++++++++-------------------------
|
|
Kmods SIG |
63c143 |
1 file changed, 43 insertions(+), 48 deletions(-)
|
|
Kmods SIG |
63c143 |
|
|
Kmods SIG |
63c143 |
diff --git a/src/inode.c b/src/inode.c
|
|
Kmods SIG |
63c143 |
index 7dd162f6a7e26435b16c08b5efed6e283b975f54..d618b0573533c043acd2fadc59a20e9ce0c772cb 100644
|
|
Kmods SIG |
63c143 |
--- a/src/inode.c
|
|
Kmods SIG |
63c143 |
+++ b/src/inode.c
|
|
Kmods SIG |
63c143 |
@@ -1763,15 +1763,15 @@ void ntfs_evict_inode(struct inode *inode)
|
|
Kmods SIG |
63c143 |
static noinline int ntfs_readlink_hlp(struct inode *inode, char *buffer,
|
|
Kmods SIG |
63c143 |
int buflen)
|
|
Kmods SIG |
63c143 |
{
|
|
Kmods SIG |
63c143 |
- int i, err = 0;
|
|
Kmods SIG |
63c143 |
+ int i, err = -EINVAL;
|
|
Kmods SIG |
63c143 |
struct ntfs_inode *ni = ntfs_i(inode);
|
|
Kmods SIG |
63c143 |
struct super_block *sb = inode->i_sb;
|
|
Kmods SIG |
63c143 |
struct ntfs_sb_info *sbi = sb->s_fs_info;
|
|
Kmods SIG |
63c143 |
- u64 i_size = inode->i_size;
|
|
Kmods SIG |
63c143 |
- u16 nlen = 0;
|
|
Kmods SIG |
63c143 |
+ u64 size;
|
|
Kmods SIG |
63c143 |
+ u16 ulen = 0;
|
|
Kmods SIG |
63c143 |
void *to_free = NULL;
|
|
Kmods SIG |
63c143 |
struct REPARSE_DATA_BUFFER *rp;
|
|
Kmods SIG |
63c143 |
- struct le_str *uni;
|
|
Kmods SIG |
63c143 |
+ const __le16 *uname;
|
|
Kmods SIG |
63c143 |
struct ATTRIB *attr;
|
|
Kmods SIG |
63c143 |
|
|
Kmods SIG |
63c143 |
/* Reparse data present. Try to parse it. */
|
|
Kmods SIG |
63c143 |
@@ -1780,68 +1780,64 @@ static noinline int ntfs_readlink_hlp(struct inode *inode, char *buffer,
|
|
Kmods SIG |
63c143 |
|
|
Kmods SIG |
63c143 |
*buffer = 0;
|
|
Kmods SIG |
63c143 |
|
|
Kmods SIG |
63c143 |
- /* Read into temporal buffer. */
|
|
Kmods SIG |
63c143 |
- if (i_size > sbi->reparse.max_size || i_size <= sizeof(u32)) {
|
|
Kmods SIG |
63c143 |
- err = -EINVAL;
|
|
Kmods SIG |
63c143 |
- goto out;
|
|
Kmods SIG |
63c143 |
- }
|
|
Kmods SIG |
63c143 |
-
|
|
Kmods SIG |
63c143 |
attr = ni_find_attr(ni, NULL, NULL, ATTR_REPARSE, NULL, 0, NULL, NULL);
|
|
Kmods SIG |
63c143 |
- if (!attr) {
|
|
Kmods SIG |
63c143 |
- err = -EINVAL;
|
|
Kmods SIG |
63c143 |
+ if (!attr)
|
|
Kmods SIG |
63c143 |
goto out;
|
|
Kmods SIG |
63c143 |
- }
|
|
Kmods SIG |
63c143 |
|
|
Kmods SIG |
63c143 |
if (!attr->non_res) {
|
|
Kmods SIG |
63c143 |
- rp = resident_data_ex(attr, i_size);
|
|
Kmods SIG |
63c143 |
- if (!rp) {
|
|
Kmods SIG |
63c143 |
- err = -EINVAL;
|
|
Kmods SIG |
63c143 |
+ rp = resident_data_ex(attr, sizeof(struct REPARSE_DATA_BUFFER));
|
|
Kmods SIG |
63c143 |
+ if (!rp)
|
|
Kmods SIG |
63c143 |
goto out;
|
|
Kmods SIG |
63c143 |
- }
|
|
Kmods SIG |
63c143 |
+ size = le32_to_cpu(attr->res.data_size);
|
|
Kmods SIG |
63c143 |
} else {
|
|
Kmods SIG |
63c143 |
- rp = kmalloc(i_size, GFP_NOFS);
|
|
Kmods SIG |
63c143 |
+ size = le64_to_cpu(attr->nres.data_size);
|
|
Kmods SIG |
63c143 |
+ rp = NULL;
|
|
Kmods SIG |
63c143 |
+ }
|
|
Kmods SIG |
63c143 |
+
|
|
Kmods SIG |
63c143 |
+ if (size > sbi->reparse.max_size || size <= sizeof(u32))
|
|
Kmods SIG |
63c143 |
+ goto out;
|
|
Kmods SIG |
63c143 |
+
|
|
Kmods SIG |
63c143 |
+ if (!rp) {
|
|
Kmods SIG |
63c143 |
+ rp = kmalloc(size, GFP_NOFS);
|
|
Kmods SIG |
63c143 |
if (!rp) {
|
|
Kmods SIG |
63c143 |
err = -ENOMEM;
|
|
Kmods SIG |
63c143 |
goto out;
|
|
Kmods SIG |
63c143 |
}
|
|
Kmods SIG |
63c143 |
to_free = rp;
|
|
Kmods SIG |
63c143 |
- err = ntfs_read_run_nb(sbi, &ni->file.run, 0, rp, i_size, NULL);
|
|
Kmods SIG |
63c143 |
+ /* Read into temporal buffer. */
|
|
Kmods SIG |
63c143 |
+ err = ntfs_read_run_nb(sbi, &ni->file.run, 0, rp, size, NULL);
|
|
Kmods SIG |
63c143 |
if (err)
|
|
Kmods SIG |
63c143 |
goto out;
|
|
Kmods SIG |
63c143 |
}
|
|
Kmods SIG |
63c143 |
|
|
Kmods SIG |
63c143 |
- err = -EINVAL;
|
|
Kmods SIG |
63c143 |
-
|
|
Kmods SIG |
63c143 |
/* Microsoft Tag. */
|
|
Kmods SIG |
63c143 |
switch (rp->ReparseTag) {
|
|
Kmods SIG |
63c143 |
case IO_REPARSE_TAG_MOUNT_POINT:
|
|
Kmods SIG |
63c143 |
/* Mount points and junctions. */
|
|
Kmods SIG |
63c143 |
/* Can we use 'Rp->MountPointReparseBuffer.PrintNameLength'? */
|
|
Kmods SIG |
63c143 |
- if (i_size <= offsetof(struct REPARSE_DATA_BUFFER,
|
|
Kmods SIG |
63c143 |
- MountPointReparseBuffer.PathBuffer))
|
|
Kmods SIG |
63c143 |
+ if (size <= offsetof(struct REPARSE_DATA_BUFFER,
|
|
Kmods SIG |
63c143 |
+ MountPointReparseBuffer.PathBuffer))
|
|
Kmods SIG |
63c143 |
goto out;
|
|
Kmods SIG |
63c143 |
- uni = Add2Ptr(rp,
|
|
Kmods SIG |
63c143 |
- offsetof(struct REPARSE_DATA_BUFFER,
|
|
Kmods SIG |
63c143 |
- MountPointReparseBuffer.PathBuffer) +
|
|
Kmods SIG |
63c143 |
- le16_to_cpu(rp->MountPointReparseBuffer
|
|
Kmods SIG |
63c143 |
- .PrintNameOffset) -
|
|
Kmods SIG |
63c143 |
- 2);
|
|
Kmods SIG |
63c143 |
- nlen = le16_to_cpu(rp->MountPointReparseBuffer.PrintNameLength);
|
|
Kmods SIG |
63c143 |
+ uname = Add2Ptr(rp,
|
|
Kmods SIG |
63c143 |
+ offsetof(struct REPARSE_DATA_BUFFER,
|
|
Kmods SIG |
63c143 |
+ MountPointReparseBuffer.PathBuffer) +
|
|
Kmods SIG |
63c143 |
+ le16_to_cpu(rp->MountPointReparseBuffer
|
|
Kmods SIG |
63c143 |
+ .PrintNameOffset));
|
|
Kmods SIG |
63c143 |
+ ulen = le16_to_cpu(rp->MountPointReparseBuffer.PrintNameLength);
|
|
Kmods SIG |
63c143 |
break;
|
|
Kmods SIG |
63c143 |
|
|
Kmods SIG |
63c143 |
case IO_REPARSE_TAG_SYMLINK:
|
|
Kmods SIG |
63c143 |
/* FolderSymbolicLink */
|
|
Kmods SIG |
63c143 |
/* Can we use 'Rp->SymbolicLinkReparseBuffer.PrintNameLength'? */
|
|
Kmods SIG |
63c143 |
- if (i_size <= offsetof(struct REPARSE_DATA_BUFFER,
|
|
Kmods SIG |
63c143 |
- SymbolicLinkReparseBuffer.PathBuffer))
|
|
Kmods SIG |
63c143 |
+ if (size <= offsetof(struct REPARSE_DATA_BUFFER,
|
|
Kmods SIG |
63c143 |
+ SymbolicLinkReparseBuffer.PathBuffer))
|
|
Kmods SIG |
63c143 |
goto out;
|
|
Kmods SIG |
63c143 |
- uni = Add2Ptr(rp,
|
|
Kmods SIG |
63c143 |
- offsetof(struct REPARSE_DATA_BUFFER,
|
|
Kmods SIG |
63c143 |
- SymbolicLinkReparseBuffer.PathBuffer) +
|
|
Kmods SIG |
63c143 |
- le16_to_cpu(rp->SymbolicLinkReparseBuffer
|
|
Kmods SIG |
63c143 |
- .PrintNameOffset) -
|
|
Kmods SIG |
63c143 |
- 2);
|
|
Kmods SIG |
63c143 |
- nlen = le16_to_cpu(
|
|
Kmods SIG |
63c143 |
+ uname = Add2Ptr(
|
|
Kmods SIG |
63c143 |
+ rp, offsetof(struct REPARSE_DATA_BUFFER,
|
|
Kmods SIG |
63c143 |
+ SymbolicLinkReparseBuffer.PathBuffer) +
|
|
Kmods SIG |
63c143 |
+ le16_to_cpu(rp->SymbolicLinkReparseBuffer
|
|
Kmods SIG |
63c143 |
+ .PrintNameOffset));
|
|
Kmods SIG |
63c143 |
+ ulen = le16_to_cpu(
|
|
Kmods SIG |
63c143 |
rp->SymbolicLinkReparseBuffer.PrintNameLength);
|
|
Kmods SIG |
63c143 |
break;
|
|
Kmods SIG |
63c143 |
|
|
Kmods SIG |
63c143 |
@@ -1873,29 +1869,28 @@ static noinline int ntfs_readlink_hlp(struct inode *inode, char *buffer,
|
|
Kmods SIG |
63c143 |
goto out;
|
|
Kmods SIG |
63c143 |
}
|
|
Kmods SIG |
63c143 |
if (!IsReparseTagNameSurrogate(rp->ReparseTag) ||
|
|
Kmods SIG |
63c143 |
- i_size <= sizeof(struct REPARSE_POINT)) {
|
|
Kmods SIG |
63c143 |
+ size <= sizeof(struct REPARSE_POINT)) {
|
|
Kmods SIG |
63c143 |
goto out;
|
|
Kmods SIG |
63c143 |
}
|
|
Kmods SIG |
63c143 |
|
|
Kmods SIG |
63c143 |
/* Users tag. */
|
|
Kmods SIG |
63c143 |
- uni = Add2Ptr(rp, sizeof(struct REPARSE_POINT) - 2);
|
|
Kmods SIG |
63c143 |
- nlen = le16_to_cpu(rp->ReparseDataLength) -
|
|
Kmods SIG |
63c143 |
+ uname = Add2Ptr(rp, sizeof(struct REPARSE_POINT));
|
|
Kmods SIG |
63c143 |
+ ulen = le16_to_cpu(rp->ReparseDataLength) -
|
|
Kmods SIG |
63c143 |
sizeof(struct REPARSE_POINT);
|
|
Kmods SIG |
63c143 |
}
|
|
Kmods SIG |
63c143 |
|
|
Kmods SIG |
63c143 |
/* Convert nlen from bytes to UNICODE chars. */
|
|
Kmods SIG |
63c143 |
- nlen >>= 1;
|
|
Kmods SIG |
63c143 |
+ ulen >>= 1;
|
|
Kmods SIG |
63c143 |
|
|
Kmods SIG |
63c143 |
/* Check that name is available. */
|
|
Kmods SIG |
63c143 |
- if (!nlen || &uni->name[nlen] > (__le16 *)Add2Ptr(rp, i_size))
|
|
Kmods SIG |
63c143 |
+ if (!ulen || uname + ulen > (__le16 *)Add2Ptr(rp, size))
|
|
Kmods SIG |
63c143 |
goto out;
|
|
Kmods SIG |
63c143 |
|
|
Kmods SIG |
63c143 |
/* If name is already zero terminated then truncate it now. */
|
|
Kmods SIG |
63c143 |
- if (!uni->name[nlen - 1])
|
|
Kmods SIG |
63c143 |
- nlen -= 1;
|
|
Kmods SIG |
63c143 |
- uni->len = nlen;
|
|
Kmods SIG |
63c143 |
+ if (!uname[ulen - 1])
|
|
Kmods SIG |
63c143 |
+ ulen -= 1;
|
|
Kmods SIG |
63c143 |
|
|
Kmods SIG |
63c143 |
- err = ntfs_utf16_to_nls(sbi, uni, buffer, buflen);
|
|
Kmods SIG |
63c143 |
+ err = ntfs_utf16_to_nls(sbi, uname, ulen, buffer, buflen);
|
|
Kmods SIG |
63c143 |
|
|
Kmods SIG |
63c143 |
if (err < 0)
|
|
Kmods SIG |
63c143 |
goto out;
|
|
Kmods SIG |
63c143 |
--
|
|
Kmods SIG |
63c143 |
2.31.1
|
|
Kmods SIG |
63c143 |
|