android_kernel_xiaomi_sm7250/drivers/platform
Nick Desaulniers 22bb7f773d platform: msm: gsi: Fix symbol versioning failure for gsi_write_channel_scratch
When building the kernel, we'd see the following warning:
WARNING: EXPORT symbol "gsi_write_channel_scratch" [vmlinux] version
generation failed, symbol will not be versioned.

When upgrading the kernel toolchain, the following related linkage
failure started occurring:
ld.lld: error: relocation R_AARCH64_ABS32 cannot be used against symbol
__crc_gsi_write_channel_scratch; recompile with -fPIC

This device config enables CONFIG_MODVERSIONS, a way of doing symbol
versioning, which can protect from loading kernel modules for which the
expected kernel interfaces (ABI) have changed.

CONFIG_MODVERSIONS uses scripts/genksyms/genksyms to create a file,
Module.symvers, that is a simple mapping of crc's of various symbols'
types to the symbol names.  It's produces these crc's by using the C
preprocessor, then passing this into genksyms. genksyms has a lex/yacc
based C parser to parse the preprocessed sources of kernel modules.  It
turns out that it's incomplete, copied from an upstream project that
ceased development in 2013, and was slated to be removed around the 4.9
kernel release.

Because genksyms's C parser is incomplete, it doesn't understand
compiler __attribute__'s on structs/enums/unions.  This has dire
implications for MODULE_EXPORT'ed function symbols that expect
__attribute__((packed)) structs/enums/unions, such as
gsi_write_channel_scratch.

The crc failure can be observed:
$ grep 0x00000000 out/android-msm-floral-4.14/private/msm-google/Module.symvers
0x00000000	gsi_write_channel_scratch	vmlinux	EXPORT_SYMBOL
$ echo 'union __attribute__((packed)) foo { char bar; };' | \
    ./scripts/genksyms/genksyms -d
Hash table occupancy 0/4096 = 0
$ echo 'union foo { char bar; };' | ./scripts/genksyms/genksyms -d
Defn for union foo == <union foo { char bar ; } >
Hash table occupancy 1/4096 = 0.000244141

This results in incorrect relocations being produced to the crc's.

Some possible solutions:
* Update the kernel's version of genksyms.  There's a comment that the
  kernel's sources were copied from "modutils." It seems that modutils'
  last release was v2.4.27 in 2004, and that development on it has
  stopped.  Upstream modutils also has the same parsing bug.
* Don't rely on MODVERSIONS.  While the current work being done on
  libabigail is meant to help, it's a build time only check and doesn't
  solve the problem of loading a potentially harmful kernel module at
  runtime. Further, Android has VTS tests for CONFIG_MODVERSIONS, which
  will take time to undo.
* Fix the parsing bug in genksysms. While the discussion about removing
  CONFIG_MODVERSIONS has started again upstream due to my bugreport,
  this would be the optimal solution, if I could just figure out how to
  rewrite the parser correctly.
* Adjust the definition of gsi_channel_scratch when __GENKSYMS__ is
  defined, such that the type appears to be something that genksyms can
  at least version.  This is suboptimal, but a quick enough fix to
  unblock the toolchain upgrade.

The final option is rather simple: __attribute__((packed)) only needs to
be applied to the declaration of a struct/enum/union, not everywhere its
used as a formal parameter or variable. For example:

struct __attribute__((packed)) foo { short z; int y; };
size_t bar(struct foo my_foo) { return sizeof(my_foo); }

would return 6 on an LP64 machine (and would return 8 if foo wasn't
packed).

Simply remove the __attribute__((packed)) from the declaration of
gsi_channel_scratch when __GENKSYMS__ is defined, and remove __packed
from all references to the type `union gsi_channel_scratch` since it's
not necessary (and the code was already inconsistent in its usage).

With gsi_write_channel_scratch being crc'ed correctly, we can now link
the kernel, and move on with the toolchain update.

A better long term solution would be to replace genksyms's
modutils/lex/yacc based incomplete and dead C parser with a libclang
based one, but such work is beyond the scope of a toolchain update.

For future travelers that would like to take a crack at fixing the
existing parser, I found the develop/build/test/debug cycle to be:

$ rm scripts/genksyms/genksyms
$ make scripts/genksyms/
$ ./scripts/genksyms/genksyms -d < test_case.i
$ ./scripts/genksyms/genksyms -d -d < test_case.i
Best of luck on that endeavor.

Signed-off-by: Andy Chang <andychangzxx@outlook.com>
Signed-off-by: Adam W. Willis <return.of.octobot@gmail.com>
2022-11-12 11:19:04 +00:00
..
chrome
goldfish
mellanox
mips
msm platform: msm: gsi: Fix symbol versioning failure for gsi_write_channel_scratch 2022-11-12 11:19:04 +00:00
olpc
x86 This is the 4.19.262 stable release 2022-10-30 16:23:17 +01:00
Kconfig
Makefile