Skip to content

NET_NS=n leads to strange program header in liblinux.so #48

Description

@pscollins

After make defconfig ARCH=lib && make library ARCH=lib, examining liblinux.so's program headers with readelf -l shows:

Program Headers:
  Type           Offset             VirtAddr           PhysAddr
                 FileSiz            MemSiz              Flags  Align
  LOAD           0x0000000000000000 0x0000000000000000 0x0000000000000000
                 0x00000000005eabf4 0x00000000005eabf4  **RWE**    200000
  LOAD           0x0000000000600000 0x0000000000800000 0x0000000000800000
                 0x000000000003b3f0 0x000000000004efe8  RW     200000
  DYNAMIC        0x000000000060f460 0x000000000080f460 0x000000000080f460
                 0x0000000000000180 0x0000000000000180  RW     8
  NOTE           0x00000000000001c8 0x00000000000001c8 0x00000000000001c8
                 0x0000000000000024 0x0000000000000024  R      4
  GNU_EH_FRAME   0x000000000057c050 0x000000000057c050 0x000000000057c050
                 0x000000000001600c 0x000000000001600c  R      4
  GNU_STACK      0x0000000000000000 0x0000000000000000 0x0000000000000000
                 0x0000000000000000 0x0000000000000000  RW     10
  GNU_RELRO      0x0000000000600000 0x0000000000800000 0x0000000000800000
                 0x0000000000011000 0x0000000000011000  R      1

 Section to Segment mapping:
  Segment Sections...
   00     .note.gnu.build-id .gnu.hash .dynsym .dynstr .rela.dyn .rela.plt .init .plt .text .init.text .sched.text .ref.text .exit.text .fini .rodata __ksymtab_strings .init.rodata .eh_frame_hdr .eh_frame

The issue is the rwx permissions on section 00. As far as I can tell, the ELF standard allows for executable regions to be writable, but this breaks some standard tools (in particular, Valgrind on amd64) and may cause very subtle bugs down the line. It will also cause issues if nuse is run on architectures with W^X protection. It is caused by a quirk of config options, and isn't necessary for the library to work.

The problem is in section .init.rodata, which has rw- permissions. The problem in .init.rodata comes from net/ipv6/{fib6_rules,addrlabel}.o and net/ipv4/{fib_rules,ipmr}.o, which all have .init.rodata sections with rw- permissions.

The problem there comes from the use of the following macros, defined in include/net/net_namespace.h:

#ifdef CONFIG_NET_NS
#define __net_init
#define __net_exit
#define __net_initdata
#define __net_initconst
#else
#define __net_init  __init
#define __net_exit  __exit_refok
#define __net_initdata  __initdata
#define __net_initconst __initconst
#endif

which depend on the macros defined in include/linux/init.h:

#define __init          __section(.init.text) __cold notrace
#define __initdata      __section(.init.data)
#define __initconst     __constsection(.init.rodata)
#define __exitdata      __section(.exit.data)
#define __exit_call     __used __section(.exitcall.exit)

It can be fixed either by changing the #ifdef CONFIG_NET_NS line in include/net/net_namespace.h to #if 1, or by adding:

config NET_NS
       def_bool y

to arch/lib/Kconfig. Then As far as I can tell, CONFIG_NET_NS=y doesn't break anything in nuse, but I haven't yet tested it thoroughly. There may be a better fix that involves changing the problematic functions annotated with __net_initconst in net/ipv6/{fib6_rules,addrlabel}.c and net/ipv4/{fib_rules,ipmr}.c --- presumably this is not intended behavior.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions