Skip to content

Commit 84253c8

Browse files
keesJonathan Corbet
authored and
Jonathan Corbet
committed
docs: Introduce deprecated APIs list
As discussed in the "API replacement/deprecation" thread[1], this makes an effort to document what things shouldn't get (re)added to the kernel, by introducing Documentation/process/deprecated.rst. [1] https://lists.linuxfoundation.org/pipermail/ksummit-discuss/2018-September/005282.html Signed-off-by: Kees Cook <[email protected]> Signed-off-by: Jonathan Corbet <[email protected]>
1 parent cf419d5 commit 84253c8

File tree

3 files changed

+123
-0
lines changed

3 files changed

+123
-0
lines changed

Documentation/driver-api/basics.rst

+3
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,9 @@ Kernel utility functions
121121
.. kernel-doc:: kernel/rcu/update.c
122122
:export:
123123

124+
.. kernel-doc:: include/linux/overflow.h
125+
:internal:
126+
124127
Device Resource Management
125128
--------------------------
126129

Documentation/process/deprecated.rst

+119
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
.. SPDX-License-Identifier: GPL-2.0
2+
3+
=====================================================================
4+
Deprecated Interfaces, Language Features, Attributes, and Conventions
5+
=====================================================================
6+
7+
In a perfect world, it would be possible to convert all instances of
8+
some deprecated API into the new API and entirely remove the old API in
9+
a single development cycle. However, due to the size of the kernel, the
10+
maintainership hierarchy, and timing, it's not always feasible to do these
11+
kinds of conversions at once. This means that new instances may sneak into
12+
the kernel while old ones are being removed, only making the amount of
13+
work to remove the API grow. In order to educate developers about what
14+
has been deprecated and why, this list has been created as a place to
15+
point when uses of deprecated things are proposed for inclusion in the
16+
kernel.
17+
18+
__deprecated
19+
------------
20+
While this attribute does visually mark an interface as deprecated,
21+
it `does not produce warnings during builds any more
22+
<https://git.kernel.org/linus/771c035372a036f83353eef46dbb829780330234>`_
23+
because one of the standing goals of the kernel is to build without
24+
warnings and no one was actually doing anything to remove these deprecated
25+
interfaces. While using `__deprecated` is nice to note an old API in
26+
a header file, it isn't the full solution. Such interfaces must either
27+
be fully removed from the kernel, or added to this file to discourage
28+
others from using them in the future.
29+
30+
open-coded arithmetic in allocator arguments
31+
--------------------------------------------
32+
Dynamic size calculations (especially multiplication) should not be
33+
performed in memory allocator (or similar) function arguments due to the
34+
risk of them overflowing. This could lead to values wrapping around and a
35+
smaller allocation being made than the caller was expecting. Using those
36+
allocations could lead to linear overflows of heap memory and other
37+
misbehaviors. (One exception to this is literal values where the compiler
38+
can warn if they might overflow. Though using literals for arguments as
39+
suggested below is also harmless.)
40+
41+
For example, do not use ``count * size`` as an argument, as in::
42+
43+
foo = kmalloc(count * size, GFP_KERNEL);
44+
45+
Instead, the 2-factor form of the allocator should be used::
46+
47+
foo = kmalloc_array(count, size, GFP_KERNEL);
48+
49+
If no 2-factor form is available, the saturate-on-overflow helpers should
50+
be used::
51+
52+
bar = vmalloc(array_size(count, size));
53+
54+
Another common case to avoid is calculating the size of a structure with
55+
a trailing array of others structures, as in::
56+
57+
header = kzalloc(sizeof(*header) + count * sizeof(*header->item),
58+
GFP_KERNEL);
59+
60+
Instead, use the helper::
61+
62+
header = kzalloc(struct_size(header, item, count), GFP_KERNEL);
63+
64+
See :c:func:`array_size`, :c:func:`array3_size`, and :c:func:`struct_size`,
65+
for more details as well as the related :c:func:`check_add_overflow` and
66+
:c:func:`check_mul_overflow` family of functions.
67+
68+
simple_strtol(), simple_strtoll(), simple_strtoul(), simple_strtoull()
69+
----------------------------------------------------------------------
70+
The :c:func:`simple_strtol`, :c:func:`simple_strtoll`,
71+
:c:func:`simple_strtoul`, and :c:func:`simple_strtoull` functions
72+
explicitly ignore overflows, which may lead to unexpected results
73+
in callers. The respective :c:func:`kstrtol`, :c:func:`kstrtoll`,
74+
:c:func:`kstrtoul`, and :c:func:`kstrtoull` functions tend to be the
75+
correct replacements, though note that those require the string to be
76+
NUL or newline terminated.
77+
78+
strcpy()
79+
--------
80+
:c:func:`strcpy` performs no bounds checking on the destination
81+
buffer. This could result in linear overflows beyond the
82+
end of the buffer, leading to all kinds of misbehaviors. While
83+
`CONFIG_FORTIFY_SOURCE=y` and various compiler flags help reduce the
84+
risk of using this function, there is no good reason to add new uses of
85+
this function. The safe replacement is :c:func:`strscpy`.
86+
87+
strncpy() on NUL-terminated strings
88+
-----------------------------------
89+
Use of :c:func:`strncpy` does not guarantee that the destination buffer
90+
will be NUL terminated. This can lead to various linear read overflows
91+
and other misbehavior due to the missing termination. It also NUL-pads the
92+
destination buffer if the source contents are shorter than the destination
93+
buffer size, which may be a needless performance penalty for callers using
94+
only NUL-terminated strings. The safe replacement is :c:func:`strscpy`.
95+
(Users of :c:func:`strscpy` still needing NUL-padding will need an
96+
explicit :c:func:`memset` added.)
97+
98+
If a caller is using non-NUL-terminated strings, :c:func:`strncpy()` can
99+
still be used, but destinations should be marked with the `__nonstring
100+
<https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html>`_
101+
attribute to avoid future compiler warnings.
102+
103+
strlcpy()
104+
---------
105+
:c:func:`strlcpy` reads the entire source buffer first, possibly exceeding
106+
the given limit of bytes to copy. This is inefficient and can lead to
107+
linear read overflows if a source string is not NUL-terminated. The
108+
safe replacement is :c:func:`strscpy`.
109+
110+
Variable Length Arrays (VLAs)
111+
-----------------------------
112+
Using stack VLAs produces much worse machine code than statically
113+
sized stack arrays. While these non-trivial `performance issues
114+
<https://git.kernel.org/linus/02361bc77888>`_ are reason enough to
115+
eliminate VLAs, they are also a security risk. Dynamic growth of a stack
116+
array may exceed the remaining memory in the stack segment. This could
117+
lead to a crash, possible overwriting sensitive contents at the end of the
118+
stack (when built without `CONFIG_THREAD_INFO_IN_TASK=y`), or overwriting
119+
memory adjacent to the stack (when built without `CONFIG_VMAP_STACK=y`)

Documentation/process/index.rst

+1
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ Other guides to the community that are of interest to most developers are:
4242
stable-kernel-rules
4343
submit-checklist
4444
kernel-docs
45+
deprecated
4546

4647
These are some overall technical guides that have been put here for now for
4748
lack of a better place.

0 commit comments

Comments
 (0)