Date: Fri, 4 Aug 2000 03:08:45 -0700 (PDT) From: Kris Kennaway <kris@hub.freebsd.org> To: audit@freebsd.org Subject: ether_line() patch Message-ID: <Pine.BSF.4.21.0008040306140.96614-100000@hub.freebsd.org>
next in thread | raw e-mail | index | archive | help
This patch fixes a minor overflow possibility in ether_line() (not really a problem at all, it's basically academic) which uses sscanf and doesnt specify a string length. I've replaced ether_line() with the version from OpenBSD which doesn't use sscanf() at all. Reviews, please! Kris Index: ether_addr.c =================================================================== RCS file: /home/ncvs/src/lib/libc/net/ether_addr.c,v retrieving revision 1.11 diff -u -r1.11 ether_addr.c --- ether_addr.c 2000/07/18 22:44:09 1.11 +++ ether_addr.c 2000/08/04 10:04:35 @@ -39,14 +39,15 @@ */ -#include <stdio.h> -#include <paths.h> #include <sys/types.h> -#include <string.h> -#include <stdlib.h> +#include <net/ethernet.h> #include <sys/param.h> #include <sys/socket.h> -#include <net/ethernet.h> +#include <errno.h> +#include <paths.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> #ifdef YP #include <rpc/rpc.h> #include <rpcsvc/yp_prot.h> @@ -57,6 +58,8 @@ #define _PATH_ETHERS "/etc/ethers" #endif +static char *_ether_aton __P((const char *, struct ether_addr *)); + /* * Parse a string of text containing an ethernet address and hostname * and separate it into its component parts. @@ -66,28 +69,39 @@ struct ether_addr *e; char *hostname; { - int i, o[6]; + char *p; + size_t n; - i = sscanf(l, "%x:%x:%x:%x:%x:%x %s", &o[0], &o[1], &o[2], - &o[3], &o[4], &o[5], - hostname); - if (i != 7) - return (i); - - for (i=0; i<6; i++) - e->octet[i] = o[i]; - return (0); + /* Parse "xx:xx:xx:xx:xx:xx" */ + if ((p = _ether_aton(l, e)) == NULL || (*p != ' ' && *p != '\t')) + goto bad; + + /* Now get the hostname */ + while (isspace(*p)) + p++; + if (*p == '\0') + goto bad; + n = strcspn(p, " \t\n"); + if (n >= MAXHOSTNAMELEN) + goto bad; + (void)strncpy(hostname, p, n); + hostname[n] = '\0'; + return (0); + +bad: + errno = EINVAL; + return (-1); } /* * Convert an ASCII representation of an ethernet address to * binary form. */ -struct ether_addr *ether_aton(a) +static char *_ether_aton(a, e) const char *a; + struct ether_addr *e; { int i; - static struct ether_addr o; unsigned int o0, o1, o2, o3, o4, o5; i = sscanf(a, "%x:%x:%x:%x:%x:%x", &o0, &o1, &o2, &o3, &o4, &o5); @@ -95,14 +109,22 @@ if (i != 6) return (NULL); - o.octet[0]=o0; - o.octet[1]=o1; - o.octet[2]=o2; - o.octet[3]=o3; - o.octet[4]=o4; - o.octet[5]=o5; + e->octet[0]=o0; + e->octet[1]=o1; + e->octet[2]=o2; + e->octet[3]=o3; + e->octet[4]=o4; + e->octet[5]=o5; + + return ((char *)e); +} + +struct ether_addr *ether_aton(s) + const char *s; +{ + static struct ether_addr n; - return ((struct ether_addr *)&o); + return (_ether_aton(s, &n) ? &n : NULL); } /* @@ -156,7 +178,7 @@ strlen(ether_a), &result, &resultlen)) { continue; } - strncpy(buf, result, resultlen); + strncpy(buf, result, resultlen - 1); buf[resultlen] = '\0'; free(result); } -- In God we Trust -- all others must submit an X.509 certificate. -- Charles Forsythe <forsythe@alum.mit.edu> To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-audit" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?Pine.BSF.4.21.0008040306140.96614-100000>