* [PATCH][next] hfsplus: Fix out-of-bounds warnings in __hfsplus_setxattr
@ 2021-03-30 14:52 Gustavo A. R. Silva
2021-03-31 4:43 ` Andrew Morton
0 siblings, 1 reply; 4+ messages in thread
From: Gustavo A. R. Silva @ 2021-03-30 14:52 UTC (permalink / raw)
To: Andrew Morton
Cc: linux-fsdevel, linux-kernel, Gustavo A. R. Silva, linux-hardening
Fix the following out-of-bounds warnings by enclosing
structure members file and finder into new struct info:
fs/hfsplus/xattr.c:300:5: warning: 'memcpy' offset [65, 80] from the object at 'entry' is out of the bounds of referenced subobject 'user_info' with type 'struct DInfo' at offset 48 [-Warray-bounds]
fs/hfsplus/xattr.c:313:5: warning: 'memcpy' offset [65, 80] from the object at 'entry' is out of the bounds of referenced subobject 'user_info' with type 'struct FInfo' at offset 48 [-Warray-bounds]
Refactor the code by making it more "structured."
Also, this helps with the ongoing efforts to enable -Warray-bounds and
makes the code clearer and avoid confusing the compiler.
Link: https://github.com/KSPP/linux/issues/109
Reported-by: kernel test robot <lkp@intel.com>
Signed-off-by: Gustavo A. R. Silva <gustavoars@kernel.org>
---
fs/hfsplus/catalog.c | 16 ++++++++--------
fs/hfsplus/dir.c | 4 ++--
fs/hfsplus/hfsplus_raw.h | 12 ++++++++----
fs/hfsplus/xattr.c | 18 ++++++++----------
4 files changed, 26 insertions(+), 24 deletions(-)
diff --git a/fs/hfsplus/catalog.c b/fs/hfsplus/catalog.c
index 35472cba750e..9cdc6550b468 100644
--- a/fs/hfsplus/catalog.c
+++ b/fs/hfsplus/catalog.c
@@ -124,7 +124,7 @@ static int hfsplus_cat_build_record(hfsplus_cat_entry *entry,
hfsplus_cat_set_perms(inode, &folder->permissions);
if (inode == sbi->hidden_dir)
/* invisible and namelocked */
- folder->user_info.frFlags = cpu_to_be16(0x5000);
+ folder->info.user.frFlags = cpu_to_be16(0x5000);
return sizeof(*folder);
} else {
struct hfsplus_cat_file *file;
@@ -142,14 +142,14 @@ static int hfsplus_cat_build_record(hfsplus_cat_entry *entry,
if (cnid == inode->i_ino) {
hfsplus_cat_set_perms(inode, &file->permissions);
if (S_ISLNK(inode->i_mode)) {
- file->user_info.fdType =
+ file->info.user.fdType =
cpu_to_be32(HFSP_SYMLINK_TYPE);
- file->user_info.fdCreator =
+ file->info.user.fdCreator =
cpu_to_be32(HFSP_SYMLINK_CREATOR);
} else {
- file->user_info.fdType =
+ file->info.user.fdType =
cpu_to_be32(sbi->type);
- file->user_info.fdCreator =
+ file->info.user.fdCreator =
cpu_to_be32(sbi->creator);
}
if (HFSPLUS_FLG_IMMUTABLE &
@@ -158,11 +158,11 @@ static int hfsplus_cat_build_record(hfsplus_cat_entry *entry,
file->flags |=
cpu_to_be16(HFSPLUS_FILE_LOCKED);
} else {
- file->user_info.fdType =
+ file->info.user.fdType =
cpu_to_be32(HFSP_HARDLINK_TYPE);
- file->user_info.fdCreator =
+ file->info.user.fdCreator =
cpu_to_be32(HFSP_HFSPLUS_CREATOR);
- file->user_info.fdFlags =
+ file->info.user.fdFlags =
cpu_to_be16(0x100);
file->create_date =
HFSPLUS_I(sbi->hidden_dir)->create_date;
diff --git a/fs/hfsplus/dir.c b/fs/hfsplus/dir.c
index 03e6c046faf4..0ae8f797d7f3 100644
--- a/fs/hfsplus/dir.c
+++ b/fs/hfsplus/dir.c
@@ -73,9 +73,9 @@ static struct dentry *hfsplus_lookup(struct inode *dir, struct dentry *dentry,
goto fail;
}
cnid = be32_to_cpu(entry.file.id);
- if (entry.file.user_info.fdType ==
+ if (entry.file.info.user.fdType ==
cpu_to_be32(HFSP_HARDLINK_TYPE) &&
- entry.file.user_info.fdCreator ==
+ entry.file.info.user.fdCreator ==
cpu_to_be32(HFSP_HFSPLUS_CREATOR) &&
HFSPLUS_SB(sb)->hidden_dir &&
(entry.file.create_date ==
diff --git a/fs/hfsplus/hfsplus_raw.h b/fs/hfsplus/hfsplus_raw.h
index 456e87aec7fd..005a043bc7ee 100644
--- a/fs/hfsplus/hfsplus_raw.h
+++ b/fs/hfsplus/hfsplus_raw.h
@@ -260,8 +260,10 @@ struct hfsplus_cat_folder {
__be32 access_date;
__be32 backup_date;
struct hfsplus_perm permissions;
- struct DInfo user_info;
- struct DXInfo finder_info;
+ struct {
+ struct DInfo user;
+ struct DXInfo finder;
+ } info;
__be32 text_encoding;
__be32 subfolders; /* Subfolder count in HFSX. Reserved in HFS+. */
} __packed;
@@ -294,8 +296,10 @@ struct hfsplus_cat_file {
__be32 access_date;
__be32 backup_date;
struct hfsplus_perm permissions;
- struct FInfo user_info;
- struct FXInfo finder_info;
+ struct {
+ struct FInfo user;
+ struct FXInfo finder;
+ } info;
__be32 text_encoding;
u32 reserved2;
diff --git a/fs/hfsplus/xattr.c b/fs/hfsplus/xattr.c
index 4d169c5a2673..e18a472ac937 100644
--- a/fs/hfsplus/xattr.c
+++ b/fs/hfsplus/xattr.c
@@ -262,10 +262,8 @@ int __hfsplus_setxattr(struct inode *inode, const char *name,
struct hfs_find_data cat_fd;
hfsplus_cat_entry entry;
u16 cat_entry_flags, cat_entry_type;
- u16 folder_finderinfo_len = sizeof(struct DInfo) +
- sizeof(struct DXInfo);
- u16 file_finderinfo_len = sizeof(struct FInfo) +
- sizeof(struct FXInfo);
+ u16 folder_finderinfo_len = sizeof(entry.folder.info);
+ u16 file_finderinfo_len = sizeof(entry.file.info);
if ((!S_ISREG(inode->i_mode) &&
!S_ISDIR(inode->i_mode)) ||
@@ -297,7 +295,7 @@ int __hfsplus_setxattr(struct inode *inode, const char *name,
sizeof(hfsplus_cat_entry));
if (be16_to_cpu(entry.type) == HFSPLUS_FOLDER) {
if (size == folder_finderinfo_len) {
- memcpy(&entry.folder.user_info, value,
+ memcpy(&entry.folder.info, value,
folder_finderinfo_len);
hfs_bnode_write(cat_fd.bnode, &entry,
cat_fd.entryoffset,
@@ -310,7 +308,7 @@ int __hfsplus_setxattr(struct inode *inode, const char *name,
}
} else if (be16_to_cpu(entry.type) == HFSPLUS_FILE) {
if (size == file_finderinfo_len) {
- memcpy(&entry.file.user_info, value,
+ memcpy(&entry.file.info, value,
file_finderinfo_len);
hfs_bnode_write(cat_fd.bnode, &entry,
cat_fd.entryoffset,
@@ -463,14 +461,14 @@ static ssize_t hfsplus_getxattr_finder_info(struct inode *inode,
if (entry_type == HFSPLUS_FOLDER) {
hfs_bnode_read(fd.bnode, folder_finder_info,
fd.entryoffset +
- offsetof(struct hfsplus_cat_folder, user_info),
+ offsetof(struct hfsplus_cat_folder, info.user),
folder_rec_len);
memcpy(value, folder_finder_info, folder_rec_len);
res = folder_rec_len;
} else if (entry_type == HFSPLUS_FILE) {
hfs_bnode_read(fd.bnode, file_finder_info,
fd.entryoffset +
- offsetof(struct hfsplus_cat_file, user_info),
+ offsetof(struct hfsplus_cat_file, info.user),
file_rec_len);
memcpy(value, file_finder_info, file_rec_len);
res = file_rec_len;
@@ -631,14 +629,14 @@ static ssize_t hfsplus_listxattr_finder_info(struct dentry *dentry,
len = sizeof(struct DInfo) + sizeof(struct DXInfo);
hfs_bnode_read(fd.bnode, folder_finder_info,
fd.entryoffset +
- offsetof(struct hfsplus_cat_folder, user_info),
+ offsetof(struct hfsplus_cat_folder, info.user),
len);
found_bit = find_first_bit((void *)folder_finder_info, len*8);
} else if (entry_type == HFSPLUS_FILE) {
len = sizeof(struct FInfo) + sizeof(struct FXInfo);
hfs_bnode_read(fd.bnode, file_finder_info,
fd.entryoffset +
- offsetof(struct hfsplus_cat_file, user_info),
+ offsetof(struct hfsplus_cat_file, info.user),
len);
found_bit = find_first_bit((void *)file_finder_info, len*8);
} else {
--
2.27.0
^ permalink raw reply related [flat|nested] 4+ messages in thread* Re: [PATCH][next] hfsplus: Fix out-of-bounds warnings in __hfsplus_setxattr
2021-03-30 14:52 [PATCH][next] hfsplus: Fix out-of-bounds warnings in __hfsplus_setxattr Gustavo A. R. Silva
@ 2021-03-31 4:43 ` Andrew Morton
2021-03-31 4:53 ` Matthew Wilcox
0 siblings, 1 reply; 4+ messages in thread
From: Andrew Morton @ 2021-03-31 4:43 UTC (permalink / raw)
To: Gustavo A. R. Silva; +Cc: linux-fsdevel, linux-kernel, linux-hardening
On Tue, 30 Mar 2021 09:52:26 -0500 "Gustavo A. R. Silva" <gustavoars@kernel.org> wrote:
> Fix the following out-of-bounds warnings by enclosing
> structure members file and finder into new struct info:
>
> fs/hfsplus/xattr.c:300:5: warning: 'memcpy' offset [65, 80] from the object at 'entry' is out of the bounds of referenced subobject 'user_info' with type 'struct DInfo' at offset 48 [-Warray-bounds]
> fs/hfsplus/xattr.c:313:5: warning: 'memcpy' offset [65, 80] from the object at 'entry' is out of the bounds of referenced subobject 'user_info' with type 'struct FInfo' at offset 48 [-Warray-bounds]
>
> Refactor the code by making it more "structured."
>
> Also, this helps with the ongoing efforts to enable -Warray-bounds and
> makes the code clearer and avoid confusing the compiler.
Confused. What was wrong with the old code? Was this warning
legitimate and if so, why? Or is this patch a workaround for a
compiler shortcoming?
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH][next] hfsplus: Fix out-of-bounds warnings in __hfsplus_setxattr
2021-03-31 4:43 ` Andrew Morton
@ 2021-03-31 4:53 ` Matthew Wilcox
2021-03-31 21:21 ` Gustavo A. R. Silva
0 siblings, 1 reply; 4+ messages in thread
From: Matthew Wilcox @ 2021-03-31 4:53 UTC (permalink / raw)
To: Andrew Morton
Cc: Gustavo A. R. Silva, linux-fsdevel, linux-kernel, linux-hardening
On Tue, Mar 30, 2021 at 09:43:20PM -0700, Andrew Morton wrote:
> On Tue, 30 Mar 2021 09:52:26 -0500 "Gustavo A. R. Silva" <gustavoars@kernel.org> wrote:
>
> > Fix the following out-of-bounds warnings by enclosing
> > structure members file and finder into new struct info:
> >
> > fs/hfsplus/xattr.c:300:5: warning: 'memcpy' offset [65, 80] from the object at 'entry' is out of the bounds of referenced subobject 'user_info' with type 'struct DInfo' at offset 48 [-Warray-bounds]
> > fs/hfsplus/xattr.c:313:5: warning: 'memcpy' offset [65, 80] from the object at 'entry' is out of the bounds of referenced subobject 'user_info' with type 'struct FInfo' at offset 48 [-Warray-bounds]
> >
> > Refactor the code by making it more "structured."
> >
> > Also, this helps with the ongoing efforts to enable -Warray-bounds and
> > makes the code clearer and avoid confusing the compiler.
>
> Confused. What was wrong with the old code? Was this warning
> legitimate and if so, why? Or is this patch a workaround for a
> compiler shortcoming?
The offending line is this:
- memcpy(&entry.file.user_info, value,
+ memcpy(&entry.file.info, value,
file_finderinfo_len);
what it's trying to do is copy two structs which are adjacent to each
other in a single call to memcpy(). gcc legitimately complains that the
memcpy to this struct overruns the bounds of the struct. What Gustavo
has done here is introduce a new struct that contains the two structs,
and now gcc is happy that the memcpy doesn't overrun the length of this
containing struct.
^ permalink raw reply [flat|nested] 4+ messages in thread* Re: [PATCH][next] hfsplus: Fix out-of-bounds warnings in __hfsplus_setxattr
2021-03-31 4:53 ` Matthew Wilcox
@ 2021-03-31 21:21 ` Gustavo A. R. Silva
0 siblings, 0 replies; 4+ messages in thread
From: Gustavo A. R. Silva @ 2021-03-31 21:21 UTC (permalink / raw)
To: Matthew Wilcox, Andrew Morton
Cc: Gustavo A. R. Silva, linux-fsdevel, linux-kernel, linux-hardening
On 3/30/21 23:53, Matthew Wilcox wrote:
> On Tue, Mar 30, 2021 at 09:43:20PM -0700, Andrew Morton wrote:
>> On Tue, 30 Mar 2021 09:52:26 -0500 "Gustavo A. R. Silva" <gustavoars@kernel.org> wrote:
>>
>>> Fix the following out-of-bounds warnings by enclosing
>>> structure members file and finder into new struct info:
>>>
>>> fs/hfsplus/xattr.c:300:5: warning: 'memcpy' offset [65, 80] from the object at 'entry' is out of the bounds of referenced subobject 'user_info' with type 'struct DInfo' at offset 48 [-Warray-bounds]
>>> fs/hfsplus/xattr.c:313:5: warning: 'memcpy' offset [65, 80] from the object at 'entry' is out of the bounds of referenced subobject 'user_info' with type 'struct FInfo' at offset 48 [-Warray-bounds]
>>>
>>> Refactor the code by making it more "structured."
>>>
>>> Also, this helps with the ongoing efforts to enable -Warray-bounds and
>>> makes the code clearer and avoid confusing the compiler.
>>
>> Confused. What was wrong with the old code? Was this warning
>> legitimate and if so, why? Or is this patch a workaround for a
>> compiler shortcoming?
>
> The offending line is this:
>
> - memcpy(&entry.file.user_info, value,
> + memcpy(&entry.file.info, value,
> file_finderinfo_len);
>
> what it's trying to do is copy two structs which are adjacent to each
> other in a single call to memcpy(). gcc legitimately complains that the
> memcpy to this struct overruns the bounds of the struct. What Gustavo
> has done here is introduce a new struct that contains the two structs,
> and now gcc is happy that the memcpy doesn't overrun the length of this
> containing struct.
Thanks for this, Matthew. :)
--
Gustavo
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2021-03-31 22:25 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2021-03-30 14:52 [PATCH][next] hfsplus: Fix out-of-bounds warnings in __hfsplus_setxattr Gustavo A. R. Silva
2021-03-31 4:43 ` Andrew Morton
2021-03-31 4:53 ` Matthew Wilcox
2021-03-31 21:21 ` Gustavo A. R. Silva
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.