• P
    cipso: don't follow a NULL pointer when setsockopt() is called · 89d7ae34
    Paul Moore 提交于
    As reported by Alan Cox, and verified by Lin Ming, when a user
    attempts to add a CIPSO option to a socket using the CIPSO_V4_TAG_LOCAL
    tag the kernel dies a terrible death when it attempts to follow a NULL
    pointer (the skb argument to cipso_v4_validate() is NULL when called via
    the setsockopt() syscall).
    
    This patch fixes this by first checking to ensure that the skb is
    non-NULL before using it to find the incoming network interface.  In
    the unlikely case where the skb is NULL and the user attempts to add
    a CIPSO option with the _TAG_LOCAL tag we return an error as this is
    not something we want to allow.
    
    A simple reproducer, kindly supplied by Lin Ming, although you must
    have the CIPSO DOI #3 configure on the system first or you will be
    caught early in cipso_v4_validate():
    
    	#include <sys/types.h>
    	#include <sys/socket.h>
    	#include <linux/ip.h>
    	#include <linux/in.h>
    	#include <string.h>
    
    	struct local_tag {
    		char type;
    		char length;
    		char info[4];
    	};
    
    	struct cipso {
    		char type;
    		char length;
    		char doi[4];
    		struct local_tag local;
    	};
    
    	int main(int argc, char **argv)
    	{
    		int sockfd;
    		struct cipso cipso = {
    			.type = IPOPT_CIPSO,
    			.length = sizeof(struct cipso),
    			.local = {
    				.type = 128,
    				.length = sizeof(struct local_tag),
    			},
    		};
    
    		memset(cipso.doi, 0, 4);
    		cipso.doi[3] = 3;
    
    		sockfd = socket(AF_INET, SOCK_DGRAM, 0);
    		#define SOL_IP 0
    		setsockopt(sockfd, SOL_IP, IP_OPTIONS,
    			&cipso, sizeof(struct cipso));
    
    		return 0;
    	}
    
    CC: Lin Ming <mlin@ss.pku.edu.cn>
    Reported-by: NAlan Cox <alan@lxorguk.ukuu.org.uk>
    Signed-off-by: NPaul Moore <pmoore@redhat.com>
    Signed-off-by: NDavid S. Miller <davem@davemloft.net>
    89d7ae34
cipso_ipv4.c 63.4 KB