libos-nuse / net-next-nuse

Network Stack in Userspace
Other
289 stars 67 forks source link

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

Open pscollins opened 8 years ago

pscollins commented 8 years ago

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.

pscollins commented 8 years ago

Actually, I was wrong --- CONFIG_NET_NS=y leads to a build error. The other solution still works, though.

thehajime commented 8 years ago

thanks for the issue report (and sorry to be late).

it's indeed a problem with the inappropriate elf header and would be great if we can work with valgrind, which is always useful.

this is a bit off-topic though but I've been thinking to this arch/lib code to migrate into LKL (linux kernel library), which I'm recently working on. i'm not yet porting all the stuff of net-next-nuse but i see the bright future with a clean design of lkl, which I expect to solve several issues of this repo (including #45).

https://github.com/libos-nuse/lkl-linux is my working repository. it would be great if you still see this issue in lkl-linux.

pscollins commented 8 years ago

@thehajime I'll take a look at it. This was an extraordinarily weird problem --- I'd be surprised if it turned up again.

Which branch of that repo is the most current one?

thehajime commented 8 years ago

(sorry for the cross-post)

I would suggest to use https://github.com/lkl/linux, not my branch (https://github.com/libos-nuse/lkl-linux) as mine is unstable while the upstream is relatively stable.