迭代ELF部分中的结构时错误的指针操作

时间:2013-09-15 14:33:22

标签: c pointers struct kernel kernel-module

我有这个POC可编译代码:

hello-1.c

#include <linux/module.h>
#include <linux/kernel.h>

char a, b, c;

asm(".section counters, \"aw\"");

typedef struct {
    atomic_t counter;
    char *name;
    int a;
    int b;
    void *ff;
    void *rf;
} __attribute__((packed)) counter_info_t;

#define __PUT_STUFF_IN_SECTION(_name)                   \
do{                                                     \
    static counter_info_t __counter_info_##_name        \
    __attribute((used, section("counters"))) = {        \
        .counter = ATOMIC_INIT(0),                      \
        .name = #_name,                                 \
        .a = 0,                                         \
        .b = 0,                                         \
        .ff = init_module,                              \
        .rf = init_module,                              \
    };                                                  \
}while(0)

extern counter_info_t __start_counters[];
extern counter_info_t __stop_counters[];

int init_module(void){
    __PUT_STUFF_IN_SECTION(a);
    __PUT_STUFF_IN_SECTION(b);
    __PUT_STUFF_IN_SECTION(c);

    return 0;
}

void cleanup_module(void){
    counter_info_t *iter = __start_counters;

    printk(KERN_INFO "Start %p\n", &__start_counters);

    for(; iter < __stop_counters; ++iter){
        printk(KERN_INFO "Name: %s.\n", iter->name);
    }

    printk(KERN_INFO "End %p\n", &__stop_counters);
    printk(KERN_INFO "Goodbye world!\n");
}

linkerscript.ld

SECTIONS
{
    counters : {
        __start_counters = . ;
        *(counters)
        __stop_counters = . ;
    }
}

Makefile

obj-m += hello.o

hello-y += hello-1.o
ldflags-y += -T$(M)/linkerscript.ld

all:
    make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules

clean:
    make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean

这段代码的作用是在一个部分中放置一些结构,然后迭代这些结构,打印每个结构的名称。

请注意,代码按原样将失败,打印错误的数据。无论如何,只从结构中删除一个成员(例如成员b),模块将开始正常工作。

我的问题是:为什么会失败?当struct有6个成员时,为什么++iter不会执行正确的指针操作,但是它可以在5个成员中正常工作?

重现的步骤:makesudo insmod hello.kosudo rmmod hellodmesg

编辑:添加readelf输出

ELF Header:
  Magic:   7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 
  Class:                             ELF64
  Data:                              2's complement, little endian
  Version:                           1 (current)
  OS/ABI:                            UNIX - System V
  ABI Version:                       0
  Type:                              REL (Relocatable file)
  Machine:                           Advanced Micro Devices X86-64
  Version:                           0x1
  Entry point address:               0x0
  Start of program headers:          0 (bytes into file)
  Start of section headers:          2808 (bytes into file)
  Flags:                             0x0
  Size of this header:               64 (bytes)
  Size of program headers:           0 (bytes)
  Number of program headers:         0
  Size of section headers:           64 (bytes)
  Number of section headers:         15
  Section header string table index: 10

Section Headers:
  [Nr] Name              Type             Address           Offset
       Size              EntSize          Flags  Link  Info  Align
  [ 0]                   NULL             0000000000000000  00000000
       0000000000000000  0000000000000000           0     0     0
  [ 1] .text             PROGBITS         0000000000000000  00000040
       0000000000000088  0000000000000000  AX       0     0     16
  [ 2] .rela.text        RELA             0000000000000000  00000838
       0000000000000168  0000000000000018          11     1     8
  [ 3] .data             PROGBITS         0000000000000000  000000c8
       0000000000000000  0000000000000000  WA       0     0     4
  [ 4] .bss              NOBITS           0000000000000000  000000c8
       0000000000000003  0000000000000000  WA       0     0     4
  [ 5] counters          PROGBITS         0000000000000000  000000e0
       00000000000000a4  0000000000000000  WA       0     0     32
  [ 6] .relacounters     RELA             0000000000000000  000009a0
       00000000000000d8  0000000000000018          11     5     8
  [ 7] .rodata.str1.1    PROGBITS         0000000000000000  00000184
       000000000000003b  0000000000000001 AMS       0     0     1
  [ 8] .comment          PROGBITS         0000000000000000  000001bf
       000000000000002b  0000000000000001  MS       0     0     1
  [ 9] .note.GNU-stack   PROGBITS         0000000000000000  000001ea
       0000000000000000  0000000000000000           0     0     1
  [10] .shstrtab         STRTAB           0000000000000000  00000a78
       0000000000000079  0000000000000000           0     0     1
  [11] .symtab           SYMTAB           0000000000000000  00000598
       00000000000001f8  0000000000000018          12    12     8
  [12] .strtab           STRTAB           0000000000000000  00000790
       00000000000000a4  0000000000000000           0     0     1
  [13] __mcount_loc      PROGBITS         0000000000000000  00000eb8
       0000000000000010  0000000000000008   A       0     0     8
  [14] .rela__mcount_loc RELA             0000000000000000  00000ec8
       0000000000000030  0000000000000018          11    13     8
Key to Flags:
  W (write), A (alloc), X (execute), M (merge), S (strings), l (large)
  I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)
  O (extra OS processing required) o (OS specific), p (processor specific)

There are no section groups in this file.

There are no program headers in this file.

Relocation section '.rela.text' at offset 0x838 contains 15 entries:
  Offset          Info           Type           Sym. Value    Sym. Name + Addend
000000000001  000d00000002 R_X86_64_PC32     0000000000000000 __fentry__ - 4
000000000011  000d00000002 R_X86_64_PC32     0000000000000000 __fentry__ - 4
00000000001b  000f0000000b R_X86_64_32S      0000000000000000 __start_counters + 0
000000000022  00060000000b R_X86_64_32S      0000000000000000 .rodata.str1.1 + 0
00000000002b  001000000002 R_X86_64_PC32     0000000000000000 printk - 4
000000000032  000f0000000b R_X86_64_32S      0000000000000000 __start_counters + 0
000000000038  00110000000b R_X86_64_32S      0000000000000000 __stop_counters + 0
000000000041  00110000000b R_X86_64_32S      0000000000000000 __stop_counters + 0
000000000048  00060000000b R_X86_64_32S      0000000000000000 .rodata.str1.1 + c
00000000004f  001000000002 R_X86_64_PC32     0000000000000000 printk - 4
000000000056  00060000000b R_X86_64_32S      0000000000000000 .rodata.str1.1 + 16
00000000005d  001000000002 R_X86_64_PC32     0000000000000000 printk - 4
000000000070  00060000000b R_X86_64_32S      0000000000000000 .rodata.str1.1 + 28
000000000079  001000000002 R_X86_64_PC32     0000000000000000 printk - 4
000000000080  00110000000b R_X86_64_32S      0000000000000000 __stop_counters + 0

Relocation section '.relacounters' at offset 0x9a0 contains 9 entries:
  Offset          Info           Type           Sym. Value    Sym. Name + Addend
000000000004  000600000001 R_X86_64_64       0000000000000000 .rodata.str1.1 + 35
000000000014  000c00000001 R_X86_64_64       0000000000000000 init_module + 0
00000000001c  000c00000001 R_X86_64_64       0000000000000000 init_module + 0
000000000044  000600000001 R_X86_64_64       0000000000000000 .rodata.str1.1 + 37
000000000054  000c00000001 R_X86_64_64       0000000000000000 init_module + 0
00000000005c  000c00000001 R_X86_64_64       0000000000000000 init_module + 0
000000000084  000600000001 R_X86_64_64       0000000000000000 .rodata.str1.1 + 39
000000000094  000c00000001 R_X86_64_64       0000000000000000 init_module + 0
00000000009c  000c00000001 R_X86_64_64       0000000000000000 init_module + 0

Relocation section '.rela__mcount_loc' at offset 0xec8 contains 2 entries:
  Offset          Info           Type           Sym. Value    Sym. Name + Addend
000000000000  000200000001 R_X86_64_64       0000000000000000 .text + 0
000000000008  000200000001 R_X86_64_64       0000000000000000 .text + 10

The decoding of unwind sections for machine type Advanced Micro Devices X86-64 is not currently supported.

Symbol table '.symtab' contains 21 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND 
     1: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS hello-1.c
     2: 0000000000000000     0 SECTION LOCAL  DEFAULT    1 
     3: 0000000000000000     0 SECTION LOCAL  DEFAULT    3 
     4: 0000000000000000     0 SECTION LOCAL  DEFAULT    4 
     5: 0000000000000000     0 SECTION LOCAL  DEFAULT    5 
     6: 0000000000000000     0 SECTION LOCAL  DEFAULT    7 
     7: 0000000000000000    36 OBJECT  LOCAL  DEFAULT    5 __counter_info_a.14513
     8: 0000000000000040    36 OBJECT  LOCAL  DEFAULT    5 __counter_info_b.14514
     9: 0000000000000080    36 OBJECT  LOCAL  DEFAULT    5 __counter_info_c.14515
    10: 0000000000000000     0 SECTION LOCAL  DEFAULT    9 
    11: 0000000000000000     0 SECTION LOCAL  DEFAULT    8 
    12: 0000000000000000    13 FUNC    GLOBAL DEFAULT    1 init_module
    13: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND __fentry__
    14: 0000000000000010   120 FUNC    GLOBAL DEFAULT    1 cleanup_module
    15: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND __start_counters
    16: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND printk
    17: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND __stop_counters
    18: 0000000000000000     1 OBJECT  GLOBAL DEFAULT    4 c
    19: 0000000000000001     1 OBJECT  GLOBAL DEFAULT    4 b
    20: 0000000000000002     1 OBJECT  GLOBAL DEFAULT    4 a

No version information found in this file.

0 个答案:

没有答案