Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/net gif(4): Infinite recursion calls prevention code wor...
details: https://anonhg.NetBSD.org/src/rev/4f57df594634
branches: trunk
changeset: 342059:4f57df594634
user: knakahara <knakahara%NetBSD.org@localhost>
date: Fri Dec 04 02:26:11 2015 +0000
description:
gif(4): Infinite recursion calls prevention code works again now.
The prevention code haven't worked since gif(4) was changed
to use softint(9). To work this prevention, git_output uses
m_tag(9) like FreeBSD and OpenBSD.
I tested with following code.
====================
# ifconfig gif0 create
# ifconfig gif0 tunnel 10.1.1.1 10.1.1.2
# ifconfig gif0 inet 192.168.100.1 192.168.100.100
# ifconfig gif1 create
# ifconfig gif1 tunnel 192.168.100.1 192.168.100.100
# ifconfig gif1 inet 192.168.101.1 192.168.101.101
# ifconfig gif2 create
# ifconfig gif2 tunnel 192.168.101.1 192.168.101.101
# ifconfig gif2 inet 192.168.102.1 192.168.102.102
# ping -w 1 -c 1 192.168.102.102
# dmesg | tail -n 1
gif0: recursively called too many times(2)
====================
diffstat:
sys/net/if_gif.c | 59 +++++++++++++++++++++++++++++++++++++++----------------
1 files changed, 42 insertions(+), 17 deletions(-)
diffs (105 lines):
diff -r 0d0fe08807ab -r 4f57df594634 sys/net/if_gif.c
--- a/sys/net/if_gif.c Fri Dec 04 01:47:48 2015 +0000
+++ b/sys/net/if_gif.c Fri Dec 04 02:26:11 2015 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: if_gif.c,v 1.94 2015/12/03 03:03:58 knakahara Exp $ */
+/* $NetBSD: if_gif.c,v 1.95 2015/12/04 02:26:11 knakahara Exp $ */
/* $KAME: if_gif.c,v 1.76 2001/08/20 02:01:02 kjc Exp $ */
/*
@@ -31,7 +31,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_gif.c,v 1.94 2015/12/03 03:03:58 knakahara Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_gif.c,v 1.95 2015/12/04 02:26:11 knakahara Exp $");
#ifdef _KERNEL_OPT
#include "opt_inet.h"
@@ -94,6 +94,7 @@
static int gif_clone_create(struct if_clone *, int);
static int gif_clone_destroy(struct ifnet *);
+static int gif_check_nesting(struct ifnet *, struct mbuf *);
static struct if_clone gif_cloner =
IF_CLONE_INITIALIZER("gif", gif_clone_create, gif_clone_destroy);
@@ -233,31 +234,56 @@
}
#endif
+/*
+ * gif may cause infinite recursion calls when misconfigured.
+ * We'll prevent this by introducing upper limit.
+ */
+static int
+gif_check_nesting(struct ifnet *ifp, struct mbuf *m)
+{
+ struct m_tag *mtag;
+ int *count;
+
+ mtag = m_tag_find(m, PACKET_TAG_TUNNEL_INFO, NULL);
+ if (mtag != NULL) {
+ count = (int *)(mtag + 1);
+ if (++(*count) > max_gif_nesting) {
+ log(LOG_NOTICE,
+ "%s: recursively called too many times(%d)\n",
+ if_name(ifp),
+ *count);
+ return EIO;
+ }
+ } else {
+ mtag = m_tag_get(PACKET_TAG_TUNNEL_INFO, sizeof(*count),
+ M_NOWAIT);
+ if (mtag != NULL) {
+ m_tag_prepend(m, mtag);
+ count = (int *)(mtag + 1);
+ *count = 0;
+ } else {
+ log(LOG_DEBUG,
+ "%s: m_tag_get() failed, recursion calls are not prevented.\n",
+ if_name(ifp));
+ }
+ }
+
+ return 0;
+}
+
int
gif_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst,
struct rtentry *rt)
{
struct gif_softc *sc = ifp->if_softc;
int error = 0;
- static int called = 0; /* XXX: MUTEX */
ALTQ_DECL(struct altq_pktattr pktattr;)
int s;
IFQ_CLASSIFY(&ifp->if_snd, m, dst->sa_family, &pktattr);
- /*
- * gif may cause infinite recursion calls when misconfigured.
- * We'll prevent this by introducing upper limit.
- * XXX: this mechanism may introduce another problem about
- * mutual exclusion of the variable CALLED, especially if we
- * use kernel thread.
- */
- if (++called > max_gif_nesting) {
- log(LOG_NOTICE,
- "gif_output: recursively called too many times(%d)\n",
- called);
- m_freem(m);
- error = EIO; /* is there better errno? */
+ if ((error = gif_check_nesting(ifp, m)) != 0) {
+ m_free(m);
goto end;
}
@@ -295,7 +321,6 @@
error = 0;
end:
- called = 0; /* reset recursion counter */
if (error)
ifp->if_oerrors++;
return error;
Home |
Main Index |
Thread Index |
Old Index