2023-05-24 11:35:10

by Thorsten Leemhuis

[permalink] [raw]
Subject: build error while building arch/x86/purgatory/sha256.o: invalid 'asm': operand is not a condition code [...]

Hi! My linux-next builds for Fedora[1] since yesterday fail with the
following error:

> In file included from <command-line>:
> ./include/crypto/sha256_base.h: In function ‘lib_sha256_base_do_update.constprop.isra’:
> ././include/linux/compiler_types.h:332:20: error: invalid 'asm': operand is not a condition code, invalid operand code 'c'
> 332 | #define asm_inline asm __inline
> | ^~~

See below for the full error message[2]. This happens on Fedora rawhide
and 38 (both use gcc13), but not on Fedora 37 (which uses gcc12).

Is this known already or do I have to bisect this?

Ciao, Thorsten

[1] https://copr.fedorainfracloud.org/coprs/g/kernel-vanilla/next/

[2]
> # CC arch/x86/purgatory/sha256.o
>
> gcc -Wp,-MMD,arch/x86/purgatory/.sha256.o.d -nostdinc
> -I./arch/x86/include -I./arch/x86/include/generated -I./include
> -I./arch/x86/include/uapi -I./arch/x86/include/generated/uapi
> -I./include/uapi -I./include/generated/uapi -include
> ./include/linux/compiler-version.h -include ./include/linux/kconfig.h
> -include ./include/linux/compiler_types.h -D__KERNEL__
> -fmacro-prefix-map=./= -Wall -Wundef -Werror=strict-prototypes
> -Wno-trigraphs -fno-strict-aliasing -fno-common -fshort-wchar -fno-PIE
> -Werror=implicit-function-declaration -Werror=implicit-int
> -Werror=return-type -Wno-format-security -funsigned-char -std=gnu11
> -mno-sse -mno-mmx -mno-sse2 -mno-3dnow -mno-avx -fcf-protection=branch
> -fno-jump-tables -m64 -falign-jumps=1 -falign-loops=1 -mno-80387
> -mno-fp-ret-in-387 -mpreferred-stack-boundary=3 -mskip-rax-setup
> -mtune=generic -mno-red-zone -Wno-sign-compare
> -fno-asynchronous-unwind-tables -fno-jump-tables -mharden-sls=all
> -fpatchable-function-entry=16,16 -fno-delete-null-pointer-checks
> -Wno-frame-address -Wno-format-truncation -Wno-format-overflow
> -Wno-address-of-packed-member -O2 -fno-allow-store-data-races
> -Wframe-larger-than=2048 -Wno-main -Wno-unused-but-set-variable
> -Wno-unused-const-variable -Wno-dangling-pointer
> -ftrivial-auto-var-init=zero -fno-stack-clash-protection
> -DCC_USING_FENTRY -falign-functions=16 -Wdeclaration-after-statement
> -Wvla -Wno-pointer-sign -Wcast-function-type -fstrict-flex-arrays=3
> -Wno-stringop-truncation -Wno-stringop-overflow -Wno-restrict
> -Wno-maybe-uninitialized -Wno-array-bounds -Wno-alloc-size-larger-than
> -Wimplicit-fallthrough=5 -fno-strict-overflow -fno-stack-check
> -fconserve-stack -Werror=date-time -Werror=incompatible-pointer-types
> -Werror=designated-init -Wno-packed-not-aligned -g -D__DISABLE_EXPORTS
> -mcmodel=large -ffreestanding -fno-zero-initialized-in-bss -g0
> -DDISABLE_BRANCH_PROFILING -fno-stack-protector
> -DKBUILD_MODFILE='"arch/x86/purgatory/sha256"'
> -DKBUILD_BASENAME='"sha256"' -DKBUILD_MODNAME='"sha256"'
> -D__KBUILD_MODNAME=kmod_sha256 -c -o arch/x86/purgatory/sha256.o
> lib/crypto/sha256.c
>
> In file included from <command-line>:
> ./include/crypto/sha256_base.h: In function ‘lib_sha256_base_do_update.constprop.isra’:
> ././include/linux/compiler_types.h:332:20: error: invalid 'asm': operand is not a condition code, invalid operand code 'c'
> 332 | #define asm_inline asm __inline
> | ^~~
> ./arch/x86/include/asm/bug.h:28:9: note: in expansion of macro ‘asm_inline’
> 28 | asm_inline volatile("1:\t" ins "\n" \
> | ^~~~~~~~~~
> ./arch/x86/include/asm/bug.h:83:9: note: in expansion of macro ‘_BUG_FLAGS’
> 83 | _BUG_FLAGS(ASM_UD2, __flags, ASM_REACHABLE); \
> | ^~~~~~~~~~
> ./include/asm-generic/bug.h:107:17: note: in expansion of macro ‘__WARN_FLAGS’
> 107 | __WARN_FLAGS(BUGFLAG_NO_CUT_HERE | BUGFLAG_TAINT(taint));\
> | ^~~~~~~~~~~~
> ./include/asm-generic/bug.h:134:17: note: in expansion of macro ‘__WARN_printf’
> 134 | __WARN_printf(TAINT_WARN, format); \
> | ^~~~~~~~~~~~~
> ./include/linux/once_lite.h:31:25: note: in expansion of macro ‘WARN’
> 31 | func(__VA_ARGS__); \
> | ^~~~
> ./include/asm-generic/bug.h:152:9: note: in expansion of macro ‘DO_ONCE_LITE_IF’
> 152 | DO_ONCE_LITE_IF(condition, WARN, 1, format)
> | ^~~~~~~~~~~~~~~
> ./include/linux/fortify-string.h:641:9: note: in expansion of macro ‘WARN_ONCE’
> 641 | WARN_ONCE(fortify_memcpy_chk(__fortify_size, __p_size, \
> | ^~~~~~~~~
> ./include/linux/fortify-string.h:693:26: note: in expansion of macro ‘__fortify_memcpy_chk’
> 693 | #define memcpy(p, q, s) __fortify_memcpy_chk(p, q, s, \
> | ^~~~~~~~~~~~~~~~~~~~
> ./include/crypto/sha256_base.h:69:17: note: in expansion of macro ‘memcpy’
> 69 | memcpy(sctx->buf + partial, data, len);
> | ^~~~~~
> make[3]: *** [arch/x86/purgatory/Makefile:13: arch/x86/purgatory/sha256.o] Error 1
> make[2]: *** [scripts/Makefile.build:494: arch/x86/purgatory] Error 2
> make[1]: *** [scripts/Makefile.build:494: arch/x86] Error 2
> make: *** [Makefile:2032: .] Error 2


2023-05-28 16:47:23

by Joan Bruguera Micó

[permalink] [raw]
Subject: Re: build error while building arch/x86/purgatory/sha256.o: invalid 'asm': operand is not a condition code [...]

I can also reproduce the problem with Arch's linux-next-git, see config:
https://aur.archlinux.org/cgit/aur.git/tree/config?h=linux-next-git&id=f9a384e1c582321651fb613782ebc5a581146af0

I've bisected it to df8fc4e934c1 ("kbuild: Enable -fstrict-flex-arrays=3"),
which explains why it only happens on GCC13.

The problematic expansion that causes the error seems to be this fragment
from `_BUG_FLAGS` in `arch/x86/include/asm/bug.h`:
asm(".long %c0 - .\n": : "i" (__FILE__));

Along with the fact that this file is built with `-mcmodel=large`
(see `PURGATORY_CFLAGS` in `arch/x86/purgatory/Makefile`).

Regards,
- Joan

2023-05-28 18:24:44

by Joan Bruguera Micó

[permalink] [raw]
Subject: Re: build error while building arch/x86/purgatory/sha256.o: invalid 'asm': operand is not a condition code [...]

Adding `-fstrict-flex-arrays=3` to `PURGATORY_CFLAGS_REMOVE` in
`arch/x86/purgatory/Makefile` fixes the build, through I don't know if
that's the best solution.

2023-05-30 04:39:20

by Kees Cook

[permalink] [raw]
Subject: Re: build error while building arch/x86/purgatory/sha256.o: invalid 'asm': operand is not a condition code [...]

On May 28, 2023 9:40:31 AM PDT, "Joan Bruguera Micó" <[email protected]> wrote:
>I can also reproduce the problem with Arch's linux-next-git, see config:
>https://aur.archlinux.org/cgit/aur.git/tree/config?h=linux-next-git&id=f9a384e1c582321651fb613782ebc5a581146af0
>
>I've bisected it to df8fc4e934c1 ("kbuild: Enable -fstrict-flex-arrays=3"),
>which explains why it only happens on GCC13.
>
>The problematic expansion that causes the error seems to be this fragment
>from `_BUG_FLAGS` in `arch/x86/include/asm/bug.h`:
> asm(".long %c0 - .\n": : "i" (__FILE__));
>
>Along with the fact that this file is built with `-mcmodel=large`
>(see `PURGATORY_CFLAGS` in `arch/x86/purgatory/Makefile`).

I haven't reproduced this yet, but the error implies that the asm input "i"mmediate value of the __FILE__ string address cannot be used with the asm template format "%c0" (a constant value).

https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html#Generic-Operand-Modifiers

I cannot fathom why struct flex array logic would change that...

I'll take a closer look in the morning.

-Kees


--
Kees Cook

2023-05-31 00:23:10

by Kees Cook

[permalink] [raw]
Subject: Re: build error while building arch/x86/purgatory/sha256.o: invalid 'asm': operand is not a condition code [...]

On Sun, May 28, 2023 at 04:40:31PM +0000, Joan Bruguera Mic? wrote:
> I can also reproduce the problem with Arch's linux-next-git, see config:
> https://aur.archlinux.org/cgit/aur.git/tree/config?h=linux-next-git&id=f9a384e1c582321651fb613782ebc5a581146af0
>
> I've bisected it to df8fc4e934c1 ("kbuild: Enable -fstrict-flex-arrays=3"),
> which explains why it only happens on GCC13.

Okay, this was a wild ride. Bottom line, -fstrict-flex-arrays=3 means
that CONFIG_FORTIFY_SOURCE wrappers will be included in new places now
that trailing arrays aren't ignored any more. The trailing array in
question was for struct sha256_state:

struct sha256_state {
u32 state[SHA256_DIGEST_SIZE / 4];
u64 count;
u8 buf[SHA256_BLOCK_SIZE];
};

And this "buf" is a memcpy() destination, it was being runtime bounds
checked, which means FORTIFY might emit wrappers, which will call the
WARN wrappers, which will hit this asm, which isn't supported in
purgatory.

>
> The problematic expansion that causes the error seems to be this fragment
> from `_BUG_FLAGS` in `arch/x86/include/asm/bug.h`:
> asm(".long %c0 - .\n": : "i" (__FILE__));
>
> Along with the fact that this file is built with `-mcmodel=large`
> (see `PURGATORY_CFLAGS` in `arch/x86/purgatory/Makefile`).

So, we can either disable fortify (which seems a big hammer) or disable
the warning. Disabling the warning kind of hides the problem, though
that seems to be the intention of purgatory.c's empty warn()
implementation. :P

I think it's best to disable fortify, though, as we're in a
DISABLE_EXPORTS state, and probably others are going to need it too, as
most other have already done so:

arch/arm64/kernel/pi/Makefile: -D__DISABLE_EXPORTS -ffreestanding -D__NO_FORTIFY \
arch/riscv/kernel/pi/Makefile:CFLAGS_cmdline_early.o += -D__NO_FORTIFY
arch/riscv/kernel/pi/Makefile:CFLAGS_lib-fdt_ro.o += -D__NO_FORTIFY
drivers/firmware/efi/libstub/Makefile: -D__NO_FORTIFY \

These should probably gain -D__NO_FORTIFY:

arch/riscv/purgatory/Makefile:CFLAGS_sha256.o := -D__DISABLE_EXPORTS
arch/riscv/purgatory/Makefile:CFLAGS_string.o := -D__DISABLE_EXPORTS
arch/riscv/purgatory/Makefile:CFLAGS_ctype.o := -D__DISABLE_EXPORTS
arch/s390/purgatory/Makefile:CFLAGS_sha256.o := -D__DISABLE_EXPORTS
arch/x86/purgatory/Makefile:CFLAGS_sha256.o := -D__DISABLE_EXPORTS

I'll send patches.

-Kees

--
Kees Cook