Need help with debugging (gcc bug?)

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hello,

Running kmemcheck, I got the following:
kmemcheck: Caught uninitialized read from EIP = c11aeba6
(sock_init_data+0xa6/0x17a), address c341a024, size 32
 [<c1218f62>] error_code+0x72/0x78
 [<c11aeba6>] sock_init_data+0xa6/0x17a
 [<c11c9db5>] __netlink_create+0x3b/0x85
 [<c11cbcd7>] netlink_kernel_create+0x59/0x148
 [<c135815a>] xfrm_user_init+0x3a/0x5a
 [<c120c421>] xfrm_netlink_rcv+0x0/0x24
 [<c1336491>] kernel_init+0x148/0x2aa
 [<c1004de6>] ret_from_fork+0x6/0x1c
 [<c1336349>] kernel_init+0x0/0x2aa
 [<c1336349>] kernel_init+0x0/0x2aa
 [<c1005aeb>] kernel_thread_helper+0x7/0x10
 =======================

Tracing the history of the address that it was accessing gives this:
KMEMCHECK_WRITE c341a024 SIZE 16 AT c11aca7b
KMEMCHECK_READ c341a024 SIZE 32 AT c11aeba6

So kmemcheck is clearly complaining because only 16 bits were
initialized on the first write, and then the whole 32 bits were read
back. Looking up the code addresses gives me the following:

(This is sock_create_lite() from net/socket.c)
c11aca48 <sock_create_lite>:
...
c11aca7b:       66 89 78 24             mov    %di,0x24(%eax)
...

(This is sock_init_data() from net/core/sock.c)
c11aeb00 <sock_init_data>:
...
c11aeba6:       8b 46 24                mov    0x24(%esi),%eax
c11aeba9:       66 89 43 2a             mov    %ax,0x2a(%ebx)
...

This shows quite clearly that indeed, the variable is initialized with
a 16-bit write and used later with a 32-bit read. The struct in
question is struct socket from include/linux/net.h, and the member it
is accessing is the socket->type:

struct socket {
        socket_state            state;
        unsigned long           flags;
        const struct proto_ops  *ops;
        struct fasync_struct    *fasync_list;
        struct file             *file;
        struct sock             *sk;
        wait_queue_head_t       wait;
        short                   type;
};

Here, offsetof(struct socket, type) = 0x24, like the one used in the
reads/writes. The type here is short, on 386 that's 16 bits. So why is
gcc later reading 32 bits off the same address, is that really legal?
Shouldn't that really have been a MOVZWL? Or did I miss something
obvious?

Kind regards,
Vegard Nossum

--
To unsubscribe from this list: send an email with
"unsubscribe kernelnewbies" to ecartis@xxxxxxxxxxxx
Please read the FAQ at http://kernelnewbies.org/FAQ


[Index of Archives]     [Newbies FAQ]     [Linux Kernel Mentors]     [Linux Kernel Development]     [IETF Annouce]     [Git]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux SCSI]     [Linux ACPI]
  Powered by Linux