Under some circumstances, udp6_output() would call ip6_clearpktopts()
with an uninitialized struct ip6_pktopts on the stack, opt. ip6_clearpktopts(&opt, ...) could dereference dangling pointers, leading to memory corruption or a crash. Now, udp6_output() calls ip6_clearpktopts(&opt, ...) only if opt was initialized. Thanks to Clement LECIGNE for reporting this bug. Fix a potential memory leak: it is udp6_output()'s responsibility to free its mbuf arguments on error. In the unlikely event that sa6_embedscope() failed, udp6_output() would not free its mbuf arguments. I will ask for this to be pulled up to -4, -5, and -5-0.
This commit is contained in:
parent
b5924bfd19
commit
a055a1e00a
@ -1,4 +1,4 @@
|
|||||||
/* $NetBSD: udp6_output.c,v 1.40 2010/07/08 00:12:35 dyoung Exp $ */
|
/* $NetBSD: udp6_output.c,v 1.41 2010/07/15 23:46:55 dyoung Exp $ */
|
||||||
/* $KAME: udp6_output.c,v 1.43 2001/10/15 09:19:52 itojun Exp $ */
|
/* $KAME: udp6_output.c,v 1.43 2001/10/15 09:19:52 itojun Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -62,7 +62,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
__KERNEL_RCSID(0, "$NetBSD: udp6_output.c,v 1.40 2010/07/08 00:12:35 dyoung Exp $");
|
__KERNEL_RCSID(0, "$NetBSD: udp6_output.c,v 1.41 2010/07/15 23:46:55 dyoung Exp $");
|
||||||
|
|
||||||
#include "opt_inet.h"
|
#include "opt_inet.h"
|
||||||
|
|
||||||
@ -128,7 +128,8 @@ udp6_output(struct in6pcb * const in6p, struct mbuf *m,
|
|||||||
int scope_ambiguous = 0;
|
int scope_ambiguous = 0;
|
||||||
u_int16_t fport;
|
u_int16_t fport;
|
||||||
int error = 0;
|
int error = 0;
|
||||||
struct ip6_pktopts *optp, opt;
|
struct ip6_pktopts *optp = NULL;
|
||||||
|
struct ip6_pktopts opt;
|
||||||
int af = AF_INET6, hlen = sizeof(struct ip6_hdr);
|
int af = AF_INET6, hlen = sizeof(struct ip6_hdr);
|
||||||
#ifdef INET
|
#ifdef INET
|
||||||
struct ip *ip;
|
struct ip *ip;
|
||||||
@ -163,7 +164,7 @@ udp6_output(struct in6pcb * const in6p, struct mbuf *m,
|
|||||||
if (sin6->sin6_scope_id == 0 && !ip6_use_defzone)
|
if (sin6->sin6_scope_id == 0 && !ip6_use_defzone)
|
||||||
scope_ambiguous = 1;
|
scope_ambiguous = 1;
|
||||||
if ((error = sa6_embedscope(sin6, ip6_use_defzone)) != 0)
|
if ((error = sa6_embedscope(sin6, ip6_use_defzone)) != 0)
|
||||||
return (error);
|
goto release;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (control) {
|
if (control) {
|
||||||
@ -417,7 +418,8 @@ release:
|
|||||||
|
|
||||||
releaseopt:
|
releaseopt:
|
||||||
if (control) {
|
if (control) {
|
||||||
ip6_clearpktopts(&opt, -1);
|
if (optp == &opt)
|
||||||
|
ip6_clearpktopts(&opt, -1);
|
||||||
m_freem(control);
|
m_freem(control);
|
||||||
}
|
}
|
||||||
return (error);
|
return (error);
|
||||||
|
Loading…
Reference in New Issue
Block a user