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

Core dump notes parsing error #90

Closed
anfedotoff opened this issue May 26, 2018 · 6 comments
Closed

Core dump notes parsing error #90

anfedotoff opened this issue May 26, 2018 · 6 comments

Comments

@anfedotoff
Copy link
Contributor

Hello,
I ran into a problem, while parsing notes in core dump of my test program. The error occurs from bad alignment. My alignment is equal to 0.

 match alignment {
                    4 => bytes.gread_with::<Nhdr32>(offset, ctx.le)?.into(),
                    // this is a guess; i haven't seen gcc/clang compilers emit 64-bit notes, and i don't have any non gcc/clang compilers
                    8 => bytes.gread_with::<Nhdr64>(offset, ctx.le)?.into(),
                    _ => return Err(error::Error::Malformed(format!("Notes has unimplemented alignment requirement: {:#x}", alignment)))
}

But readelf works perfectly fine and parses core dump correctly. I looked into source code of readelf and found this:

/* NB: Some note sections may have alignment value of 0 or 1.  gABI
     specifies that notes should be aligned to 4 bytes in 32-bit
     objects and to 8 bytes in 64-bit objects.  As a Linux extension,
     we also support 4 byte alignment in 64-bit objects.  If section
     alignment is less than 4, we treate alignment as 4 bytes.   */
  if (align < 4)
    align = 4;
  else if (align != 4 && align != 8)
    {
      warn (_("Corrupt note: alignment %ld, expecting 4 or 8\n"),
	    (long) align);
      return FALSE;
}

As I see, match should be like this:

match alignment {
                    0 ... 4 => bytes.gread_with::<Nhdr32>(offset, ctx.le)?.into(),
                    // this is a guess; i haven't seen gcc/clang compilers emit 64-bit notes, and i don't have any non gcc/clang compilers
                    8 => bytes.gread_with::<Nhdr64>(offset, ctx.le)?.into(),
                    _ => return Err(error::Error::Malformed(format!("Notes has unimplemented alignment requirement: {:#x}", alignment)))
}
@philipc
Copy link
Collaborator

philipc commented May 27, 2018

You're right that there's a problem there. I looked into the readelf behaviour a bit more.

binutils readelf behaviour:

  • treat alignments of 0 ... 4 as 4, accept alignment of 8, reject everything else
  • always use 32 bit note header, except for IA64 on OpenVMS

(This means readelf can use a 64 bit alignment with a 32 bit note header.)

llvm-readobj behaviour:

  • always use alignment 4
  • always use 32 bit note header

So I think we should

  • use your proposed change for alignments of 0 ... 4
  • use Nhdr32 even for alignments of 8

Can you submit a PR for that? Note that for the 0 ... 4 case you need to make sure you use the alignment of 4 when reading desc, so it might be better to do that by modifying alignment before doing the match.

Adding support for OpenVMS notes probably isn't worth the effort, since binutils has a few other fixes for OpenVMS elsewhere too.

cc @m4b, who has looked into this before.

@m4b
Copy link
Owner

m4b commented May 27, 2018

@philipc recommendation seems good to me! Most important is to get it parsing.

Just curious, @xcoldhandsx what is the precise error you get, and can you also paste the readelf/objdump of the core file ? Thanks !

@anfedotoff
Copy link
Contributor Author

I've just created the pull request with some fix for solving this problem including @philipc recommendations. I also attach the output of readelf (readelf -l ../core)

Elf file type is CORE (Core file)
Entry point 0x0
There are 18 program headers, starting at offset 64

Program Headers:
  Type           Offset             VirtAddr           PhysAddr
                 FileSiz            MemSiz              Flags  Align
  NOTE           0x0000000000000430 0x0000000000000000 0x0000000000000000
                 0x0000000000000bb8 0x0000000000000000         0x0
  LOAD           0x0000000000001000 0x00005630bfd42000 0x0000000000000000
                 0x0000000000001000 0x0000000000001000  R E    0x1000
  LOAD           0x0000000000002000 0x00005630bff42000 0x0000000000000000
                 0x0000000000001000 0x0000000000001000  R      0x1000
  LOAD           0x0000000000003000 0x00005630bff43000 0x0000000000000000
                 0x0000000000001000 0x0000000000001000  RW     0x1000
  LOAD           0x0000000000004000 0x00007f5433763000 0x0000000000000000
                 0x0000000000001000 0x00000000001e7000  R E    0x1000
  LOAD           0x0000000000005000 0x00007f543394a000 0x0000000000000000
                 0x0000000000000000 0x0000000000200000         0x1000
  LOAD           0x0000000000005000 0x00007f5433b4a000 0x0000000000000000
                 0x0000000000004000 0x0000000000004000  R      0x1000
  LOAD           0x0000000000009000 0x00007f5433b4e000 0x0000000000000000
                 0x0000000000002000 0x0000000000002000  RW     0x1000
  LOAD           0x000000000000b000 0x00007f5433b50000 0x0000000000000000
                 0x0000000000004000 0x0000000000004000  RW     0x1000
  LOAD           0x000000000000f000 0x00007f5433b54000 0x0000000000000000
                 0x0000000000001000 0x0000000000027000  R E    0x1000
  LOAD           0x0000000000010000 0x00007f5433d64000 0x0000000000000000
                 0x0000000000002000 0x0000000000002000  RW     0x1000
  LOAD           0x0000000000012000 0x00007f5433d7b000 0x0000000000000000
                 0x0000000000001000 0x0000000000001000  R      0x1000
  LOAD           0x0000000000013000 0x00007f5433d7c000 0x0000000000000000
                 0x0000000000001000 0x0000000000001000  RW     0x1000
  LOAD           0x0000000000014000 0x00007f5433d7d000 0x0000000000000000
                 0x0000000000001000 0x0000000000001000  RW     0x1000
  LOAD           0x0000000000015000 0x00007ffd97063000 0x0000000000000000
                 0x0000000000021000 0x0000000000021000  RW     0x1000
  LOAD           0x0000000000036000 0x00007ffd971f9000 0x0000000000000000
                 0x0000000000003000 0x0000000000003000  R      0x1000
  LOAD           0x0000000000039000 0x00007ffd971fc000 0x0000000000000000
                 0x0000000000002000 0x0000000000002000  R E    0x1000
  LOAD           0x000000000003b000 0xffffffffff600000 0x0000000000000000
                 0x0000000000001000 0x0000000000001000  R E    0x1000

@philipc
Copy link
Collaborator

philipc commented May 28, 2018

Fixed by #91

@philipc philipc closed this as completed May 28, 2018
@Swatinem
Copy link
Contributor

Its been a long time…
I have been running into a similar problem here:

align(alignment, offset);

This is using alignment, which is 8 in this case as it comes from the program header.

However the ELF manpage is pretty clear on this using a 4 byte alignment:

https://www.mankier.com/5/elf#Description-Notes_(Nhdr)

Each note is followed by the name field (whose length is defined in n_namesz) and then by the descriptor field (whose length is defined in n_descsz) and whose starting address has a 4 byte alignment.

The example given there is also hardcoding a 4 byte alignment even though the example is using Elf64_Nhdr.

@philipc
Copy link
Collaborator

philipc commented Apr 12, 2023

@Swatinem Can you open a new issue and provide steps to reproduce?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants