[d-kernel] I: Oops на 2.4.26-std-smp-alt12 в transaction.c (ext3)

Sergey Vlasov vsu на altlinux.ru
Чт Окт 20 20:32:28 MSD 2005


On Thu, Oct 20, 2005 at 05:22:03PM +0400, Alexey I. Froloff wrote:
> * Alexey I. Froloff <raorn@> [051020 11:59]:
> > Пару месяцев назад писал сюда про свой Oops.  На IRC vsu@ мне
> > посоветовал пересобрать ядро с DEBUG_STACKOVERFLOW, лог в аттаче.

Похоже, совет был всё-таки правильным (а DEBUG_STACKOVERFLOW, возможно,
стоит включать по умолчанию - при этом добавляется только одна проверка в
do_IRQ()).

> dmesg | ksymoops тоже в аттаче.

Оказывается, функция ipsec_tunnel_start_xmit() использует для локальных
переменных 1212 байт в стеке.  Безобразие.

Следующим патчем удалось сократить запросы этой функции до 420 байт (хотя
это тоже слишком много).  Патч не тестировался ничем, кроме компилятора.


--- kernel-source-2.4.26/net/ipsec/ipsec_tunnel.c.ipsec_tunnel-stack	2005-09-08 18:25:59 +0400
+++ kernel-source-2.4.26/net/ipsec/ipsec_tunnel.c	2005-10-20 20:19:08 +0400
@@ -592,10 +592,8 @@ ipsec_tunnel_start_xmit(struct sk_buff *
 	int i;
 	unsigned short   sport,dport;
 
-	struct sockaddr_encap matcher;	/* eroute search key */
 	struct eroute *er;
 	struct ipsec_sa *tdbp, *tdbq;	/* Tunnel Descriptor Block pointers */
-	char sa[SATOA_BUF];
 	size_t sa_len;
 	int hard_header_stripped = 0;	/* has the hard header been removed yet? */
 	int hard_header_len = 0;
@@ -613,7 +611,6 @@ ipsec_tunnel_start_xmit(struct sk_buff *
 #endif /* NET_21 */
 	int error = 0;
 	uint32_t eroute_pid = 0;
-	struct ipsec_sa tdb;
 #ifdef CONFIG_IPSEC_ALG
 	struct ipsec_alg_enc *ixt_e = NULL;
 	struct ipsec_alg_auth *ixt_a = NULL;
@@ -623,11 +620,30 @@ ipsec_tunnel_start_xmit(struct sk_buff *
 	uint8_t natt_type = 0, natt_head = 0;
 	uint16_t natt_sport = 0, natt_dport = 0;
 #endif
+	struct {
+		struct sockaddr_encap matcher;	/* eroute search key */
+		char sa[SATOA_BUF];
+		struct ipsec_sa tdb;
+		struct sockaddr_in src, dst;
+#ifdef CONFIG_IPSEC_DEBUG
+		char bufsrc[ADDRTOA_BUF], bufdst[ADDRTOA_BUF];
+#endif /* CONFIG_IPSEC_DEBUG */
+		struct iphdr ipo;
+#if defined(CONFIG_IPSEC_AUTH_HMAC_MD5) || defined(CONFIG_IPSEC_AUTH_HMAC_SHA1)
+		union {
+#ifdef CONFIG_IPSEC_AUTH_HMAC_MD5
+			MD5_CTX md5;
+#endif /* CONFIG_IPSEC_AUTH_HMAC_MD5 */
+#ifdef CONFIG_IPSEC_AUTH_HMAC_SHA1
+			SHA1_CTX sha1;
+#endif /* CONFIG_IPSEC_AUTH_HMAC_SHA1 */
+		} tctx;
+		__u8 hash[AH_AMAX];
+#endif /* defined(CONFIG_IPSEC_AUTH_HMAC_MD5) || defined(CONFIG_IPSEC_AUTH_HMAC_SHA1) */
+	} *locals = 0;			/* local variables too big for stack */
 
 	dport=sport=0;
 
-	memset((char*)&tdb, 0, sizeof(struct ipsec_sa));
-
 	/*
 	 *	Return if there is nothing to do.  (Does this ever happen?) XXX
 	 */
@@ -664,6 +680,18 @@ ipsec_tunnel_start_xmit(struct sk_buff *
 
 	stats = (struct net_device_stats *) &(prv->mystats);
 
+	locals = kmalloc(sizeof(*locals), GFP_ATOMIC);
+	if (!locals) {
+		if (net_ratelimit())
+			printk(KERN_WARNING "klips_debug:ipsec_tunnel_start_xmit: "
+			       "Failed, tried to allocate %ld bytes for local variables.\n", 
+			       (long)sizeof(*locals));
+		stats->tx_dropped++;
+		goto cleanup;
+	}
+
+	memset((char*)&locals->tdb, 0, sizeof(struct ipsec_sa));
+
 #ifdef NET_21
 	/* if skb was cloned (most likely due to a packet sniffer such as
 	   tcpdump being momentarily attached to the interface), make
@@ -780,13 +808,13 @@ ipsec_tunnel_start_xmit(struct sk_buff *
 	/*
 	 * First things first -- look us up in the erouting tables.
 	 */
-	matcher.sen_len = sizeof (struct sockaddr_encap);
-	matcher.sen_family = AF_ENCAP;
-	matcher.sen_type = SENT_IP4;
-	matcher.sen_ip_src.s_addr = iph->saddr;
-	matcher.sen_ip_dst.s_addr = iph->daddr;
-	matcher.sen_proto = iph->protocol;
-	extract_ports(iph, &matcher);
+	locals->matcher.sen_len = sizeof (struct sockaddr_encap);
+	locals->matcher.sen_family = AF_ENCAP;
+	locals->matcher.sen_type = SENT_IP4;
+	locals->matcher.sen_ip_src.s_addr = iph->saddr;
+	locals->matcher.sen_ip_dst.s_addr = iph->daddr;
+	locals->matcher.sen_proto = iph->protocol;
+	extract_ports(iph, &locals->matcher);
 
 	/*
 	 * The spinlock is to prevent any other process from accessing or deleting
@@ -794,7 +822,7 @@ ipsec_tunnel_start_xmit(struct sk_buff *
 	 */
 	spin_lock(&eroute_lock);
 	
-	er = ipsec_findroute(&matcher);
+	er = ipsec_findroute(&locals->matcher);
 
 	if(iph->protocol == IPPROTO_UDP) {
 		if(skb->sk) {
@@ -877,12 +905,12 @@ ipsec_tunnel_start_xmit(struct sk_buff *
 		       || (outgoing_said.spi==htonl(SPI_TRAPSUBNET)))) {
 			int len;
 			
-			tdb.tdb_ident_s.type = er->er_ident_s.type;
-			tdb.tdb_ident_s.id = er->er_ident_s.id;
-			tdb.tdb_ident_s.len = er->er_ident_s.len;
-			if (tdb.tdb_ident_s.len) {
-				len = tdb.tdb_ident_s.len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident);
-				if ((tdb.tdb_ident_s.data = kmalloc(len, GFP_ATOMIC)) == NULL) {
+			locals->tdb.tdb_ident_s.type = er->er_ident_s.type;
+			locals->tdb.tdb_ident_s.id = er->er_ident_s.id;
+			locals->tdb.tdb_ident_s.len = er->er_ident_s.len;
+			if (locals->tdb.tdb_ident_s.len) {
+				len = locals->tdb.tdb_ident_s.len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident);
+				if ((locals->tdb.tdb_ident_s.data = kmalloc(len, GFP_ATOMIC)) == NULL) {
 					printk(KERN_WARNING "klips_debug:ipsec_tunnel_start_xmit: "
 					       "Failed, tried to allocate %d bytes for source ident.\n", 
 					       len);
@@ -890,14 +918,14 @@ ipsec_tunnel_start_xmit(struct sk_buff *
 					spin_unlock(&eroute_lock);
 					goto cleanup;
 				}
-				memcpy(tdb.tdb_ident_s.data, er->er_ident_s.data, len);
+				memcpy(locals->tdb.tdb_ident_s.data, er->er_ident_s.data, len);
 			}
-			tdb.tdb_ident_d.type = er->er_ident_d.type;
-			tdb.tdb_ident_d.id = er->er_ident_d.id;
-			tdb.tdb_ident_d.len = er->er_ident_d.len;
-			if (tdb.tdb_ident_d.len) {
-				len = tdb.tdb_ident_d.len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident);
-				if ((tdb.tdb_ident_d.data = kmalloc(len, GFP_ATOMIC)) == NULL) {
+			locals->tdb.tdb_ident_d.type = er->er_ident_d.type;
+			locals->tdb.tdb_ident_d.id = er->er_ident_d.id;
+			locals->tdb.tdb_ident_d.len = er->er_ident_d.len;
+			if (locals->tdb.tdb_ident_d.len) {
+				len = locals->tdb.tdb_ident_d.len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident);
+				if ((locals->tdb.tdb_ident_d.data = kmalloc(len, GFP_ATOMIC)) == NULL) {
 					printk(KERN_WARNING "klips_debug:ipsec_tunnel_start_xmit: "
 					       "Failed, tried to allocate %d bytes for dest ident.\n", 
 					       len);
@@ -905,7 +933,7 @@ ipsec_tunnel_start_xmit(struct sk_buff *
 					spin_unlock(&eroute_lock);
 					goto cleanup;
 				}
-				memcpy(tdb.tdb_ident_d.data, er->er_ident_d.data, len);
+				memcpy(locals->tdb.tdb_ident_d.data, er->er_ident_d.data, len);
 			}
 		}
 	}
@@ -970,24 +998,19 @@ ipsec_tunnel_start_xmit(struct sk_buff *
 			case SPI_TRAP:
 			case SPI_TRAPSUBNET:
 			{
-				struct sockaddr_in src, dst;
-#ifdef CONFIG_IPSEC_DEBUG
-				char bufsrc[ADDRTOA_BUF], bufdst[ADDRTOA_BUF];
-#endif /* CONFIG_IPSEC_DEBUG */
-				
 				/* Signal all listening KMds with a PF_KEY ACQUIRE */
-				tdb.tdb_said.proto = iph->protocol;
-				src.sin_family = AF_INET;
-				dst.sin_family = AF_INET;
-				src.sin_addr.s_addr = iph->saddr;
-				dst.sin_addr.s_addr = iph->daddr;
-				src.sin_port = 
+				locals->tdb.tdb_said.proto = iph->protocol;
+				locals->src.sin_family = AF_INET;
+				locals->dst.sin_family = AF_INET;
+				locals->src.sin_addr.s_addr = iph->saddr;
+				locals->dst.sin_addr.s_addr = iph->daddr;
+				locals->src.sin_port = 
 					(iph->protocol == IPPROTO_UDP
 					 ? ((struct udphdr*) (((caddr_t)iph) + (iph->ihl << 2)))->source
 					 : (iph->protocol == IPPROTO_TCP
 					    ? ((struct tcphdr*)((caddr_t)iph + (iph->ihl << 2)))->source
 					    : 0));
-				dst.sin_port = 
+				locals->dst.sin_port = 
 					(iph->protocol == IPPROTO_UDP
 					 ? ((struct udphdr*) (((caddr_t)iph) + (iph->ihl << 2)))->dest
 					 : (iph->protocol == IPPROTO_TCP
@@ -997,22 +1020,22 @@ ipsec_tunnel_start_xmit(struct sk_buff *
 				    i < sizeof(struct sockaddr_in)
 					    - offsetof(struct sockaddr_in, sin_zero);
 				    i++) {
-					src.sin_zero[i] = 0;
-					dst.sin_zero[i] = 0;
+					locals->src.sin_zero[i] = 0;
+					locals->dst.sin_zero[i] = 0;
 				}
 				
-				tdb.tdb_addr_s = (struct sockaddr*)(&src);
-				tdb.tdb_addr_d = (struct sockaddr*)(&dst);
+				locals->tdb.tdb_addr_s = (struct sockaddr*)(&locals->src);
+				locals->tdb.tdb_addr_d = (struct sockaddr*)(&locals->dst);
 				KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
 					    "klips_debug:ipsec_tunnel_start_xmit: "
 					    "SADB_ACQUIRE sent with src=%s:%d, dst=%s:%d, proto=%d.\n",
-					    addrtoa(((struct sockaddr_in*)(tdb.tdb_addr_s))->sin_addr, 0, bufsrc, sizeof(bufsrc)) <= ADDRTOA_BUF ? bufsrc : "BAD_ADDR",
-					    ntohs(((struct sockaddr_in*)(tdb.tdb_addr_s))->sin_port),
-					    addrtoa(((struct sockaddr_in*)(tdb.tdb_addr_d))->sin_addr, 0, bufdst, sizeof(bufdst)) <= ADDRTOA_BUF ? bufdst : "BAD_ADDR",
-					    ntohs(((struct sockaddr_in*)(tdb.tdb_addr_d))->sin_port),
-					    tdb.tdb_said.proto);
+					    addrtoa(((struct sockaddr_in*)(locals->tdb.tdb_addr_s))->sin_addr, 0, locals->bufsrc, sizeof(locals->bufsrc)) <= ADDRTOA_BUF ? locals->bufsrc : "BAD_ADDR",
+					    ntohs(((struct sockaddr_in*)(locals->tdb.tdb_addr_s))->sin_port),
+					    addrtoa(((struct sockaddr_in*)(locals->tdb.tdb_addr_d))->sin_addr, 0, locals->bufdst, sizeof(locals->bufdst)) <= ADDRTOA_BUF ? locals->bufdst : "BAD_ADDR",
+					    ntohs(((struct sockaddr_in*)(locals->tdb.tdb_addr_d))->sin_port),
+					    locals->tdb.tdb_said.proto);
 				
-				if (pfkey_acquire(&tdb) == 0) {
+				if (pfkey_acquire(&locals->tdb) == 0) {
 					
 					if (outgoing_said.spi==htonl(SPI_TRAPSUBNET)) {
 						/*
@@ -1022,7 +1045,7 @@ ipsec_tunnel_start_xmit(struct sk_buff *
 						 * updating it.
 						 */
 						spin_lock(&eroute_lock);
-						er = ipsec_findroute(&matcher);
+						er = ipsec_findroute(&locals->matcher);
 						if(er) {
 							er->er_said.spi = htonl(SPI_HOLD);
 							er->er_first = skb;
@@ -1056,14 +1079,14 @@ ipsec_tunnel_start_xmit(struct sk_buff *
 		spin_lock(&tdb_lock);
 
 		tdbp = ipsec_sa_getbyid(&outgoing_said);
-		sa_len = satoa(outgoing_said, 0, sa, SATOA_BUF);
+		sa_len = satoa(outgoing_said, 0, locals->sa, SATOA_BUF);
 
 		if (tdbp == NULL) {
 			spin_unlock(&tdb_lock);
 			KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
 				    "klips_debug:ipsec_tunnel_start_xmit: "
 				    "no Tunnel Descriptor Block for SA%s: outgoing packet with no SA, dropped.\n",
-				    sa_len ? sa : " (error)");
+				    sa_len ? locals->sa : " (error)");
 			stats->tx_dropped++;
 			goto cleanup;
 		}
@@ -1072,7 +1095,7 @@ ipsec_tunnel_start_xmit(struct sk_buff *
 			    "klips_debug:ipsec_tunnel_start_xmit: "
 			    "found Tunnel Descriptor Block -- SA:<%s%s%s> %s\n",
 			    IPS_XFORM_NAME(tdbp),
-			    sa_len ? sa : " (error)");
+			    sa_len ? locals->sa : " (error)");
 		
 		/*
 		 * How much headroom do we need to be able to apply
@@ -1080,9 +1103,9 @@ ipsec_tunnel_start_xmit(struct sk_buff *
 		 */
 		tdbq = tdbp;	/* save the head of the tdb chain */
 		while (tdbp)	{
-			sa_len = satoa(tdbp->tdb_said, 0, sa, SATOA_BUF);
+			sa_len = satoa(tdbp->tdb_said, 0, locals->sa, SATOA_BUF);
 			if(sa_len == 0) {
-				strcpy(sa, "(error)");
+				strcpy(locals->sa, "(error)");
 			}
 
 			/* If it is in larval state, drop the packet, we cannot process yet. */
@@ -1091,7 +1114,7 @@ ipsec_tunnel_start_xmit(struct sk_buff *
 					    "klips_debug:ipsec_tunnel_start_xmit: "
 					    "TDB in larval state for SA:<%s%s%s> %s, cannot be used yet, dropping packet.\n",
 					    IPS_XFORM_NAME(tdbp),
-					    sa_len ? sa : " (error)");
+					    sa_len ? locals->sa : " (error)");
 				spin_unlock(&tdb_lock);
 				stats->tx_errors++;
 				goto cleanup;
@@ -1102,7 +1125,7 @@ ipsec_tunnel_start_xmit(struct sk_buff *
 					    "klips_debug:ipsec_tunnel_start_xmit: "
 					    "TDB in dead state for SA:<%s%s%s> %s, can no longer be used, dropping packet.\n",
 					    IPS_XFORM_NAME(tdbp),
-					    sa_len ? sa : " (error)");
+					    sa_len ? locals->sa : " (error)");
 				spin_unlock(&tdb_lock);
 				stats->tx_errors++;
 				goto cleanup;
@@ -1115,7 +1138,7 @@ ipsec_tunnel_start_xmit(struct sk_buff *
 					    "klips_debug:ipsec_tunnel_start_xmit: "
 					    "replay window counter rolled for SA:<%s%s%s> %s, packet dropped, expiring SA.\n",
 					    IPS_XFORM_NAME(tdbp),
-					    sa_len ? sa : " (error)");
+					    sa_len ? locals->sa : " (error)");
 				ipsec_sa_delchain(tdbp);
 				spin_unlock(&tdb_lock);
 				stats->tx_errors++;
@@ -1135,13 +1158,13 @@ ipsec_tunnel_start_xmit(struct sk_buff *
 #endif
 			  
 
-			if(ipsec_lifetime_check(&tdbp->ips_life.ipl_bytes, "bytes", sa, 
+			if(ipsec_lifetime_check(&tdbp->ips_life.ipl_bytes, "bytes", locals->sa, 
 						ipsec_life_countbased, ipsec_outgoing, tdbp) == ipsec_life_harddied ||
-			   ipsec_lifetime_check(&tdbp->ips_life.ipl_addtime, "addtime",sa,
+			   ipsec_lifetime_check(&tdbp->ips_life.ipl_addtime, "addtime",locals->sa,
 						ipsec_life_timebased,  ipsec_outgoing, tdbp) == ipsec_life_harddied ||
-			   ipsec_lifetime_check(&tdbp->ips_life.ipl_usetime, "usetime",sa,
+			   ipsec_lifetime_check(&tdbp->ips_life.ipl_usetime, "usetime",locals->sa,
 						ipsec_life_timebased,  ipsec_outgoing, tdbp) == ipsec_life_harddied ||
-			   ipsec_lifetime_check(&tdbp->ips_life.ipl_packets, "packets",sa,
+			   ipsec_lifetime_check(&tdbp->ips_life.ipl_packets, "packets",locals->sa,
 						ipsec_life_countbased, ipsec_outgoing, tdbp) == ipsec_life_harddied) {
 				
 				ipsec_sa_delchain(tdbp);
@@ -1156,7 +1179,7 @@ ipsec_tunnel_start_xmit(struct sk_buff *
 				    "klips_debug:ipsec_tunnel_start_xmit: "
 				    "calling room for <%s%s%s>, SA:%s\n", 
 				    IPS_XFORM_NAME(tdbp),
-				    sa_len ? sa : " (error)");
+				    sa_len ? locals->sa : " (error)");
 			switch(tdbp->tdb_said.proto) {
 #ifdef CONFIG_IPSEC_AH
 			case IPPROTO_AH:
@@ -1552,31 +1575,19 @@ ipsec_tunnel_start_xmit(struct sk_buff *
 			int authlen = 0, padlen = 0, i;
 #endif /* !CONFIG_IPSEC_ESP */
 #ifdef CONFIG_IPSEC_AH
-			struct iphdr ipo;
 			struct ah *ahp;
 #endif /* CONFIG_IPSEC_AH */
-#if defined(CONFIG_IPSEC_AUTH_HMAC_MD5) || defined(CONFIG_IPSEC_AUTH_HMAC_SHA1)
-			union {
-#ifdef CONFIG_IPSEC_AUTH_HMAC_MD5
-				MD5_CTX md5;
-#endif /* CONFIG_IPSEC_AUTH_HMAC_MD5 */
-#ifdef CONFIG_IPSEC_AUTH_HMAC_SHA1
-				SHA1_CTX sha1;
-#endif /* CONFIG_IPSEC_AUTH_HMAC_SHA1 */
-			} tctx;
-			__u8 hash[AH_AMAX];
-#endif /* defined(CONFIG_IPSEC_AUTH_HMAC_MD5) || defined(CONFIG_IPSEC_AUTH_HMAC_SHA1) */
 			int headroom = 0, tailroom = 0, ilen = 0, len = 0;
 			unsigned char *dat;
 			
 			iphlen = iph->ihl << 2;
 			pyldsz = ntohs(iph->tot_len) - iphlen;
-			sa_len = satoa(tdbp->tdb_said, 0, sa, SATOA_BUF);
+			sa_len = satoa(tdbp->tdb_said, 0, locals->sa, SATOA_BUF);
 			KLIPS_PRINT(debug_tunnel & DB_TN_OXFS,
 				    "klips_debug:ipsec_tunnel_start_xmit: "
 				    "calling output for <%s%s%s>, SA:%s\n", 
 				    IPS_XFORM_NAME(tdbp),
-				    sa_len ? sa : " (error)");
+				    sa_len ? locals->sa : " (error)");
 			
 			switch(tdbp->tdb_said.proto) {
 #ifdef CONFIG_IPSEC_AH
@@ -1799,38 +1810,38 @@ ipsec_tunnel_start_xmit(struct sk_buff *
 #ifdef CONFIG_IPSEC_AUTH_HMAC_MD5
 				case AH_MD5:
 					dmp("espp", (char*)espp, len - iphlen - authlen);
-					tctx.md5 = ((struct md5_ctx*)(tdbp->tdb_key_a))->ictx;
-					dmp("ictx", (char*)&tctx.md5, sizeof(tctx.md5));
-					MD5Update(&tctx.md5, (caddr_t)espp, len - iphlen - authlen);
-					dmp("ictx+dat", (char*)&tctx.md5, sizeof(tctx.md5));
-					MD5Final(hash, &tctx.md5);
-					dmp("ictx hash", (char*)&hash, sizeof(hash));
-					tctx.md5 = ((struct md5_ctx*)(tdbp->tdb_key_a))->octx;
-					dmp("octx", (char*)&tctx.md5, sizeof(tctx.md5));
-					MD5Update(&tctx.md5, hash, AHMD596_ALEN);
-					dmp("octx+hash", (char*)&tctx.md5, sizeof(tctx.md5));
-					MD5Final(hash, &tctx.md5);
-					dmp("octx hash", (char*)&hash, sizeof(hash));
-					memcpy(&(dat[len - authlen]), hash, authlen);
+					locals->tctx.md5 = ((struct md5_ctx*)(tdbp->tdb_key_a))->ictx;
+					dmp("ictx", (char*)&locals->tctx.md5, sizeof(locals->tctx.md5));
+					MD5Update(&locals->tctx.md5, (caddr_t)espp, len - iphlen - authlen);
+					dmp("ictx+dat", (char*)&locals->tctx.md5, sizeof(locals->tctx.md5));
+					MD5Final(locals->hash, &locals->tctx.md5);
+					dmp("ictx hash", (char*)&locals->hash, sizeof(locals->hash));
+					locals->tctx.md5 = ((struct md5_ctx*)(tdbp->tdb_key_a))->octx;
+					dmp("octx", (char*)&locals->tctx.md5, sizeof(locals->tctx.md5));
+					MD5Update(&locals->tctx.md5, locals->hash, AHMD596_ALEN);
+					dmp("octx+hash", (char*)&locals->tctx.md5, sizeof(locals->tctx.md5));
+					MD5Final(locals->hash, &locals->tctx.md5);
+					dmp("octx hash", (char*)&locals->hash, sizeof(locals->hash));
+					memcpy(&(dat[len - authlen]), locals->hash, authlen);
 
 					/* paranoid */
-					memset((caddr_t)&tctx.md5, 0, sizeof(tctx.md5));
-					memset((caddr_t)hash, 0, sizeof(*hash));
+					memset((caddr_t)&locals->tctx.md5, 0, sizeof(locals->tctx.md5));
+					memset((caddr_t)locals->hash, 0, sizeof(*locals->hash));
 					break;
 #endif /* CONFIG_IPSEC_AUTH_HMAC_MD5 */
 #ifdef CONFIG_IPSEC_AUTH_HMAC_SHA1
 				case AH_SHA:
-					tctx.sha1 = ((struct sha1_ctx*)(tdbp->tdb_key_a))->ictx;
-					SHA1Update(&tctx.sha1, (caddr_t)espp, len - iphlen - authlen);
-					SHA1Final(hash, &tctx.sha1);
-					tctx.sha1 = ((struct sha1_ctx*)(tdbp->tdb_key_a))->octx;
-					SHA1Update(&tctx.sha1, hash, AHSHA196_ALEN);
-					SHA1Final(hash, &tctx.sha1);
-					memcpy(&(dat[len - authlen]), hash, authlen);
+					locals->tctx.sha1 = ((struct sha1_ctx*)(tdbp->tdb_key_a))->ictx;
+					SHA1Update(&locals->tctx.sha1, (caddr_t)espp, len - iphlen - authlen);
+					SHA1Final(locals->hash, &locals->tctx.sha1);
+					locals->tctx.sha1 = ((struct sha1_ctx*)(tdbp->tdb_key_a))->octx;
+					SHA1Update(&locals->tctx.sha1, locals->hash, AHSHA196_ALEN);
+					SHA1Final(locals->hash, &locals->tctx.sha1);
+					memcpy(&(dat[len - authlen]), locals->hash, authlen);
 					
 					/* paranoid */
-					memset((caddr_t)&tctx.sha1, 0, sizeof(tctx.sha1));
-					memset((caddr_t)hash, 0, sizeof(*hash));
+					memset((caddr_t)&locals->tctx.sha1, 0, sizeof(locals->tctx.sha1));
+					memset((caddr_t)locals->hash, 0, sizeof(*locals->hash));
 					break;
 #endif /* CONFIG_IPSEC_AUTH_HMAC_SHA1 */
 				case AH_NONE:
@@ -1856,59 +1867,59 @@ ipsec_tunnel_start_xmit(struct sk_buff *
 				iph->protocol = IPPROTO_AH;
 				dmp("ahp", (char*)ahp, sizeof(*ahp));
 				
-				ipo = *iph;
-				ipo.tos = 0;
-				ipo.frag_off = 0;
-				ipo.ttl = 0;
-				ipo.check = 0;
-				dmp("ipo", (char*)&ipo, sizeof(ipo));
+				locals->ipo = *iph;
+				locals->ipo.tos = 0;
+				locals->ipo.frag_off = 0;
+				locals->ipo.ttl = 0;
+				locals->ipo.check = 0;
+				dmp("ipo", (char*)&locals->ipo, sizeof(locals->ipo));
 				
 				switch(tdbp->tdb_authalg) {
 #ifdef CONFIG_IPSEC_AUTH_HMAC_MD5
 				case AH_MD5:
-					tctx.md5 = ((struct md5_ctx*)(tdbp->tdb_key_a))->ictx;
-					dmp("ictx", (char*)&tctx.md5, sizeof(tctx.md5));
-					MD5Update(&tctx.md5, (unsigned char *)&ipo, sizeof (struct iphdr));
-					dmp("ictx+ipo", (char*)&tctx.md5, sizeof(tctx.md5));
-					MD5Update(&tctx.md5, (unsigned char *)ahp, headroom - sizeof(ahp->ah_data));
-					dmp("ictx+ahp", (char*)&tctx.md5, sizeof(tctx.md5));
-					MD5Update(&tctx.md5, (unsigned char *)zeroes, AHHMAC_HASHLEN);
-					dmp("ictx+zeroes", (char*)&tctx.md5, sizeof(tctx.md5));
-					MD5Update(&tctx.md5,  dat + iphlen + headroom, len - iphlen - headroom);
-					dmp("ictx+dat", (char*)&tctx.md5, sizeof(tctx.md5));
-					MD5Final(hash, &tctx.md5);
-					dmp("ictx hash", (char*)&hash, sizeof(hash));
-					tctx.md5 = ((struct md5_ctx*)(tdbp->tdb_key_a))->octx;
-					dmp("octx", (char*)&tctx.md5, sizeof(tctx.md5));
-					MD5Update(&tctx.md5, hash, AHMD596_ALEN);
-					dmp("octx+hash", (char*)&tctx.md5, sizeof(tctx.md5));
-					MD5Final(hash, &tctx.md5);
-					dmp("octx hash", (char*)&hash, sizeof(hash));
+					locals->tctx.md5 = ((struct md5_ctx*)(tdbp->tdb_key_a))->ictx;
+					dmp("ictx", (char*)&locals->tctx.md5, sizeof(locals->tctx.md5));
+					MD5Update(&locals->tctx.md5, (unsigned char *)&locals->ipo, sizeof (struct iphdr));
+					dmp("ictx+ipo", (char*)&locals->tctx.md5, sizeof(locals->tctx.md5));
+					MD5Update(&locals->tctx.md5, (unsigned char *)ahp, headroom - sizeof(ahp->ah_data));
+					dmp("ictx+ahp", (char*)&locals->tctx.md5, sizeof(locals->tctx.md5));
+					MD5Update(&locals->tctx.md5, (unsigned char *)zeroes, AHHMAC_HASHLEN);
+					dmp("ictx+zeroes", (char*)&locals->tctx.md5, sizeof(locals->tctx.md5));
+					MD5Update(&locals->tctx.md5,  dat + iphlen + headroom, len - iphlen - headroom);
+					dmp("ictx+dat", (char*)&locals->tctx.md5, sizeof(locals->tctx.md5));
+					MD5Final(locals->hash, &locals->tctx.md5);
+					dmp("ictx hash", (char*)&locals->hash, sizeof(locals->hash));
+					locals->tctx.md5 = ((struct md5_ctx*)(tdbp->tdb_key_a))->octx;
+					dmp("octx", (char*)&locals->tctx.md5, sizeof(locals->tctx.md5));
+					MD5Update(&locals->tctx.md5, locals->hash, AHMD596_ALEN);
+					dmp("octx+hash", (char*)&locals->tctx.md5, sizeof(locals->tctx.md5));
+					MD5Final(locals->hash, &locals->tctx.md5);
+					dmp("octx hash", (char*)&locals->hash, sizeof(locals->hash));
 					
-					memcpy(ahp->ah_data, hash, AHHMAC_HASHLEN);
+					memcpy(ahp->ah_data, locals->hash, AHHMAC_HASHLEN);
 					
 					/* paranoid */
-					memset((caddr_t)&tctx.md5, 0, sizeof(tctx.md5));
-					memset((caddr_t)hash, 0, sizeof(hash));
+					memset((caddr_t)&locals->tctx.md5, 0, sizeof(locals->tctx.md5));
+					memset((caddr_t)locals->hash, 0, sizeof(locals->hash));
 					break;
 #endif /* CONFIG_IPSEC_AUTH_HMAC_MD5 */
 #ifdef CONFIG_IPSEC_AUTH_HMAC_SHA1
 				case AH_SHA:
-					tctx.sha1 = ((struct sha1_ctx*)(tdbp->tdb_key_a))->ictx;
-					SHA1Update(&tctx.sha1, (unsigned char *)&ipo, sizeof (struct iphdr));
-					SHA1Update(&tctx.sha1, (unsigned char *)ahp, headroom - sizeof(ahp->ah_data));
-					SHA1Update(&tctx.sha1, (unsigned char *)zeroes, AHHMAC_HASHLEN);
-					SHA1Update(&tctx.sha1,  dat + iphlen + headroom, len - iphlen - headroom);
-					SHA1Final(hash, &tctx.sha1);
-					tctx.sha1 = ((struct sha1_ctx*)(tdbp->tdb_key_a))->octx;
-					SHA1Update(&tctx.sha1, hash, AHSHA196_ALEN);
-					SHA1Final(hash, &tctx.sha1);
+					locals->tctx.sha1 = ((struct sha1_ctx*)(tdbp->tdb_key_a))->ictx;
+					SHA1Update(&locals->tctx.sha1, (unsigned char *)&locals->ipo, sizeof (struct iphdr));
+					SHA1Update(&locals->tctx.sha1, (unsigned char *)ahp, headroom - sizeof(ahp->ah_data));
+					SHA1Update(&locals->tctx.sha1, (unsigned char *)zeroes, AHHMAC_HASHLEN);
+					SHA1Update(&locals->tctx.sha1,  dat + iphlen + headroom, len - iphlen - headroom);
+					SHA1Final(locals->hash, &locals->tctx.sha1);
+					locals->tctx.sha1 = ((struct sha1_ctx*)(tdbp->tdb_key_a))->octx;
+					SHA1Update(&locals->tctx.sha1, locals->hash, AHSHA196_ALEN);
+					SHA1Final(locals->hash, &locals->tctx.sha1);
 					
-					memcpy(ahp->ah_data, hash, AHHMAC_HASHLEN);
+					memcpy(ahp->ah_data, locals->hash, AHHMAC_HASHLEN);
 					
 					/* paranoid */
-					memset((caddr_t)&tctx.sha1, 0, sizeof(tctx.sha1));
-					memset((caddr_t)hash, 0, sizeof(hash));
+					memset((caddr_t)&locals->tctx.sha1, 0, sizeof(locals->tctx.sha1));
+					memset((caddr_t)locals->hash, 0, sizeof(locals->hash));
 					break;
 #endif /* CONFIG_IPSEC_AUTH_HMAC_SHA1 */
 				default:
@@ -2030,7 +2041,7 @@ ipsec_tunnel_start_xmit(struct sk_buff *
 				    "klips_debug:ipsec_tunnel_start_xmit: "
 				    "after <%s%s%s>, SA:%s:\n",
 				    IPS_XFORM_NAME(tdbp),
-				    sa_len ? sa : " (error)");
+				    sa_len ? locals->sa : " (error)");
 			KLIPS_IP_PRINT(debug_tunnel & DB_TN_XMIT, iph);
  			
 			tdbp->ips_life.ipl_bytes.ipl_count += len;
@@ -2054,13 +2065,13 @@ ipsec_tunnel_start_xmit(struct sk_buff *
 
 		spin_unlock(&tdb_lock);
 
-		matcher.sen_ip_src.s_addr = iph->saddr;
-		matcher.sen_ip_dst.s_addr = iph->daddr;
-		matcher.sen_proto = iph->protocol;
-		extract_ports(iph, &matcher);
+		locals->matcher.sen_ip_src.s_addr = iph->saddr;
+		locals->matcher.sen_ip_dst.s_addr = iph->daddr;
+		locals->matcher.sen_proto = iph->protocol;
+		extract_ports(iph, &locals->matcher);
 		
 		spin_lock(&eroute_lock);
-		er = ipsec_findroute(&matcher);
+		er = ipsec_findroute(&locals->matcher);
 		if(er) {
 			outgoing_said = er->er_said;
 			eroute_pid = er->er_pid;
@@ -2243,12 +2254,13 @@ ipsec_tunnel_start_xmit(struct sk_buff *
 	if(oskb) {
 		dev_kfree_skb(oskb, FREE_WRITE);
 	}
-	if (tdb.tdb_ident_s.data) {
-		kfree(tdb.tdb_ident_s.data);
+	if (locals && locals->tdb.tdb_ident_s.data) {
+		kfree(locals->tdb.tdb_ident_s.data);
 	}
-	if (tdb.tdb_ident_d.data) {
-		kfree(tdb.tdb_ident_d.data);
+	if (locals && locals->tdb.tdb_ident_d.data) {
+		kfree(locals->tdb.tdb_ident_d.data);
 	}
+	kfree(locals);
 	return 0;
 }
 
----------- следущая часть -----------
Было удалено вложение не в текстовом формате...
Имя     : отсутствует
Тип     : application/pgp-signature
Размер  : 189 байтов
Описание: отсутствует
Url     : http://lists.altlinux.org/pipermail/devel-kernel/attachments/20051020/13e2ebd5/attachment-0001.bin


Подробная информация о списке рассылки devel-kernel