mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-12-28 16:56:26 +00:00
powerpc/powernv: Fix fortify source warnings in opal-prd.c
commit feea65a338
upstream.
As reported by Mahesh & Aneesh, opal_prd_msg_notifier() triggers a
FORTIFY_SOURCE warning:
memcpy: detected field-spanning write (size 32) of single field "&item->msg" at arch/powerpc/platforms/powernv/opal-prd.c:355 (size 4)
WARNING: CPU: 9 PID: 660 at arch/powerpc/platforms/powernv/opal-prd.c:355 opal_prd_msg_notifier+0x174/0x188 [opal_prd]
NIP opal_prd_msg_notifier+0x174/0x188 [opal_prd]
LR opal_prd_msg_notifier+0x170/0x188 [opal_prd]
Call Trace:
opal_prd_msg_notifier+0x170/0x188 [opal_prd] (unreliable)
notifier_call_chain+0xc0/0x1b0
atomic_notifier_call_chain+0x2c/0x40
opal_message_notify+0xf4/0x2c0
This happens because the copy is targeting item->msg, which is only 4
bytes in size, even though the enclosing item was allocated with extra
space following the msg.
To fix the warning define struct opal_prd_msg with a union of the header
and a flex array, and have the memcpy target the flex array.
Reported-by: "Aneesh Kumar K.V" <aneesh.kumar@linux.ibm.com>
Reported-by: Mahesh Salgaonkar <mahesh@linux.ibm.com>
Tested-by: Mahesh Salgaonkar <mahesh@linux.ibm.com>
Reviewed-by: Mahesh Salgaonkar <mahesh@linux.ibm.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://msgid.link/20230821142820.497107-1-mpe@ellerman.id.au
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
7aded92aeb
commit
1f59a2a928
@ -24,13 +24,20 @@
|
||||
#include <linux/uaccess.h>
|
||||
|
||||
|
||||
struct opal_prd_msg {
|
||||
union {
|
||||
struct opal_prd_msg_header header;
|
||||
DECLARE_FLEX_ARRAY(u8, data);
|
||||
};
|
||||
};
|
||||
|
||||
/*
|
||||
* The msg member must be at the end of the struct, as it's followed by the
|
||||
* message data.
|
||||
*/
|
||||
struct opal_prd_msg_queue_item {
|
||||
struct list_head list;
|
||||
struct opal_prd_msg_header msg;
|
||||
struct list_head list;
|
||||
struct opal_prd_msg msg;
|
||||
};
|
||||
|
||||
static struct device_node *prd_node;
|
||||
@ -156,7 +163,7 @@ static ssize_t opal_prd_read(struct file *file, char __user *buf,
|
||||
int rc;
|
||||
|
||||
/* we need at least a header's worth of data */
|
||||
if (count < sizeof(item->msg))
|
||||
if (count < sizeof(item->msg.header))
|
||||
return -EINVAL;
|
||||
|
||||
if (*ppos)
|
||||
@ -186,7 +193,7 @@ static ssize_t opal_prd_read(struct file *file, char __user *buf,
|
||||
return -EINTR;
|
||||
}
|
||||
|
||||
size = be16_to_cpu(item->msg.size);
|
||||
size = be16_to_cpu(item->msg.header.size);
|
||||
if (size > count) {
|
||||
err = -EINVAL;
|
||||
goto err_requeue;
|
||||
@ -352,7 +359,7 @@ static int opal_prd_msg_notifier(struct notifier_block *nb,
|
||||
if (!item)
|
||||
return -ENOMEM;
|
||||
|
||||
memcpy(&item->msg, msg->params, msg_size);
|
||||
memcpy(&item->msg.data, msg->params, msg_size);
|
||||
|
||||
spin_lock_irqsave(&opal_prd_msg_queue_lock, flags);
|
||||
list_add_tail(&item->list, &opal_prd_msg_queue);
|
||||
|
Loading…
Reference in New Issue
Block a user