2023-11-16 19:14:51

by Kees Cook

[permalink] [raw]
Subject: [PATCH] dma-buf: Replace strlcpy() with strscpy()

strlcpy() reads the entire source buffer first. This read may exceed
the destination size limit. This is both inefficient and can lead
to linear read overflows if a source string is not NUL-terminated[1].
Additionally, it returns the size of the source string, not the
resulting size of the destination string. In an effort to remove strlcpy()
completely[2], replace strlcpy() here with strscpy().

Link: https://www.kernel.org/doc/html/latest/process/deprecated.html#strlcpy [1]
Link: https://github.com/KSPP/linux/issues/89 [2]
Cc: Sumit Semwal <[email protected]>
Cc: "Christian König" <[email protected]>
Cc: Azeem Shaikh <[email protected]>
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
Signed-off-by: Kees Cook <[email protected]>
---
drivers/dma-buf/dma-buf.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c
index 21916bba77d5..8fe5aa67b167 100644
--- a/drivers/dma-buf/dma-buf.c
+++ b/drivers/dma-buf/dma-buf.c
@@ -46,12 +46,12 @@ static char *dmabuffs_dname(struct dentry *dentry, char *buffer, int buflen)
{
struct dma_buf *dmabuf;
char name[DMA_BUF_NAME_LEN];
- size_t ret = 0;
+ ssize_t ret = 0;

dmabuf = dentry->d_fsdata;
spin_lock(&dmabuf->name_lock);
if (dmabuf->name)
- ret = strlcpy(name, dmabuf->name, DMA_BUF_NAME_LEN);
+ ret = strscpy(name, dmabuf->name, sizeof(name));
spin_unlock(&dmabuf->name_lock);

return dynamic_dname(buffer, buflen, "/%s:%s",
--
2.34.1


2023-11-17 18:51:21

by T.J. Mercier

[permalink] [raw]
Subject: Re: [PATCH] dma-buf: Replace strlcpy() with strscpy()

On Thu, Nov 16, 2023 at 11:14 AM Kees Cook <[email protected]> wrote:
>
> strlcpy() reads the entire source buffer first. This read may exceed
> the destination size limit. This is both inefficient and can lead
> to linear read overflows if a source string is not NUL-terminated[1].
> Additionally, it returns the size of the source string, not the
> resulting size of the destination string. In an effort to remove strlcpy()
> completely[2], replace strlcpy() here with strscpy().
>
> Link: https://www.kernel.org/doc/html/latest/process/deprecated.html#strlcpy [1]
> Link: https://github.com/KSPP/linux/issues/89 [2]
> Cc: Sumit Semwal <[email protected]>
> Cc: "Christian König" <[email protected]>
> Cc: Azeem Shaikh <[email protected]>
> Cc: [email protected]
> Cc: [email protected]
> Cc: [email protected]
> Signed-off-by: Kees Cook <[email protected]>

Reviewed-by: T.J. Mercier <[email protected]>

strscpy returns -E2BIG when it truncates / force null-terminates which
would provide the wrong argument for dynamic_dname, but
dma_buf_set_name{_user} makes sure we have a null-terminated string of
the appropriate maximum size in dmabuf->name.

2023-11-20 10:00:32

by Christian König

[permalink] [raw]
Subject: Re: [PATCH] dma-buf: Replace strlcpy() with strscpy()

Am 17.11.23 um 19:50 schrieb T.J. Mercier:
> On Thu, Nov 16, 2023 at 11:14 AM Kees Cook <[email protected]> wrote:
>> strlcpy() reads the entire source buffer first. This read may exceed
>> the destination size limit. This is both inefficient and can lead
>> to linear read overflows if a source string is not NUL-terminated[1].
>> Additionally, it returns the size of the source string, not the
>> resulting size of the destination string. In an effort to remove strlcpy()
>> completely[2], replace strlcpy() here with strscpy().
>>
>> Link: https://www.kernel.org/doc/html/latest/process/deprecated.html#strlcpy [1]
>> Link: https://github.com/KSPP/linux/issues/89 [2]
>> Cc: Sumit Semwal <[email protected]>
>> Cc: "Christian König" <[email protected]>
>> Cc: Azeem Shaikh <[email protected]>
>> Cc: [email protected]
>> Cc: [email protected]
>> Cc: [email protected]
>> Signed-off-by: Kees Cook <[email protected]>
> Reviewed-by: T.J. Mercier <[email protected]>
>
> strscpy returns -E2BIG when it truncates / force null-terminates which
> would provide the wrong argument for dynamic_dname, but
> dma_buf_set_name{_user} makes sure we have a null-terminated string of
> the appropriate maximum size in dmabuf->name.

Thanks for that background check, I was about to note that this might
not be a good idea.

Linus pretty clearly stated that he doesn't want to see patches like
that one here, see this article as well. https://lwn.net/Articles/659214/

I think the commit message gives enough reason to merge the patch, so
I'm going to push it to drm-misc-next. But please make sure to triple
check stuff like this before sending.

Thanks,
Christian.