From: Alexey Tourbin <at@altlinux.ru>
To: ALT Devel discussion list <devel@lists.altlinux.org>
Subject: Re: [devel] verify-elf lint=normal (elflint)
Date: Thu, 24 Dec 2009 07:33:04 +0300
Message-ID: <20091224043304.GF9864@altlinux.org> (raw)
In-Reply-To: <20091224005722.GE9864@altlinux.org>
[-- Attachment #1: Type: text/plain, Size: 8291 bytes --]
On Thu, Dec 24, 2009 at 03:57:22AM +0300, Alexey Tourbin wrote:
> On Mon, Dec 21, 2009 at 11:08:52PM +0300, Dmitry V. Levin wrote:
> > glibc-6:2.10.1-alt8
> > loadable segment [1] is writable but contains no writable sections
> > verify-elf: WARNING: ./sbin/glibc_preinstall: eu-elflint failed
>
> > klibc-1.5.15-alt4
> > loadable segment [3] is writable but contains no writable sections
> > verify-elf: WARNING: ./lib/mkinitrd/klibc/bin/cat: eu-elflint failed
> > [9 lines skipped]
> > verify-elf: WARNING: ./lib/mkinitrd/klibc/bin/umount: eu-elflint failed
> > loadable segment [3] is writable but contains no writable sections
> > verify-elf: WARNING: ./usr/lib/klibc/bin/cat: eu-elflint failed
> > [12 lines skipped]
> > section [ 4] '.interp' present in object file
> > section [ 4] '.interp' has SHF_ALLOC flag set but there is no loadable segment
> > verify-elf: WARNING: ./usr/lib/klibc/lib/interp.o: eu-elflint failed
>
> > util-linux-2.16.1-alt3
> > loadable segment [1] is writable but contains no writable sections
> > verify-elf: WARNING: ./sbin/nologin: eu-elflint failed
> > verify-elf: WARNING: ./usr/bin/pause: eu-elflint failed
>
> It looks like all klibc executables (compiled with klcc) are subject
> to this warning. Let's try to fix it before we discuss whether
> lint=normal should be on by default.
Let's test a simple program to examine the problem.
$ cat test.c
int foo = 0;
int main()
{
return 0;
}
$ klcc test.c && readelf --segments a.out && eu-elflint --gnu-ld a.out
Elf file type is EXEC (Executable file)
Entry point 0x4000e8
There are 3 program headers, starting at offset 64
Program Headers:
Type Offset VirtAddr PhysAddr
FileSiz MemSiz Flags Align
LOAD 0x0000000000000000 0x0000000000400000 0x0000000000400000
0x00000000000001ac 0x00000000000001ac R E 200000
LOAD 0x00000000000001b0 0x00000000006001b0 0x00000000006001b0
0x0000000000000000 0x0000000000000030 RW 200000
GNU_STACK 0x0000000000000000 0x0000000000000000 0x0000000000000000
Section to Segment mapping:
Segment Sections...
00 .text
01 .bss
02
loadable segment [1] is writable but contains no writable sections
$
The last line, which is eu-elflint output, suggests there's a problem.
Now, if we replace "foo = 0" with "foo = 1", the test will pass.
$ cat test.c
int foo = 1;
int main()
{
return 0;
}
$ klcc test.c && readelf --segments a.out && eu-elflint --gnu-ld a.out
Elf file type is EXEC (Executable file)
Entry point 0x4000e8
There are 3 program headers, starting at offset 64
Program Headers:
Type Offset VirtAddr PhysAddr
FileSiz MemSiz Flags Align
LOAD 0x0000000000000000 0x0000000000400000 0x0000000000400000
0x00000000000001ac 0x00000000000001ac R E 200000
LOAD 0x00000000000001ac 0x00000000006001ac 0x00000000006001ac
0x0000000000000004 0x000000000000002c RW 200000
GNU_STACK 0x0000000000000000 0x0000000000000000 0x0000000000000000
0x0000000000000000 0x0000000000000000 RWE 8
Section to Segment mapping:
Segment Sections...
00 .text
01 .data .bss
02
No errors
$
(The last line now says "No errors".)
So the problem is that, while ".data" section contributes to the ELF
segment being writable, ".bss" section alone does not.
Let's see the code.
elfutils-0.143/src/elflint.c:
3694 if (ehdr->e_type != ET_REL && (shdr->sh_flags & SHF_ALLOC) != 0)
3695 {
3696 /* Make sure the section is contained in a loaded segment
3697 and that the initialization part matches NOBITS sections. */
3698 int pcnt;
3699 GElf_Phdr phdr_mem;
3700 GElf_Phdr *phdr;
3701
3702 for (pcnt = 0; pcnt < ehdr->e_phnum; ++pcnt)
3703 if ((phdr = gelf_getphdr (ebl->elf, pcnt, &phdr_mem)) != NULL
3704 && ((phdr->p_type == PT_LOAD
3705 && (shdr->sh_flags & SHF_TLS) == 0)
3706 || (phdr->p_type == PT_TLS
3707 && (shdr->sh_flags & SHF_TLS) != 0))
3708 && phdr->p_offset <= shdr->sh_offset
3709 && (phdr->p_offset + phdr->p_filesz > shdr->sh_offset
3710 || (phdr->p_offset + phdr->p_memsz > shdr->sh_offset
3711 && shdr->sh_type == SHT_NOBITS)))
3712 {
3713 /* Found the segment. */
3714 if (phdr->p_offset + phdr->p_memsz
3715 < shdr->sh_offset + shdr->sh_size)
3716 ERROR (gettext ("\
3717 section [%2zu] '%s' not fully contained in segment of program header entry %d\n"),
3718 cnt, section_name (ebl, cnt), pcnt);
3719
3720 if (shdr->sh_type == SHT_NOBITS)
3721 {
3722 if (shdr->sh_offset < phdr->p_offset + phdr->p_filesz
3723 && !is_debuginfo)
3724 ERROR (gettext ("\
3725 section [%2zu] '%s' has type NOBITS but is read from the file in segment of program header entry %d\n"),
3726 cnt, section_name (ebl, cnt), pcnt);
3727 }
3728 else
3729 {
3730 const GElf_Off end = phdr->p_offset + phdr->p_filesz;
3731 if (shdr->sh_offset > end ||
3732 (shdr->sh_offset == end && shdr->sh_size != 0))
3733 ERROR (gettext ("\
3734 section [%2zu] '%s' has not type NOBITS but is not read from the file in segment of program header entry %d\n"),
3735 cnt, section_name (ebl, cnt), pcnt);
3736 }
3737
3738 if (shdr->sh_type != SHT_NOBITS)
3739 {
3740 if ((shdr->sh_flags & SHF_EXECINSTR) != 0)
3741 {
3742 segment_flags[pcnt] |= PF_X;
3743 if ((phdr->p_flags & PF_X) == 0)
3744 ERROR (gettext ("\
3745 section [%2zu] '%s' is executable in nonexecutable segment %d\n"),
3746 cnt, section_name (ebl, cnt), pcnt);
3747 }
3748
3749 if ((shdr->sh_flags & SHF_WRITE) != 0)
3750 {
3751 segment_flags[pcnt] |= PF_W;
3752 if (0 /* XXX vdso images have this */
3753 && (phdr->p_flags & PF_W) == 0)
3754 ERROR (gettext ("\
3755 section [%2zu] '%s' is writable in unwritable segment %d\n"),
3756 cnt, section_name (ebl, cnt), pcnt);
3757 }
3758 }
This code tests each allocatable section (3694) and, among other things,
sets segments_flags (3742, 3751) -- permissions which corresponding ELF
segment should have (the segments are tested later against segments_flags).
However, only NOBITS sections contribute to ELF segment flags (3738).
This is possibly wrong: ".bss" section, despite the fact that it is
NOBITS (filled with zeroes upon startup), should be writable.
Here's a dumb patch which fixes the problem.
--- src/elflint.c- 2009-12-24 01:09:24 +0000
+++ src/elflint.c 2009-12-24 03:48:23 +0000
@@ -3794,7 +3794,10 @@ section [%2zu] '%s' has not type NOBITS
section [%2zu] '%s' is executable in nonexecutable segment %d\n"),
cnt, section_name (ebl, cnt), pcnt);
}
+ }
+ if (shdr->sh_type != SHT_NOBITS || strcmp (scnname, ".bss") == 0)
+ {
if ((shdr->sh_flags & SHF_WRITE) != 0)
{
segment_flags[pcnt] |= PF_W;
[-- Attachment #2: Type: application/pgp-signature, Size: 198 bytes --]
next prev parent reply other threads:[~2009-12-24 4:33 UTC|newest]
Thread overview: 28+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-12-17 21:52 ` [devel] 5.1 FAILED cgal.git=3.5-alt0.M51.1 Alexey Tourbin
2009-12-17 21:59 ` Alexey Tourbin
2009-12-17 22:44 ` Dmitry V. Levin
2009-12-18 0:05 ` Alexey Tourbin
2009-12-18 0:59 ` [devel] elflint Alexey Tourbin
2009-12-18 3:21 ` Dmitry V. Levin
2009-12-18 17:27 ` Alexey Tourbin
2009-12-18 17:44 ` Dmitry V. Levin
2009-12-18 2:23 ` [devel] eu-elflint Dmitry V. Levin
2009-12-18 2:49 ` Alexey Tourbin
2009-12-19 0:26 ` [devel] verify-elf lint=normal (elflint) Alexey Tourbin
2009-12-19 19:50 ` Dmitry V. Levin
2009-12-19 21:03 ` Alexey Tourbin
2009-12-19 21:42 ` Dmitry V. Levin
2009-12-19 23:57 ` Alexey Tourbin
2009-12-20 2:37 ` Alexey Tourbin
2009-12-21 6:06 ` REAL
2009-12-21 6:02 ` Alexey Tourbin
2009-12-21 6:25 ` REAL
2009-12-21 18:06 ` [devel] [SOLVED] " Alexey Tourbin
2009-12-22 3:34 ` [devel] CMAKE please (was: [SOLVED] verify-elf lint=normal (elflint)) REAL
2009-12-21 20:08 ` [devel] verify-elf lint=normal (elflint) Dmitry V. Levin
2009-12-21 20:54 ` Michael Shigorin
2009-12-22 7:12 ` Anton Farygin
2009-12-24 0:57 ` Alexey Tourbin
2009-12-24 4:33 ` Alexey Tourbin [this message]
2009-12-21 8:47 ` Anton V. Boyarshinov
2009-12-21 10:55 ` Anton V. Boyarshinov
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20091224043304.GF9864@altlinux.org \
--to=at@altlinux.ru \
--cc=devel@lists.altlinux.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
ALT Linux Team development discussions
This inbox may be cloned and mirrored by anyone:
git clone --mirror http://lore.altlinux.org/devel/0 devel/git/0.git
# If you have public-inbox 1.1+ installed, you may
# initialize and index your mirror using the following commands:
public-inbox-init -V2 devel devel/ http://lore.altlinux.org/devel \
devel@altlinux.org devel@altlinux.ru devel@lists.altlinux.org devel@lists.altlinux.ru devel@linux.iplabs.ru mandrake-russian@linuxteam.iplabs.ru sisyphus@linuxteam.iplabs.ru
public-inbox-index devel
Example config snippet for mirrors.
Newsgroup available over NNTP:
nntp://lore.altlinux.org/org.altlinux.lists.devel
AGPL code for this site: git clone https://public-inbox.org/public-inbox.git