Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

zfs_log: add flex array fields to log record structs #16539

Merged
merged 1 commit into from
Sep 27, 2024

Conversation

robn
Copy link
Member

@robn robn commented Sep 16, 2024

Motivation and Context

Silence Linux warnings since ~6.11.

Closes #16501.

Description

ZIL log record structs (lr_XX_t) are frequently allocated with extra space after the struct to carry variable-sized "payload" items.

Linux 6.10+ compiled with CONFIG_FORTIFY_SOURCE has been doing runtime bounds checking on memcpy() calls. Because these types had no indicator that they might use more space than their simple definition, __fortify_memcpy_chk will frequently complain about overruns eg:

memcpy: detected field-spanning write (size 7) of single field "lr + 1" at /home/robn/zfs/module/zfs/zfs_log.c:425 (size 0)
memcpy: detected field-spanning write (size 9) of single field "(char *)(lr + 1)" at /home/robn/zfs/module/zfs/zfs_log.c:593 (size 0)
memcpy: detected field-spanning write (size 4) of single field "(char *)(lr + 1) + snamesize" at /home/robn/zfs/module/zfs/zfs_log.c:594 (size 0)
memcpy: detected field-spanning write (size 7) of single field "lr + 1" at /home/robn/zfs/module/zfs/zfs_log.c:425 (size 0)
memcpy: detected field-spanning write (size 9) of single field "(char *)(lr + 1)" at /home/robn/zfs/module/zfs/zfs_log.c:593 (size 0)
memcpy: detected field-spanning write (size 4) of single field "(char *)(lr + 1) + snamesize" at /home/robn/zfs/module/zfs/zfs_log.c:594 (size 0)
memcpy: detected field-spanning write (size 7) of single field "lr + 1" at /home/robn/zfs/module/zfs/zfs_log.c:425 (size 0)
memcpy: detected field-spanning write (size 9) of single field "(char *)(lr + 1)" at /home/robn/zfs/module/zfs/zfs_log.c:593 (size 0)
memcpy: detected field-spanning write (size 4) of single field "(char *)(lr + 1) + snamesize" at /home/robn/zfs/module/zfs/zfs_log.c:594 (size 0)

To fix this, this commit adds flex array fields to all lr_XX_t structs that require them, and then uses those fields to access that end-of-struct area rather than more complicated casts and pointer addition.

I'll note here that I wrote this a few weeks ago and kind of forgot about it. I remember I didn't love it; it felt messy in a couple of places. But, it passes tests, and 6.11 is here and 2.3 is looming, so its probably better to post this sooner rather than later.

How Has This Been Tested?

Full ZTS run completed against 6.11.0.

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Performance enhancement (non-breaking change which improves efficiency)
  • Code cleanup (non-breaking change which makes code smaller or more readable)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Library ABI change (libzfs, libzfs_core, libnvpair, libuutil and libzfsbootenv)
  • Documentation (a change to man pages or other documentation)

Checklist:

module/zfs/zfs_log.c Outdated Show resolved Hide resolved
module/zfs/zfs_log.c Outdated Show resolved Hide resolved
ZIL log record structs (lr_XX_t) are frequently allocated with extra
space after the struct to carry variable-sized "payload" items.

Linux 6.10+ compiled with CONFIG_FORTIFY_SOURCE has been doing runtime
bounds checking on memcpy() calls. Because these types had no indicator
that they might use more space than their simple definition,
__fortify_memcpy_chk will frequently complain about overruns eg:

    memcpy: detected field-spanning write (size 7) of single field
        "lr + 1" at zfs_log.c:425 (size 0)
    memcpy: detected field-spanning write (size 9) of single field
        "(char *)(lr + 1)" at zfs_log.c:593 (size 0)
    memcpy: detected field-spanning write (size 4) of single field
        "(char *)(lr + 1) + snamesize" at zfs_log.c:594 (size 0)
    memcpy: detected field-spanning write (size 7) of single field
        "lr + 1" at zfs_log.c:425 (size 0)
    memcpy: detected field-spanning write (size 9) of single field
        "(char *)(lr + 1)" at zfs_log.c:593 (size 0)
    memcpy: detected field-spanning write (size 4) of single field
        "(char *)(lr + 1) + snamesize" at zfs_log.c:594 (size 0)
    memcpy: detected field-spanning write (size 7) of single field
        "lr + 1" at zfs_log.c:425 (size 0)
    memcpy: detected field-spanning write (size 9) of single field
        "(char *)(lr + 1)" at zfs_log.c:593 (size 0)
    memcpy: detected field-spanning write (size 4) of single field
        "(char *)(lr + 1) + snamesize" at zfs_log.c:594 (size 0)

To fix this, this commit adds flex array fields to all lr_XX_t structs
that require them, and then uses those fields to access that
end-of-struct area rather than more complicated casts and pointer
addition.

Signed-off-by: Rob Norris <[email protected]>
Sponsored-by: https://despairlabs.com/sponsor/
@behlendorf behlendorf added Status: Accepted Ready to integrate (reviewed, tested) and removed Status: Code Review Needed Ready for review and testing labels Sep 27, 2024
@behlendorf behlendorf merged commit 6f50f8e into openzfs:master Sep 27, 2024
20 of 21 checks passed
@darkbasic
Copy link

Could you please backport this into the 2.2.x branch? It's been two months without any commit on staging: is 2.3 nearing release or what?

@darkbasic
Copy link

Yeah it looks like so: https://github.com/openzfs/zfs/releases/tag/zfs-2.3.0-rc1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Status: Accepted Ready to integrate (reviewed, tested)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

memcpy: detected field-spanning write
4 participants