After Six Years Of Work and Over 360 Patches, Linux 7.2 Finally Removes Bug-Prone strncpy (techtimes.com)
- Reference: 0184021198
- News link: https://linux.slashdot.org/story/26/06/21/1810200/after-six-years-of-work-and-over-360-patches-linux-72-finally-removes-bug-prone-strncpy
- Source link: https://www.techtimes.com/articles/318769/20260621/linux-72-closes-memory-bug-class-strncpy-removal-after-six-years.htm
> Linux 7.2's merge window closed out a cleanup campaign on Friday that most kernel developers had stopped expecting to see end: the complete removal of strncpy() , a C string-copy function that the kernel's own documentation labels "actively dangerous," from every subsystem, driver, and architecture-specific file in the kernel source tree.
>
> The merge landed June 20, 2026. After around 362 commits spread across six years of incremental work, no call site using the function remained, and the function itself — including the last per-CPU-architecture optimized implementations — was struck from the source. The removal matters beyond housekeeping. strncpy() is a persistent source of a specific class of memory error: kernel buffers that contain sensitive data can leak bytes past an unterminated string boundary, a pattern that enables memory disclosure vulnerabilities. Eliminating the function from the tree removes that entire class from the kernel's attack surface — and, critically, makes strncpy() unavailable to any future contributor, turning a best-practice suggestion into an enforced policy.
Phoronix notes it's replaced [2]by five different functions :
> In place of strncpy , Linux kernel code should use strscpy() for NUL terminated destinations, strscpy_pad() for NUl-terminated destinations with zero-padding, strtomem_pad() for non-NUL-terminated fixed-width fields, memcpy_and_pad() for bounded copies with explicit padding, or memcpy() for known-length memory copies.
"The reason five functions were needed," [3]explains Tech Times , "is that different parts of the kernel were using strncpy() for five semantically distinct memory operations — each with a different intent, different termination requirement, and different padding behavior. "
> The original function obscured all of those differences under a single ambiguous name. The 362-commit campaign to replace it was, in effect, a codebase-wide audit that forced every call site to declare its actual intent in code That is an engineering outcome with lasting value: the kernel's string-handling semantics are now explicit where they were previously implicit, and future maintainers can read a function name and understand what a copy operation actually does.
[1] https://www.techtimes.com/articles/318769/20260621/linux-72-closes-memory-bug-class-strncpy-removal-after-six-years.htm
[2] https://www.phoronix.com/news/Linux-7.2-Drops-strncpy
[3] https://www.techtimes.com/articles/318769/20260621/linux-72-closes-memory-bug-class-strncpy-removal-after-six-years.htm
strncpy never made sense (Score:3)
strncpy() should always have null terminated on truncation. I can't think of a single time i've ever used it where i didn't want it to terminate
Re: strncpy never made sense (Score:2)
Agreed. It was a badly design function from the get go - yeah let's have a function that copies a string and nul terminates except when it doesnt. Genius.
Re: (Score:2)
strncpy() was not intended for null-terminated strings at all. It should have been named copy_null_padded_buffer(). Then its operation would have made sense to almost anyone. People wouldn't have minded the longer name much either, because hardly anybody uses null-padded buffers in modern software.
Note that a null-padded buffer that is completely full doesn't have any nulls in it at all. That's why strncpy() doesn't necessarily add a null termination. It also fills the entire destination buffer with nulls a
Go Janitors! (Score:5, Interesting)
I see so many names in the commit logs, but some standouts include: Blum, Cook, Torvalds, Solodai, Tyragu, Stitt, Bergmann, Wysocki, Panda, de Mello, and no doubt some I missed who have a large number of commits fixing this problem.
Thank to all who undertook this Herculean chore!
strcpy (Score:1)
They took away my strncpy ? No problem, I'll use strcpy instead.
Re: (Score:1)
I don't have to worry about it because I use Rust so I don't enough memory to compile my source.
Why C is dangerous (Score:2)
I'm sure I'll get flamed, but this is why C (and other languages that don't provide mechanisms to BOUND the length of a string) are actively dangerous in The Real World. Look at the massive effort and time to mitigate this VERY COMMON AND WELL UNDERSTOOD vulnerability.
C (and here are somemore chars to satisfy the bot) (Score:3)
One of the annoyances of C: using a string function for operations that have nothing to do with strings. One of the many reasons I used to hate trying to understand other people's C code.
Re: (Score:2)
Why would you do that? If you're using it for non-strings, you'd never have used strncpy, you'd have used memcpy. Which is the same thing without the null termination rules of strncpy. You'd never use the str versions unless actually working on strings.
Re: C (and here are somemore chars to satisfy the (Score:3)
Never say never. "I have a lump of bytes that end in a NUL always -- this function works perfectly!"
Re: (Score:1)
i don't know lately but string functions were often a way to force debugging i/o. kind of a bug becoming a feature.
Re: (Score:2)
C doesn't have strings, but sometimes people like to have some bytes with a 0 on the end. Some of the memxxx() functions are useful with C's fake strings. For example, memchr() is good for when you have a null-terminated string but it also some upper bounds. And stuff like strncpy() doesn't appear to have anything at all to do with null terminated strings, and is grossly misnamed.
Re:C (and here are somemore chars to satisfy the b (Score:4, Interesting)
> C doesn't have strings, but sometimes people like to have some bytes with a 0 on the end. Some of the memxxx() functions are useful with C's fake strings. For example, memchr() is good for when you have a null-terminated string but it also some upper bounds. And stuff like strncpy() doesn't appear to have anything at all to do with null terminated strings, and is grossly misnamed.
strncpy() copies a string to another location stopping when it reaches a NUL or the end of the buffer.
The problem is the second case doesn't NUL terminate the string so you either have to make the buffer one smaller and terminate always or terminate always. Or try to handle it. The other problem is 'n' is unintuitive - it's the size of the buffer in characters. Easy peasy with 8-bit chars, not so much for Unicode strings. (UTF-16...)
I've personally be more of a fan of the BSD "l" versions - strlcpy and strlcat - both take the size of the target buffer in bytes - so a sizeof() is the proper way to use it, and both properly NUL terminate the string. strlcat has the added benefit that it computes the size it needs to copy based on the existing length of the string, so you can use strlcat() to concatenate a bunch of strings without computing the remaining buffer sizes (as you would in strncat). Luckily the BSD versions are in libbsd because they aren't in Glibc. Much nicer and much easier to use functions.
Re: C (and here are somemore chars to satisfy the (Score:2)
It's also one of the things I love about C -- that you can do that.
I rarely use C. I generally use Typescript or Python these days.
But it is a genuine love I have of C, that it's so close to the hardware, and so powerful because of that, second only to raw assembler. (I tend to "visualise" how computers work through C).
But it's also so dangerous and easy to use wrong.
Re: (Score:3)
Really? I don't recall ever seeing that. memcpy() is generally used in those cases.
Re: (Score:3)
> C (and here are somemore chars to satisfy the b
I wonder where the rest of the characters following 'b' got copied.