• Justin Stitt's avatar
    rpmsg: virtio: Replace deprecated strncpy with strscpy/_pad · 2a6e483a
    Justin Stitt authored
    strncpy() is deprecated for use on NUL-terminated destination strings
    [1] and as such we should prefer more robust and less ambiguous string
    interfaces.
    
    This patch replaces 3 callsites of strncpy().
    
    The first two populate the destination buffer `nsm.name` -- which we
    expect to be NUL-terminated based on their use with format strings.
    
    Firstly, as I understand it, virtio_rpmsg_announce_create() creates an
    rpmsg_ns_msg and sends via:
    
    virtio_rpmsg_bus.c:
    336: err = rpmsg_sendto(rpdev->ept, &nsm, sizeof(nsm), RPMSG_NS_ADDR);
    
    ... which uses:
    virtio_rpmsg_sendto() -> rpmsg_send_offchannel_raw()
    
    ... which copies its data into an rpmsg_hdr `msg` in virtio_rpmsg_bus.c
    618: memcpy(msg->data, data, len);
    
    This callback is invoked when a message is received from the remote
    processor:
    
    rpmsg_ns.c:
    30: /* invoked when a name service announcement arrives */
    31: static int rpmsg_ns_cb(struct rpmsg_device *rpdev, void *data, int len,
    32: 		       void *priv, u32 src)
    33: {
    34:         struct rpmsg_ns_msg *msg = data;
    ...
    50:         /* don't trust the remote processor for null terminating the name */
    51:         msg->name[RPMSG_NAME_SIZE - 1] = '\0';
    
    ... which leads into the use of `name` within a format string:
    rpmsg_ns.c:
    57: dev_info(dev, "%sing channel %s addr 0x%x\n",
    58:          rpmsg32_to_cpu(rpdev, msg->flags) & RPMSG_NS_DESTROY ?
    59:          "destroy" : "creat", msg->name, chinfo.dst);
    
    We can also observe that `nsm` is not zero-initialized and as such we
    should maintain the NUL-padding behavior that strncpy() provides:
    
    virtio_rpmsg_bus.c:
    330: struct rpmsg_ns_msg nsm;
    
    Considering the above, a suitable replacement is `strscpy_pad` due to
    the fact that it guarantees both NUL-termination and NUL-padding on the
    destination buffer.
    
    Now, for the third and final destination buffer rpdev->id.name we can
    just go for strscpy() (not _pad()) as rpdev points to &vch->rpdev:
    |       rpdev = &vch->rpdev;
    
    ... and vch is zero-allocated:
    |       vch = kzalloc(sizeof(*vch), GFP_KERNEL);
    
    ... this renders any additional NUL-byte assignments (like the ones
    strncpy() or strscpy_pad() does) redundant.
    
    Link: https://www.kernel.org/doc/html/latest/process/deprecated.html#strncpy-on-nul-terminated-strings [1]
    Link: https://github.com/KSPP/linux/issues/90
    Cc: linux-hardening@vger.kernel.org
    Signed-off-by: default avatarJustin Stitt <justinstitt@google.com>
    Link: https://lore.kernel.org/r/20231023-strncpy-drivers-rpmsg-virtio_rpmsg_bus-c-v2-1-dc591c36f5ed@google.comSigned-off-by: default avatarMathieu Poirier <mathieu.poirier@linaro.org>
    2a6e483a
virtio_rpmsg_bus.c 30.4 KB