Subject: Alignment problems in socket calls

From: Ralph Siemsen <[email-masked]>
Date: Wed, 19 Apr 2000 14:50:22 -0400

The socket code in net/ipv4/ip_sockglue.c seems to make some assumptions
about the alignment of the data passed in (char *optval).  If a string
of 4 bytes or more is passed in, and therefore optlen >= sizeof(int),
then get_user() performs a word read.  This will fail if optval is not
aligned correctly, and faults the user  process.  However, the prototype
(char *) does not imply any required alignment restrictions.  Can anyone
shed some light on why the code is written this way?

To reproduce the bug, try "ipchains -F foo".  If the name of the chain
contains an odd number of characters, ipchains will be stopped by an
alignment fault ('not handling ldrt/strt correctly') because get_user()
is called on an unaligned buffer that originally came from getopt(). 
This was first reported by Mark Lord on the netwinder bugtraq list.

Relevant code from net/ipv4/ip_sockglue.c (kernel 2.2.14):

int ip_setsockopt(struct sock *sk, int level, 
	int optname, char *optval, int optlen)
{
	int val=0,err;
#if defined(CONFIG_IP_FIREWALL)
	char tmp_fw[MAX(sizeof(struct ip_fwtest),sizeof(struct ip_fwnew))];
#endif
	if(optlen>=sizeof(int)) {
		if(get_user(val, (int *) optval))
			return -EFAULT;
	} else if(optlen>=sizeof(char)) {
		unsigned char ucval;
		if(get_user(ucval, (unsigned char *) optval))
			return -EFAULT;
		val = (int)ucval;
	}

-- 
Ralph Siemsen -- [email-masked]

unsubscribe: body of `unsubscribe linux-arm-kernel' to [email-masked]