From bd9f52d566a4e7d4881bc8df069dec2208235917 Mon Sep 17 00:00:00 2001 From: Hajimu UMEMOTO Date: Wed, 5 Nov 2003 09:41:23 +0000 Subject: [PATCH] - plug memory leak. - fixed a length of the sadb extension in the case of pfkey_send_x5(). - used getprotobynumber() for printing a upper layer protocol name. - modified the output format against the change of the setkey syntax about a icmp6 type/code. - don't enumerate reserved fields. use memset. Obtained from: KAME --- lib/libipsec/Makefile | 1 + lib/libipsec/ipsec_set_policy.3 | 16 +-- lib/libipsec/pfkey.c | 14 ++- lib/libipsec/pfkey_dump.c | 188 ++++++++++++++++++-------------- lib/libipsec/policy_parse.y | 17 ++- lib/libipsec/policy_token.l | 24 ++-- 6 files changed, 150 insertions(+), 110 deletions(-) diff --git a/lib/libipsec/Makefile b/lib/libipsec/Makefile index e09ef7feff89..d197caa2fdc6 100644 --- a/lib/libipsec/Makefile +++ b/lib/libipsec/Makefile @@ -24,6 +24,7 @@ # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # SUCH DAMAGE. +# # $FreeBSD$ LIB= ipsec diff --git a/lib/libipsec/ipsec_set_policy.3 b/lib/libipsec/ipsec_set_policy.3 index 5c63acffdda4..d9ee41163d7b 100644 --- a/lib/libipsec/ipsec_set_policy.3 +++ b/lib/libipsec/ipsec_set_policy.3 @@ -1,5 +1,5 @@ -.\" $KAME: ipsec_set_policy.3,v 1.15 2001/08/17 07:21:36 itojun Exp $ -.\" $FreeBSD$ +.\" $KAME: ipsec_set_policy.3,v 1.16 2003/01/06 21:59:03 sumikawa Exp $ +.\" $FreeBSD$ .\" .\" Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project. .\" All rights reserved. @@ -117,7 +117,7 @@ means to consult to SPD defined by .It Ar direction Li bypass .Li bypass means to be bypassed the IPsec processing. -(packet will be transmitted in clear). +.Pq packet will be transmitted in clear . This is for privileged socket. .It Xo .Ar direction @@ -174,7 +174,7 @@ is this node and .Ar src is the other node -(peer). +.Pq peer . If .Ar mode is @@ -203,9 +203,9 @@ regarding the system default. means that a relevant SA can be used when available, since the kernel may perform IPsec operation against packets when possible. In this case, packets can be transmitted in clear -(when SA is not available), +.Pq when SA is not available , or encrypted -(when SA is available). +.Pq when SA is available . .Li require means that a relevant SA is required, since the kernel must perform IPsec operation against packets. @@ -248,7 +248,7 @@ Refer to for detail. .Pp Here are several examples -(long lines are wrapped for readability): +.Pq long lines are wrapped for readability : .Bd -literal -offset indent in discard out ipsec esp/transport//require @@ -265,7 +265,7 @@ successful; otherwise a NULL pointer is returned. The .Fn ipsec_get_policylen function returns with positive value -(meaning the buffer size) +.Pq meaning the buffer size on success, and negative value on errors. The .Fn ipsec_dump_policy diff --git a/lib/libipsec/pfkey.c b/lib/libipsec/pfkey.c index 42137f90e80c..d7263eee7c59 100644 --- a/lib/libipsec/pfkey.c +++ b/lib/libipsec/pfkey.c @@ -1,4 +1,4 @@ -/* $KAME: pfkey.c,v 1.39 2001/03/05 18:22:17 thorpej Exp $ */ +/* $KAME: pfkey.c,v 1.46 2003/08/26 03:37:06 itojun Exp $ */ /* * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project. @@ -44,7 +44,6 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include #include "ipsec_strerror.h" #include "libpfkey.h" @@ -706,11 +705,14 @@ pfkey_recv_register(so) int error = -1; /* receive message */ - do { + for (;;) { if ((newmsg = pfkey_recv(so)) == NULL) return -1; - } while (newmsg->sadb_msg_type != SADB_REGISTER - || newmsg->sadb_msg_pid != pid); + if (newmsg->sadb_msg_type == SADB_REGISTER && + newmsg->sadb_msg_pid == pid) + break; + free(newmsg); + } /* check and fix */ newmsg->sadb_msg_len = PFKEY_UNUNIT64(newmsg->sadb_msg_len); @@ -1540,7 +1542,7 @@ pfkey_send_x5(so, type, spid) return -1; } memset(&xpl, 0, sizeof(xpl)); - xpl.sadb_x_policy_len = PFKEY_UNUNIT64(sizeof(xpl)); + xpl.sadb_x_policy_len = PFKEY_UNIT64(sizeof(xpl)); xpl.sadb_x_policy_exttype = SADB_X_EXT_POLICY; xpl.sadb_x_policy_id = spid; memcpy(p, &xpl, sizeof(xpl)); diff --git a/lib/libipsec/pfkey_dump.c b/lib/libipsec/pfkey_dump.c index 126e86881918..393f74ef2ec4 100644 --- a/lib/libipsec/pfkey_dump.c +++ b/lib/libipsec/pfkey_dump.c @@ -1,4 +1,4 @@ -/* $KAME: pfkey_dump.c,v 1.28 2001/06/27 10:46:51 sakane Exp $ */ +/* $KAME: pfkey_dump.c,v 1.45 2003/09/08 10:14:56 itojun Exp $ */ /* * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project. @@ -102,7 +102,8 @@ do { \ } while (0) static char *str_ipaddr(struct sockaddr *); -static char *str_prefport(u_int, u_int, u_int); +static char *str_prefport(u_int, u_int, u_int, u_int); +static void str_upperspec(u_int, u_int, u_int); static char *str_time(time_t); static void str_lifetime_byte(struct sadb_lifetime *, char *); @@ -133,22 +134,6 @@ static char *str_mode[] = { "tunnel", }; -static char *str_upper[] = { -/*0*/ "ip", "icmp", "igmp", "ggp", "ip4", - "", "tcp", "", "egp", "", -/*10*/ "", "", "", "", "", - "", "", "udp", "", "", -/*20*/ "", "", "idp", "", "", - "", "", "", "", "tp", -/*30*/ "", "", "", "", "", - "", "", "", "", "", -/*40*/ "", "ip6", "", "rt6", "frag6", - "", "rsvp", "gre", "", "", -/*50*/ "esp", "ah", "", "", "", - "", "", "", "icmp6", "none", -/*60*/ "dst6", -}; - static char *str_state[] = { "larval", "mature", @@ -381,9 +366,9 @@ pfkey_spdump(m) caddr_t mhp[SADB_EXT_MAX + 1]; struct sadb_address *m_saddr, *m_daddr; struct sadb_x_policy *m_xpl; - struct sadb_lifetime *m_lft = NULL; + struct sadb_lifetime *m_lftc = NULL, *m_lfth = NULL; struct sockaddr *sa; - u_int16_t port; + u_int16_t sport = 0, dport = 0; /* check pfkey message. */ if (pfkey_align(m, mhp)) { @@ -398,63 +383,60 @@ pfkey_spdump(m) m_saddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_SRC]; m_daddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_DST]; m_xpl = (struct sadb_x_policy *)mhp[SADB_X_EXT_POLICY]; - m_lft = (struct sadb_lifetime *)mhp[SADB_EXT_LIFETIME_HARD]; + m_lftc = (struct sadb_lifetime *)mhp[SADB_EXT_LIFETIME_CURRENT]; + m_lfth = (struct sadb_lifetime *)mhp[SADB_EXT_LIFETIME_HARD]; - /* source address */ - if (m_saddr == NULL) { - printf("no ADDRESS_SRC extension.\n"); - return; - } - sa = (struct sockaddr *)(m_saddr + 1); - switch (sa->sa_family) { - case AF_INET: - case AF_INET6: - if (getnameinfo(sa, sa->sa_len, NULL, 0, pbuf, sizeof(pbuf), - NI_NUMERICSERV) != 0) - port = 0; /*XXX*/ - else - port = atoi(pbuf); - printf("%s%s ", str_ipaddr(sa), - str_prefport(sa->sa_family, - m_saddr->sadb_address_prefixlen, port)); - break; - default: - printf("unknown-af "); - break; - } + if (m_saddr && m_daddr) { + /* source address */ + sa = (struct sockaddr *)(m_saddr + 1); + switch (sa->sa_family) { + case AF_INET: + case AF_INET6: + if (getnameinfo(sa, sa->sa_len, NULL, 0, + pbuf, sizeof(pbuf), NI_NUMERICSERV) != 0) + sport = 0; /*XXX*/ + else + sport = atoi(pbuf); + printf("%s%s ", str_ipaddr(sa), + str_prefport(sa->sa_family, + m_saddr->sadb_address_prefixlen, sport, + m_saddr->sadb_address_proto)); + break; + default: + printf("unknown-af "); + break; + } - /* destination address */ - if (m_daddr == NULL) { - printf("no ADDRESS_DST extension.\n"); - return; - } - sa = (struct sockaddr *)(m_daddr + 1); - switch (sa->sa_family) { - case AF_INET: - case AF_INET6: - if (getnameinfo(sa, sa->sa_len, NULL, 0, pbuf, sizeof(pbuf), - NI_NUMERICSERV) != 0) - port = 0; /*XXX*/ - else - port = atoi(pbuf); - printf("%s%s ", str_ipaddr(sa), - str_prefport(sa->sa_family, - m_daddr->sadb_address_prefixlen, port)); - break; - default: - printf("unknown-af "); - break; - } + /* destination address */ + sa = (struct sockaddr *)(m_daddr + 1); + switch (sa->sa_family) { + case AF_INET: + case AF_INET6: + if (getnameinfo(sa, sa->sa_len, NULL, 0, + pbuf, sizeof(pbuf), NI_NUMERICSERV) != 0) + dport = 0; /*XXX*/ + else + dport = atoi(pbuf); + printf("%s%s ", str_ipaddr(sa), + str_prefport(sa->sa_family, + m_daddr->sadb_address_prefixlen, dport, + m_saddr->sadb_address_proto)); + break; + default: + printf("unknown-af "); + break; + } - /* upper layer protocol */ - if (m_saddr->sadb_address_proto != m_daddr->sadb_address_proto) { - printf("upper layer protocol mismatched.\n"); - return; + /* upper layer protocol */ + if (m_saddr->sadb_address_proto != + m_daddr->sadb_address_proto) { + printf("upper layer protocol mismatched.\n"); + return; + } + str_upperspec(m_saddr->sadb_address_proto, sport, dport); } - if (m_saddr->sadb_address_proto == IPSEC_ULPROTO_ANY) - printf("any"); else - GETMSGSTR(str_upper, m_saddr->sadb_address_proto); + printf("(no selector, probably per-socket policy) "); /* policy */ { @@ -472,11 +454,19 @@ pfkey_spdump(m) } /* lifetime */ - if (m_lft) { - printf("\tlifetime:%lu validtime:%lu\n", - (u_long)m_lft->sadb_lifetime_addtime, - (u_long)m_lft->sadb_lifetime_usetime); + if (m_lftc) { + printf("\tcreated: %s ", + str_time(m_lftc->sadb_lifetime_addtime)); + printf("lastused: %s\n", + str_time(m_lftc->sadb_lifetime_usetime)); } + if (m_lfth) { + printf("\tlifetime: %lu(s) ", + (u_long)m_lfth->sadb_lifetime_addtime); + printf("validtime: %lu(s)\n", + (u_long)m_lfth->sadb_lifetime_usetime); + } + printf("\tspid=%ld seq=%ld pid=%ld\n", (u_long)m_xpl->sadb_x_policy_id, @@ -511,8 +501,8 @@ str_ipaddr(sa) * set "/prefix[port number]" to buffer. */ static char * -str_prefport(family, pref, port) - u_int family, pref, port; +str_prefport(family, pref, port, ulp) + u_int family, pref, port, ulp; { static char buf[128]; char prefbuf[128]; @@ -535,16 +525,50 @@ str_prefport(family, pref, port) else snprintf(prefbuf, sizeof(prefbuf), "/%u", pref); - if (port == IPSEC_PORT_ANY) - snprintf(portbuf, sizeof(portbuf), "[%s]", "any"); - else - snprintf(portbuf, sizeof(portbuf), "[%u]", port); + if (ulp == IPPROTO_ICMPV6) + memset(portbuf, 0, sizeof(portbuf)); + else { + if (port == IPSEC_PORT_ANY) + snprintf(portbuf, sizeof(portbuf), "[%s]", "any"); + else + snprintf(portbuf, sizeof(portbuf), "[%u]", port); + } snprintf(buf, sizeof(buf), "%s%s", prefbuf, portbuf); return buf; } +static void +str_upperspec(ulp, p1, p2) + u_int ulp, p1, p2; +{ + if (ulp == IPSEC_ULPROTO_ANY) + printf("any"); + else if (ulp == IPPROTO_ICMPV6) { + printf("icmp6"); + if (!(p1 == IPSEC_PORT_ANY && p2 == IPSEC_PORT_ANY)) + printf(" %u,%u", p1, p2); + } else { + struct protoent *ent; + + switch (ulp) { + case IPPROTO_IPV4: + printf("ip4"); + break; + default: + ent = getprotobynumber(ulp); + if (ent) + printf("%s", ent->p_name); + else + printf("%u", ulp); + + endprotoent(); + break; + } + } +} + /* * set "Mon Day Time Year" to buffer */ diff --git a/lib/libipsec/policy_parse.y b/lib/libipsec/policy_parse.y index c7788f5981ec..ae25958852cc 100644 --- a/lib/libipsec/policy_parse.y +++ b/lib/libipsec/policy_parse.y @@ -1,5 +1,4 @@ -/* $FreeBSD$ */ -/* $KAME: policy_parse.y,v 1.10 2000/05/07 05:25:03 itojun Exp $ */ +/* $KAME: policy_parse.y,v 1.14 2003/06/27 03:39:20 itojun Exp $ */ /* * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project. @@ -50,6 +49,9 @@ */ %{ +#include +__FBSDID("$FreeBSD$"); + #include #include #include @@ -85,9 +87,12 @@ static void policy_parse_request_init(void); static caddr_t policy_parse(char *msg, int msglen); extern void __policy__strbuffer__init__(char *msg); +extern void __policy__strbuffer__free__(void); extern int yyparse(void); extern int yylex(void); +extern char *__libipsecyytext; /*XXX*/ + %} %union { @@ -210,8 +215,6 @@ void yyerror(msg) char *msg; { - extern char *__libipsecyytext; /*XXX*/ - fprintf(stderr, "libipsec: %s while parsing \"%s\"\n", msg, __libipsecyytext); @@ -300,12 +303,14 @@ init_x_policy() __ipsec_errcode = EIPSEC_NO_BUFS; return -1; } + memset(pbuf, 0, tlen); p = (struct sadb_x_policy *)pbuf; p->sadb_x_policy_len = 0; /* must update later */ p->sadb_x_policy_exttype = SADB_X_EXT_POLICY; p->sadb_x_policy_type = p_type; p->sadb_x_policy_dir = p_dir; - p->sadb_x_policy_reserved = 0; + p->sadb_x_policy_id = 0; + offset = tlen; __ipsec_errcode = EIPSEC_NO_ERROR; @@ -398,6 +403,8 @@ policy_parse(msg, msglen) __policy__strbuffer__init__(msg); error = yyparse(); /* it must be set errcode. */ + __policy__strbuffer__free__(); + if (error) { if (pbuf != NULL) free(pbuf); diff --git a/lib/libipsec/policy_token.l b/lib/libipsec/policy_token.l index 11e0c06a330e..ced57b3fee71 100644 --- a/lib/libipsec/policy_token.l +++ b/lib/libipsec/policy_token.l @@ -1,5 +1,5 @@ /* $FreeBSD$ */ -/* $KAME: policy_token.l,v 1.11 2000/12/01 10:08:29 sakane Exp $ */ +/* $KAME: policy_token.l,v 1.13 2003/05/09 05:19:55 sakane Exp $ */ /* * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project. @@ -46,11 +46,7 @@ #include #include -#ifndef __NetBSD__ #include "y.tab.h" -#else -#include "policy_parse.h" -#endif #define yylval __libipsecyylval /* XXX */ int yylex(void); @@ -133,16 +129,26 @@ unique { yylval.num = IPSEC_LEVEL_UNIQUE; return(LEVEL); } %% void __policy__strbuffer__init__(char *); +void __policy__strbuffer__free__(void); + +static YY_BUFFER_STATE strbuffer; void __policy__strbuffer__init__(msg) char *msg; { - YY_BUFFER_STATE yyb; - - yyb = (YY_BUFFER_STATE)yy_scan_string(msg); - yy_switch_to_buffer(yyb); + if (yy_current_buffer) + yy_delete_buffer(yy_current_buffer); + strbuffer = (YY_BUFFER_STATE)yy_scan_string(msg); + yy_switch_to_buffer(strbuffer); return; } +void +__policy__strbuffer__free__() +{ + yy_delete_buffer(strbuffer); + + return; +}