From 18fdf802d31354c62a27cc5a63b196780a0d486e Mon Sep 17 00:00:00 2001
From: Yousong Zhou <yszhou4tech@gmail.com>
Date: Wed, 29 Apr 2015 16:30:17 +0800
Subject: [PATCH 206/210] xl2tpd: start_pppd: place opts after "plugin
 pppol2tp.so".

so that plugin options like pppol2tp_debug_mark can be recognized by
pppd.  While doing this also add bound check to prevent potential buffer
overflow problem.
---
 xl2tpd.c |   22 +++++++++++-----------
 1 file changed, 11 insertions(+), 11 deletions(-)

diff --git a/xl2tpd.c b/xl2tpd.c
index 6c945fc..017adfd 100644
--- a/xl2tpd.c
+++ b/xl2tpd.c
@@ -382,7 +382,6 @@ int start_pppd (struct call *c, struct ppp_opts *opts)
     /* char a, b; */
     char tty[512];
     char *stropt[80];
-    struct ppp_opts *p;
 #ifdef USE_KERNEL
     struct sockaddr_pppol2tp sax;
     int flags;
@@ -396,16 +395,7 @@ int start_pppd (struct call *c, struct ppp_opts *opts)
     struct call *sc;
     struct tunnel *st;
 
-    p = opts;
     stropt[0] = strdup (PPPD);
-    while (p)
-    {
-        stropt[pos] = (char *) malloc (strlen (p->option) + 1);
-        strncpy (stropt[pos], p->option, strlen (p->option) + 1);
-        pos++;
-        p = p->next;
-    }
-    stropt[pos] = NULL;
     if (c->pppd > 0)
     {
         l2tp_log(LOG_WARNING, "%s: PPP already started on call!\n", __FUNCTION__);
@@ -467,7 +457,6 @@ int start_pppd (struct call *c, struct ppp_opts *opts)
         snprintf (stropt[pos], 10, "%d", c->ourcid);
             pos++;
        }
-        stropt[pos] = NULL;
     }
     else
 #endif
@@ -497,6 +486,17 @@ int start_pppd (struct call *c, struct ppp_opts *opts)
             return -EINVAL;
         }
         stropt[pos++] = strdup(tty);
+    }
+
+    {
+        struct ppp_opts *p = opts;
+        int maxn_opts = sizeof(stropt) / sizeof(stropt[0]) - 1;
+        while (p && pos < maxn_opts)
+        {
+            stropt[pos] = strdup (p->option);
+            pos++;
+            p = p->next;
+        }
         stropt[pos] = NULL;
     }
 
-- 
1.7.10.4

