Thread (11 messages) 11 messages, 8 authors, 2009-06-09

Re: net: uninitialized loopback addr leaks to userspace

From: John Dykstra <hidden>
Date: 2009-06-07 21:03:50
Also in: lkml

On Sat, 2009-05-30 at 22:23 +0200, Vegard Nossum wrote:
It seems that loopback's hardware address is never initialized by the
kernel. So if userspace attempts to read this address before it has
been set, the kernel will return some uninitialized data (only 6
bytes, though).
Thank you for the report, Vegard.

I've been unable to reproduce the problem you describe, using
2.6-30-rc8, this test program and a couple of kernel builds for system
load:

------------------------------------------------------------------
#define REPEAT_COUNT 10000

int childTask() {
	struct ifreq ifreq;
	int fd;
	unsigned char allBits;

	fd = socket(AF_INET, SOCK_DGRAM, 0);
	if (fd < 0){
		printf("Error %s from socket()\n", strerror(errno));
		_exit(-1);
	}

	strncpy(ifreq.ifr_name, "lo", sizeof("lo"));
	if (ioctl (fd, SIOCGIFHWADDR, &ifreq) < 0){
		printf("Error %s from ioctl(SIOCGIFHWADDR) for %s.\n", strerror(errno), ifreq.ifr_name);
		_exit(-1);
	}
	
	allBits = ifreq.ifr_hwaddr.sa_data[0] |
			ifreq.ifr_hwaddr.sa_data[1] |
			ifreq.ifr_hwaddr.sa_data[2] |
			ifreq.ifr_hwaddr.sa_data[3] |
			ifreq.ifr_hwaddr.sa_data[4] |
			ifreq.ifr_hwaddr.sa_data[5];

	if (allBits != 0)
		printf("Device %s -> Ethernet %02x:%02x:%02x:%02x:%02x:%02x\n", ifreq.ifr_name,
			(int) ((unsigned char *) &ifreq.ifr_hwaddr.sa_data)[0],
			(int) ((unsigned char *) &ifreq.ifr_hwaddr.sa_data)[1],
			(int) ((unsigned char *) &ifreq.ifr_hwaddr.sa_data)[2],
			(int) ((unsigned char *) &ifreq.ifr_hwaddr.sa_data)[3],
			(int) ((unsigned char *) &ifreq.ifr_hwaddr.sa_data)[4],
			(int) ((unsigned char *) &ifreq.ifr_hwaddr.sa_data)[5]);
}


int main(int argc, char *argv[]) {
   	void **child_stack;
	int pid, i, status;

	child_stack = (void **) malloc(16384);

	for (i = 0; i < REPEAT_COUNT; i++){

		pid = clone(childTask, child_stack, CLONE_NEWNET, NULL);
		if (pid < 0){
			printf("Error %s from clone()\n", strerror(errno));
			_exit(-1);
		}
		
		pid = waitpid(pid, &status, __WCLONE);
		if (pid < 0){
			printf("Error %s from waitpid()\n", strerror(errno));
			_exit(-1);
		}
	}   
      
	return 0;
}
------------------------------------------------------------------

Looking at the kernel code, it appears that all bytes of struct
net_device, including the L2 address, are initialized to zeros at
interface creation time.

Can you spot a difference between your test procedures and mine that
would enable me to reproduce the problem?

  --  John
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help