[PATCH 1/2] powerpc/powernv: Fix fortify source warnings in opal-prd.c
Mahesh J Salgaonkar
mahesh at linux.ibm.com
Wed Aug 23 12:58:16 AEST 2023
On 2023-08-22 00:28:19 Tue, Michael Ellerman wrote:
> 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 targetting 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 at linux.ibm.com>
> Reported-by: Mahesh Salgaonkar <mahesh at linux.ibm.com>
> Signed-off-by: Michael Ellerman <mpe at ellerman.id.au>
Tested-by: Mahesh Salgaonkar <mahesh at linux.ibm.com>
Reviewed-by: Mahesh Salgaonkar <mahesh at linux.ibm.com>
Thanks,
-Mahesh
> ---
> arch/powerpc/platforms/powernv/opal-prd.c | 17 ++++++++++++-----
> 1 file changed, 12 insertions(+), 5 deletions(-)
>
> diff --git a/arch/powerpc/platforms/powernv/opal-prd.c b/arch/powerpc/platforms/powernv/opal-prd.c
> index 113bdb151f68..40e26e9f318f 100644
> --- a/arch/powerpc/platforms/powernv/opal-prd.c
> +++ b/arch/powerpc/platforms/powernv/opal-prd.c
> @@ -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);
> --
> 2.41.0
>
--
Mahesh J Salgaonkar
More information about the Linuxppc-dev
mailing list