On Nov 20, 2007 12:16 PM, Vegard Nossum <[EMAIL PROTECTED]> wrote:
> 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?
I will add that compiling the file in question without optimisations
(it was -Os), it does indeed produce a MOVZWL instruction instead. I
am trying to construct a minimal test-case now. Help is still
appreciated.
Vegard
--
To unsubscribe from this list: send an email with
"unsubscribe kernelnewbies" to [EMAIL PROTECTED]
Please read the FAQ at http://kernelnewbies.org/FAQ