tree:
https://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git
kspp/memcpy/next-20210621/v0
head: 711a2c0c23d479d212e8d80f5dcaaf267162c8de
commit: b14704acbcd3290c2ab263615639d7e2f2a2e501 [53/86] fortify: Detect struct member
overflows in memcpy()
config: i386-randconfig-r025-20210621 (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-20210621/v0
git checkout b14704acbcd3290c2ab263615639d7e2f2a2e501
# 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/processor.h:19,
from arch/x86/include/asm/timex.h:5,
from include/linux/timex.h:65,
from include/linux/time32.h:13,
from include/linux/time.h:60,
from include/linux/ktime.h:24,
from include/linux/timer.h:6,
from include/linux/netdevice.h:24,
from net/mac80211/wpa.c:9:
In function '__fortify_memcpy_chk',
inlined from '__fortify_memcpy' at include/linux/fortify-string.h:281:2,
inlined from 'bip_aad.isra.0' at net/mac80211/wpa.c:912:2:
> 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:281:2,
inlined from 'ccmp_special_blocks.isra.0' at net/mac80211/wpa.c:365:2:
> 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:281:2,
inlined from 'gcmp_special_blocks.isra.0' at net/mac80211/wpa.c:597:2:
> 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();
| ^~~~~~~~~~~~~~~~~~~~~~~~
vim +/__read_overflow2_field +246 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 /*
255 * Warn when writing beyond destination field size.
256 * Since flexible-arrays are considered 0 bytes, we
257 * must ignore 0 sizes at runtime for now.
258 */
259 if (p_size_field && p_size != p_size_field && p_size_field <
size)
260 fortify_warn_write(func, p_size_field, size);
261 /* Warn when reading beyond source field size. */
262 /*
263 if (q_size_field && q_size != q_size_field && q_size_field <
size)
264 fortify_warn_read(func, q_size_field, size);
265 */
266
267 /*
268 * Always stop accesses beyond the struct that contains the
269 * field, when the buffer's remaining size is known.
270 */
271 if ((p_size != (size_t)(-1) && p_size < size) ||
272 (q_size != (size_t)(-1) && q_size < size))
273 fortify_panic(func);
274 }
275 }
276
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org