Skip to content

Commit a080e65

Browse files
pcmooregregkh
authored andcommitted
cipso: don't follow a NULL pointer when setsockopt() is called
[ Upstream commit 89d7ae3 ] 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: Alan Cox <alan@lxorguk.ukuu.org.uk> Signed-off-by: Paul Moore <pmoore@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent 60d2aa5 commit a080e65

File tree

1 file changed

+4
-2
lines changed

1 file changed

+4
-2
lines changed

net/ipv4/cipso_ipv4.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1725,8 +1725,10 @@ int cipso_v4_validate(const struct sk_buff *skb, unsigned char **option)
17251725
case CIPSO_V4_TAG_LOCAL:
17261726
/* This is a non-standard tag that we only allow for
17271727
* local connections, so if the incoming interface is
1728-
* not the loopback device drop the packet. */
1729-
if (!(skb->dev->flags & IFF_LOOPBACK)) {
1728+
* not the loopback device drop the packet. Further,
1729+
* there is no legitimate reason for setting this from
1730+
* userspace so reject it if skb is NULL. */
1731+
if (skb == NULL || !(skb->dev->flags & IFF_LOOPBACK)) {
17301732
err_offset = opt_iter;
17311733
goto validate_return_locked;
17321734
}

0 commit comments

Comments
 (0)