aboutsummaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorJulian Elischer <julian@FreeBSD.org>1998-06-08 20:33:29 +0000
committerJulian Elischer <julian@FreeBSD.org>1998-06-08 20:33:29 +0000
commit01f0fef31bf69b981c193713a2a9f6fbe085e888 (patch)
treea09a95439763b190451a55b284572645bfd9bb6a /sys
parent645b7985eafc181953363418b6e494abcc2d60bf (diff)
downloadsrc-01f0fef31bf69b981c193713a2a9f6fbe085e888.tar.gz
src-01f0fef31bf69b981c193713a2a9f6fbe085e888.zip
Don't let ifunit() modify the string passed as an argument.
it may be in the text segment and write protected.
Notes
Notes: svn path=/head/; revision=36775
Diffstat (limited to 'sys')
-rw-r--r--sys/net/if.c42
1 files changed, 26 insertions, 16 deletions
diff --git a/sys/net/if.c b/sys/net/if.c
index 5030b3f5e038..0cdbfc1a3cc2 100644
--- a/sys/net/if.c
+++ b/sys/net/if.c
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)if.c 8.3 (Berkeley) 1/4/94
- * $Id: if.c,v 1.58 1998/04/06 11:43:10 phk Exp $
+ * $Id: if.c,v 1.59 1998/06/07 17:12:02 dfr Exp $
*/
#include "opt_compat.h"
@@ -482,37 +482,47 @@ struct ifnet *
ifunit(name)
register char *name;
{
- register char *cp;
+ char namebuf[IFNAMSIZ + 1];
+ register char *cp, *cp2;
+ char *end;
register struct ifnet *ifp;
int unit;
unsigned len;
- char *ep, c;
+ register char c = '\0';
- for (cp = name; cp < name + IFNAMSIZ && *cp; cp++)
- if (*cp >= '0' && *cp <= '9')
+ /*
+ * Look for a non numeric part
+ */
+ end = name + IFNAMSIZ;
+ cp2 = namebuf;
+ cp = name;
+ while ((cp < end) && (c = *cp)) {
+ if (c >= '0' && c <= '9')
break;
- if (*cp == '\0' || cp == name + IFNAMSIZ)
+ *cp2++ = c;
+ cp++;
+ }
+ if ((cp == end) || (c == '\0') || (cp == name))
return ((struct ifnet *)0);
+ *cp2 = '\0';
/*
- * Save first char of unit, and pointer to it,
- * so we can put a null there to avoid matching
- * initial substrings of interface names.
+ * check we have a legal number (limit to 7 digits?)
*/
len = cp - name + 1;
- c = *cp;
- ep = cp;
- for (unit = 0; *cp >= '0' && *cp <= '9'; )
- unit = unit * 10 + *cp++ - '0';
+ for (unit = 0;
+ ((c = *cp) >= '0') && (c <= '9') && (unit < 1000000); cp++ )
+ unit = (unit * 10) + (c - '0');
if (*cp != '\0')
return 0; /* no trailing garbage allowed */
- *ep = 0;
+ /*
+ * Now search all the interfaces for this name/number
+ */
for (ifp = ifnet.tqh_first; ifp; ifp = ifp->if_link.tqe_next) {
- if (bcmp(ifp->if_name, name, len))
+ if (bcmp(ifp->if_name, namebuf, len))
continue;
if (unit == ifp->if_unit)
break;
}
- *ep = c;
return (ifp);
}