tree:
https://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git
kspp/memcpy/next-20210618/v0
head: fd2aa2a169de8bde9502e7a2fc48cd03d4bfd996
commit: 21405e341f4b8742f8c6d8b91ad39348d7cf970f [58/82] fortify: Detect struct member
overflows in memcpy()
config: i386-randconfig-r026-20210618 (attached as .config)
compiler: gcc-9 (Debian 9.3.0-22) 9.3.0
reproduce (this is a W=1 build):
#
https://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git/commit/?id...
git remote add kees
https://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git
git fetch --no-tags kees kspp/memcpy/next-20210618/v0
git checkout 21405e341f4b8742f8c6d8b91ad39348d7cf970f
# save the attached .config to linux build tree
make W=1 ARCH=i386
If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp(a)intel.com>
All warnings (new ones prefixed by >>):
In file included from include/linux/string.h:253,
from arch/x86/include/asm/page_32.h:35,
from arch/x86/include/asm/page.h:14,
from arch/x86/include/asm/thread_info.h:12,
from include/linux/thread_info.h:60,
from arch/x86/include/asm/preempt.h:7,
from include/linux/preempt.h:78,
from include/linux/spinlock.h:51,
from include/linux/wait.h:9,
from include/linux/wait_bit.h:8,
from include/linux/fs.h:6,
from fs/cifs/smb2pdu.c:31:
In function '__fortify_memcpy_chk',
inlined from '__fortify_memcpy' at include/linux/fortify-string.h:277:2,
inlined from 'SMB2_open' at fs/cifs/smb2pdu.c:2909:3:
include/linux/fortify-string.h:246:4: warning: call to '__read_overflow2_field'
declared with attribute warning: detected read beyond size of field (2nd parameter); maybe
use struct_group()? [-Wattribute-warning]
246 | __read_overflow2_field();
| ^~~~~~~~~~~~~~~~~~~~~~~~
In function '__fortify_memcpy_chk',
inlined from '__fortify_memcpy' at include/linux/fortify-string.h:277:2,
inlined from '__SMB2_close' at fs/cifs/smb2pdu.c:3262:4:
include/linux/fortify-string.h:246:4: warning: call to '__read_overflow2_field'
declared with attribute warning: detected read beyond size of field (2nd parameter); maybe
use struct_group()? [-Wattribute-warning]
246 | __read_overflow2_field();
| ^~~~~~~~~~~~~~~~~~~~~~~~
In function '__fortify_memcpy_chk',
inlined from '__fortify_memcpy' at include/linux/fortify-string.h:277:2,
inlined from 'posix_info_parse' at fs/cifs/smb2pdu.c:4555:3:
> include/linux/fortify-string.h:239:4: warning: call to
'__write_overflow_field' declared with attribute warning: detected write beyond
size of field (1st parameter); maybe use struct_group()? [-Wattribute-warning]
239 | __write_overflow_field();
| ^~~~~~~~~~~~~~~~~~~~~~~~
In function '__fortify_memcpy_chk',
inlined from '__fortify_memcpy' at include/linux/fortify-string.h:277:2,
inlined from 'posix_info_parse' at fs/cifs/smb2pdu.c:4557:3:
> include/linux/fortify-string.h:239:4: warning: call to
'__write_overflow_field' declared with attribute warning: detected write beyond
size of field (1st parameter); maybe use struct_group()? [-Wattribute-warning]
239 | __write_overflow_field();
| ^~~~~~~~~~~~~~~~~~~~~~~~
vim +/__write_overflow_field +239 include/linux/fortify-string.h
189
190 /*
191 * To make sure the compiler can enforce protection against buffer overflows,
192 * memcpy(), memmove(), and memset() must not be used beyond individual
193 * struct members. If you need to copy across multiple members, please use
194 * struct_group() to create a named mirror of an anonymous struct union.
195 * (e.g. see struct sk_buff.)
196 *
197 * Mitigation coverage
198 * Bounds checking at:
199 * +-------+-------+-------+-------+
200 * | Compile time | Run time |
201 * memcpy() argument sizes: | write | read | write | read |
202 * +-------+-------+-------+-------+
203 * memcpy(known, known, constant) | y | y | n/a | n/a |
204 * memcpy(unknown, known, constant) | n | y | V | n/a |
205 * memcpy(known, unknown, constant) | y | n | n/a | V |
206 * memcpy(unknown, unknown, constant) | n | n | V | V |
207 * memcpy(known, known, dynamic) | n | n | b | B |
208 * memcpy(unknown, known, dynamic) | n | n | V | B |
209 * memcpy(known, unknown, dynamic) | n | n | b | V |
210 * memcpy(unknown, unknown, dynamic) | n | n | V | V |
211 * +-------+-------+-------+-------+
212 *
213 * y = deterministic compile-time bounds checking
214 * n = cannot do deterministic compile-time bounds checking
215 * n/a = no run-time bounds checking needed since compile-time deterministic
216 * b = perform run-time bounds checking
217 * B = can perform run-time bounds checking, but current unenforced
218 * V = vulnerable to run-time overflow
219 *
220 */
221 __FORTIFY_INLINE void __fortify_memcpy_chk(void *p, const void *q,
222 __kernel_size_t size,
223 const char *func)
224 {
225 size_t p_size = __builtin_object_size(p, 0);
226 size_t q_size = __builtin_object_size(q, 0);
227 size_t p_size_field = __builtin_object_size(p, 1);
228 size_t q_size_field = __builtin_object_size(q, 1);
229
230 if (__builtin_constant_p(size)) {
231 /*
232 * Length argument is a constant expression, so we
233 * can perform compile-time bounds checking where
234 * buffer sizes are known.
235 */
236
237 /* Warn when write size argument larger than dest field. */
238 if (p_size_field < size)
239 __write_overflow_field();
240 /*
241 * Warn for over-read under W=1 or when an over-write
242 * happened, so both can be fixed at the same time.
243 */
244 if ((IS_ENABLED(KBUILD_EXTRA_WARN1) || p_size_field < size) &&
245 q_size_field < size)
246 __read_overflow2_field();
247 } else {
248 /*
249 * Length argument is not a constant expression, so
250 * run-time bounds checking can happen where buffer
251 * sizes are known.
252 */
253
254 /* Warn when writing beyond destination field size. */
255 if (p_size != p_size_field && p_size_field < size)
256 fortify_warn_write(func, p_size_field, size);
257 /* Warn when reading beyond source field size. */
258 /*
259 if (q_size != q_size_field && q_size_field < size)
260 fortify_warn_read(func, q_size_field, size);
261 */
262
263 /*
264 * Always stop accesses beyond the struct that contains the
265 * field, when the buffer's remaining size is known.
266 */
267 if ((p_size != (size_t)(-1) && p_size < size) ||
268 (q_size != (size_t)(-1) && q_size < size))
269 fortify_panic(func);
270 }
271 }
272
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org