mirror of
https://github.com/MariaDB/server.git
synced 2025-08-08 11:22:35 +03:00
Minimize unsafe C functions usage - replace strcat() and strcpy() (and strncat() and strncpy()) with custom safe_strcat() and safe_strcpy() functions
The MariaDB code base uses strcat() and strcpy() in several places. These are known to have memory safety issues and their usage is discouraged. Common security scanners like Flawfinder flags them. In MariaDB we should start using modern and safer variants on these functions. This is similar to memory issues fixes in19af1890b5
and9de9f105b5
but now replace use of strcat() and strcpy() with safer options strncat() and strncpy(). However, add '\0' forcefully to make sure the result string is correct since for these two functions it is not guaranteed what new string will be null-terminated. Example: size_t dest_len = sizeof(g->Message); strncpy(g->Message, "Null json tree", dest_len); strncat(g->Message, ":", sizeof(g->Message) - strlen(g->Message)); size_t wrote_sz = strlen(g->Message); size_t cur_len = wrote_sz >= dest_len ? dest_len - 1 : wrote_sz; g->Message[cur_len] = '\0'; All new code of the whole pull request, including one or several files that are either new files or modified ones, are contributed under the BSD-new license. I am contributing on behalf of my employer Amazon Web Services -- Reviewer and co-author Vicențiu Ciorbaru <vicentiu@mariadb.org> -- Reviewer additions: * The initial function implementation was flawed. Replaced with a simpler and also correct version. * Simplified code by making use of snprintf instead of chaining strcat. * Simplified code by removing dynamic string construction in the first place and using static strings if possible. See connect storage engine changes.
This commit is contained in:
committed by
Vicențiu Ciorbaru
parent
ea270178b0
commit
567b681299
@@ -225,6 +225,44 @@ static inline void lex_string_set3(LEX_CSTRING *lex_str, const char *c_str,
|
||||
lex_str->length= len;
|
||||
}
|
||||
|
||||
/*
|
||||
Copies src into dst and ensures dst is a NULL terminated C string.
|
||||
|
||||
Returns 1 if the src string was truncated due to too small size of dst.
|
||||
Returns 0 if src completely fit within dst. Pads the remaining dst with '\0'
|
||||
|
||||
Note: dst_size must be > 0
|
||||
*/
|
||||
static inline int safe_strcpy(char *dst, size_t dst_size, const char *src)
|
||||
{
|
||||
memset(dst, '\0', dst_size);
|
||||
strncpy(dst, src, dst_size - 1);
|
||||
/*
|
||||
If the first condition is true, we are guaranteed to have src length
|
||||
>= (dst_size - 1), hence safe to access src[dst_size - 1].
|
||||
*/
|
||||
if (dst[dst_size - 2] != '\0' && src[dst_size - 1] != '\0')
|
||||
return 1; /* Truncation of src. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
Appends src to dst and ensures dst is a NULL terminated C string.
|
||||
|
||||
Returns 1 if the src string was truncated due to too small size of dst.
|
||||
Returns 0 if src completely fit within the remaining dst space. Pads the
|
||||
remaining dst with '\0'.
|
||||
|
||||
Note: dst_size must be > 0
|
||||
*/
|
||||
static inline int safe_strcat(char *dst, size_t dst_size, const char *src)
|
||||
{
|
||||
size_t init_len= strlen(dst);
|
||||
if (unlikely(init_len >= dst_size - 1))
|
||||
return 1;
|
||||
return safe_strcpy(dst + init_len, dst_size - init_len, src);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
static inline char *safe_str(char *str)
|
||||
{ return str ? str : const_cast<char*>(""); }
|
||||
|
Reference in New Issue
Block a user