diff options
author | Alexander Motin <mav@FreeBSD.org> | 2008-01-31 08:51:48 +0000 |
---|---|---|
committer | Alexander Motin <mav@FreeBSD.org> | 2008-01-31 08:51:48 +0000 |
commit | 81a253a4ede94f5f284f5696da87a1394c126be5 (patch) | |
tree | e401ae1e6519d6fbdbbcd1a030ecceea296b79b8 /sys/netgraph/ng_base.c | |
parent | 2a57ca33c742c600a5837ba32f9325b79e669f45 (diff) | |
download | src-81a253a4ede94f5f284f5696da87a1394c126be5.tar.gz src-81a253a4ede94f5f284f5696da87a1394c126be5.zip |
Implement stack protection based on GET_STACK_USAGE() macro.
This fixes system panics possible with complicated netgraph setups
and allows to avoid unneded extra queueing for stack unwrapping.
Notes
Notes:
svn path=/head/; revision=175847
Diffstat (limited to 'sys/netgraph/ng_base.c')
-rw-r--r-- | sys/netgraph/ng_base.c | 30 |
1 files changed, 22 insertions, 8 deletions
diff --git a/sys/netgraph/ng_base.c b/sys/netgraph/ng_base.c index 47fde6078755..f61d2fd1c69c 100644 --- a/sys/netgraph/ng_base.c +++ b/sys/netgraph/ng_base.c @@ -60,6 +60,7 @@ #include <sys/sysctl.h> #include <sys/syslog.h> #include <sys/refcount.h> +#include <sys/proc.h> #include <net/netisr.h> @@ -2300,8 +2301,6 @@ ng_snd_item(item_p item, int flags) ERROUT(EINVAL); /* No address */ } - queue = (flags & NG_QUEUE) ? 1 : 0; - switch(item->el_flags & NGQF_TYPE) { case NGQF_DATA: /* @@ -2327,9 +2326,6 @@ ng_snd_item(item_p item, int flags) || (NG_NODE_NOT_VALID(NG_HOOK_NODE(hook)))) { ERROUT(ENOTCONN); } - if ((hook->hk_flags & HK_QUEUE)) { - queue = 1; - } break; case NGQF_MESG: /* @@ -2339,9 +2335,6 @@ ng_snd_item(item_p item, int flags) * References are held by the item on the node and * the hook if it is present. */ - if (hook && (hook->hk_flags & HK_QUEUE)) { - queue = 1; - } break; case NGQF_FN: case NGQF_FN2: @@ -2370,6 +2363,27 @@ ng_snd_item(item_p item, int flags) || (hook && (hook->hk_flags & HK_FORCE_WRITER))) rw = NGQRW_W; + /* + * If sender or receiver requests queued delivery or stack usage + * level is dangerous - enqueue message. + */ + queue = 0; + if ((flags & NG_QUEUE) || (hook && (hook->hk_flags & HK_QUEUE))) { + queue = 1; + } +#ifdef GET_STACK_USAGE + else { + size_t st, su; + GET_STACK_USAGE(st, su); + su = (su * 128) / st; + if ((su > 100) || + ((su > 64) && ((node->nd_flags & NGF_HI_STACK) || + (hook && (hook->hk_flags & HK_HI_STACK))))) { + queue = 1; + } + } +#endif + if (queue) { /* Put it on the queue for that node*/ #ifdef NETGRAPH_DEBUG |