Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 9 Jun 2019 23:15:57 -0700
From:      Mark Millard <marklmi@yahoo.com>
To:        FreeBSD Hackers <freebsd-hackers@freebsd.org>, freeBSD PowerPC ML <freebsd-ppc@freebsd.org>
Subject:   kern_execve using vm_page_zero_invalid but not vm_page_set_validclean to load /sbin/init ?
Message-ID:  <1464D960-A1D6-404A-BB10-E615E2D14C1D@yahoo.com>

next in thread | raw e-mail | index | archive | help
This leads up to questioning if .sbss and .bss
in /sbin/init are always correctly zeroed. But
I may have missed something in the sequencing.
(The code is not familiar material.)

If I've tracked it down right:

sys/kern/kern_exec.c uses kern_execve top deal with
starting up /sbin/init.

kern_execve uses do_execve.

do_execve uses:

/*
 * Each of the items is a pointer to a `const struct execsw', hence the
 * double pointer here.
 */
static const struct execsw **execsw;
. . .
        /*
         *      Loop through the list of image activators, calling each =
one.
         *      An activator returns -1 if there is no match, 0 on =
success,
         *      and an error otherwise.
         */
        for (i =3D 0; error =3D=3D -1 && execsw[i]; ++i) {
                if (execsw[i]->ex_imgact =3D=3D NULL ||
                    execsw[i]->ex_imgact =3D=3D img_first) {
                        continue;
                }
                error =3D (*execsw[i]->ex_imgact)(imgp);
        }

/usr/src/sys/kern/imgact_elf.c has:

/*
 * Tell kern_execve.c about it, with a little help from the linker.
 */
static struct execsw __elfN(execsw) =3D {
        .ex_imgact =3D __CONCAT(exec_, __elfN(imgact)),
        .ex_name =3D __XSTRING(__CONCAT(ELF, __ELF_WORD_SIZE))
};
EXEC_SET(__CONCAT(elf, __ELF_WORD_SIZE), __elfN(execsw));


__CONCAT(exec_, __elfN(imgact)) uses
__elfN(load_sections) .

__elfN(load_sections) uses __elfN(load_section).

__elfN(load_section) uses vm_imgact_map_page
to set up for its copyout. This appears to be
how the FileSiz (not including .sbss or .bss)
vs. MemSiz (including .sbss and .bss) is
handled (attempted?).

vm_imgact_map_page uses vm_imgact_hold_page.

vm_imgact_hold_page uses vm_pager_get_pages.

vm_pager_get_pages uses vm_page_zero_invalid
to "Zero out partially filled data".

But vm_page_zero_invalid does not zero every "invalid"
byte but works in terms of units of DEV_BSIZE :

void
vm_page_zero_invalid(vm_page_t m, boolean_t setvalid)
{
        int b;
        int i;

        VM_OBJECT_ASSERT_WLOCKED(m->object);
        /*
         * Scan the valid bits looking for invalid sections that
         * must be zeroed.  Invalid sub-DEV_BSIZE'd areas ( where the
         * valid bit may be set ) have already been zeroed by
         * vm_page_set_validclean().
         */
        for (b =3D i =3D 0; i <=3D PAGE_SIZE / DEV_BSIZE; ++i) {
                if (i =3D=3D (PAGE_SIZE / DEV_BSIZE) ||
                    (m->valid & ((vm_page_bits_t)1 << i))) {
                        if (i > b) {
                                pmap_zero_page_area(m,
                                    b << DEV_BSHIFT, (i - b) << =
DEV_BSHIFT);
                        }
                        b =3D i + 1;
                }
        }

        /*
         * setvalid is TRUE when we can safely set the zero'd areas
         * as being valid.  We can do this if there are no cache =
consistancy
         * issues.  e.g. it is ok to do with UFS, but not ok to do with =
NFS.
         */
        if (setvalid)
                m->valid =3D VM_PAGE_BITS_ALL;
}

The comment indicates that areas of "sub-DEV_BSIZE"
should have been handled previously by
vm_page_set_validclean .

But no part of the sequence appears to use
vm_page_set_validclean .


So, if, say, char**environ ends up at the start of .sbss
consistently, does environ always end up zeroed independently
of FileSz for the PT_LOAD that spans them?

The following is not necessarily an example of problematical
figures but is just for showing an example structure of what
FileSiz covers vs. MemSiz for PT_LOAD's that involve .sbss
and .bss :

Program Headers:
  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg =
Align
  LOAD           0x000000 0x01800000 0x01800000 0x1222dc 0x1222dc R E =
0x10000
  LOAD           0x123000 0x01933000 0x01933000 0x0618c 0x32e88 RWE =
0x10000
  NOTE           0x0000d4 0x018000d4 0x018000d4 0x00048 0x00048 R   0x4
  TLS            0x123000 0x01933000 0x01933000 0x00b10 0x00b1d R   0x10
  GNU_STACK      0x000000 0x00000000 0x00000000 0x00000 0x00000 RW  0x10

 Section to Segment mapping:
  Segment Sections...
   00     .note.tag .init .text .fini .rodata .eh_frame=20
   01     .tdata .tbss .init_array .fini_array .ctors .dtors .jcr =
.data.rel.ro .data .got .sbss .bss=20
   02     .note.tag=20
   03     .tdata .tbss=20
   04    =20
There are 24 section headers, starting at offset 0x14eb20:

Section Headers:
  [Nr] Name              Type            Addr     Off    Size   ES Flg =
Lk Inf Al
  [ 0]                   NULL            00000000 000000 000000 00      =
0   0  0
  [ 1] .note.tag         NOTE            018000d4 0000d4 000048 00   A  =
0   0  4
  [ 2] .init             PROGBITS        0180011c 00011c 000034 00  AX  =
0   0  4
  [ 3] .text             PROGBITS        01800150 000150 111e14 00  AX  =
0   0 16
  [ 4] .fini             PROGBITS        01911f64 111f64 000030 00  AX  =
0   0  4
  [ 5] .rodata           PROGBITS        01911fc0 111fc0 010318 00   A  =
0   0 64
  [ 6] .eh_frame         PROGBITS        019222d8 1222d8 000004 00   A  =
0   0  4
  [ 7] .tdata            PROGBITS        01933000 123000 000b10 00 WAT  =
0   0 16
  [ 8] .tbss             NOBITS          01933b10 123b10 00000d 00 WAT  =
0   0  4
  [ 9] .init_array       INIT_ARRAY      01933b10 123b10 000008 04  WA  =
0   0  4
  [10] .fini_array       FINI_ARRAY      01933b18 123b18 000004 04  WA  =
0   0  4
  [11] .ctors            PROGBITS        01933b1c 123b1c 000008 00  WA  =
0   0  4
  [12] .dtors            PROGBITS        01933b24 123b24 000008 00  WA  =
0   0  4
  [13] .jcr              PROGBITS        01933b2c 123b2c 000004 00  WA  =
0   0  4
  [14] .data.rel.ro      PROGBITS        01933b30 123b30 002ee4 00  WA  =
0   0  4
  [15] .data             PROGBITS        01936a18 126a18 002763 00  WA  =
0   0  8
  [16] .got              PROGBITS        0193917c 12917c 000010 04 WAX  =
0   0  4
  [17] .sbss             NOBITS          0193918c 12918c 0000b0 00  WA  =
0   0  4
  [18] .bss              NOBITS          01939240 12918c 02cc48 00  WA  =
0   0 64
  [19] .comment          PROGBITS        00000000 12918c 0073d4 01  MS  =
0   0  1
  [20] .gnu_debuglink    PROGBITS        00000000 130560 000010 00      =
0   0  4
  [21] .symtab           SYMTAB          00000000 130570 00fc40 10     =
22 1681  4
  [22] .strtab           STRTAB          00000000 1401b0 00e8b3 00      =
0   0  1
  [23] .shstrtab         STRTAB          00000000 14ea63 0000bc 00      =
0   0  1
. . .
  2652: 000000000193918c     4 OBJECT  GLOBAL DEFAULT   17 environ


=3D=3D=3D
Mark Millard
marklmi at yahoo.com
( dsl-only.net went
away in early 2018-Mar)




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?1464D960-A1D6-404A-BB10-E615E2D14C1D>