RFC for a new string-copy function, using mixtures of strlcpy and strscpy

From: Ajay Garg
Date: Sun Nov 07 2021 - 22:17:20 EST


Hello everyone.

I recently came across the functions strlcpy and strscpy, and it seems
something is missing/unclean.

This email is a RFC for another function, by the name "strlscpy".
Following is a small .ko, which demonstrates the differences in
behaviours of strlcpy/strscpy/strlscpy :

######################################################
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/string.h>

char *__MODULE__ = "KERN-ajay-hello-world";

char a[10] = {0};
char b[] = "1234567890123456";

typedef size_t (*func_type_1)(char *dest, const char *src, size_t size);
typedef ssize_t (*func_type_2)(char *dest, const char *src, size_t size);

size_t strlscpy(char *dest, const char *src, size_t size)
{
size_t len = strlen(src);

if (size) {
if(len >= size)
len = size - 1;

memcpy(dest, src, len);
dest[len] = '\0';
}

return len;
}

void common(const char *fname, int len)
{
printk("\n\nUsing [%s] :: \n\n", fname);
printk("len = [%d]\n", len);
printk("a = [%s]\n", a);
}

void run_test_type_1(func_type_1 fn, const char *fname)
{
common(fname, fn(a, b, sizeof(a)));
}

void run_test_type_2(func_type_2 fn, const char *fname)
{
common(fname, fn(a, b, sizeof(a)));
}

static int __init hello_init(void)
{
run_test_type_1(strlcpy, "strlcpy");
run_test_type_2(strscpy, "strscpy");
run_test_type_1(strlscpy, "strlscpy");

return 0;
}

static void __exit hello_exit(void)
{
}

module_init(hello_init);
module_exit(hello_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Ajay Garg <ajaygargnsit@xxxxxxxxx>");
MODULE_DESCRIPTION("Hello-World Driver");
######################################################




The output is as follows :

######################################################
Using [strlcpy] ::

len = [16]
a = [123456789]


Using [strscpy] ::

len = [-7]
a = [123456789]


Using [strlscpy] ::

len = [9]
a = [123456789]
######################################################


As is seen, the intended strlscpy function returns the number of bytes
truly copied, whereas the other two functions return values that are
prone to causing overflows/underflows.


== Motivation for the intended new function ==

Currently, strlcpy is being used in the kernel in following ways :

i)
Return-value is not consumed by the client.

ii)
Return-value is consumed by the client, and the overflow-check done on
the return-value.

iii)
Return-value is consumed by the client, but no overflow-check done on
the return-value.


Case i) is error-free, Case ii) is also acceptable.
However, Case iii) is error-prone to overflows (thus defeating the
purpose of using strlcpy at the first place).


Thus, kindly let know your thoughts, on this proposal for the addition
of this new strlscpy function in lib/string.c, so that return-value is
exact and not prone to any overflows/underflows.


Thanks and Regards,
Ajay