From: Jo-Philipp Wich Date: Tue, 12 Aug 2014 11:14:11 +0000 (+0000) Subject: package: fix segfault of iwinfo.scanlist("radio0"). X-Git-Tag: reboot~6216 X-Git-Url: http://git.lede-project.org./?a=commitdiff_plain;h=eb02b887ff2e71b28c47205f2c4070e9139bc2a0;p=openwrt%2Fstaging%2Flynxis.git package: fix segfault of iwinfo.scanlist("radio0"). This is a bug revealed in r41830. First, the static variable `char nif[IFNAMSIZ]` of nl80211_phy2ifname() would be zeroed out if the argument is "wlan0" or the like. This will happen in the following call stack. nl80211_get_scanlist("radio0", buf, len); nl80211_phy2ifname("radio0") // return static var nif with content "wlan0" nl80211_get_scanlist(nif, buf, len); // tail call nl80211_get_mode(nif); nl80211_phy2ifname(nif); // zero out nif Later we try nl80211_ifadd("") which was supposed to create interface "tmp.", but that won't happen because nl80211_msg() will put an invalid ifidx 0 to the nlmsg. Then iwinfo_ifup() and iwinfo_ifdown() would fail and happily nl80211_get_scanlist() returned 0 and left *len undefined. Signed-off-by: Yousong Zhou SVN-Revision: 42151 --- diff --git a/package/network/utils/iwinfo/src/iwinfo_lua.c b/package/network/utils/iwinfo/src/iwinfo_lua.c index 9b7d6554db..cdb90d5b47 100644 --- a/package/network/utils/iwinfo/src/iwinfo_lua.c +++ b/package/network/utils/iwinfo/src/iwinfo_lua.c @@ -362,7 +362,7 @@ static int iwinfo_L_txpwrlist(lua_State *L, int (*func)(const char *, char *, in /* Wrapper for scan list */ static int iwinfo_L_scanlist(lua_State *L, int (*func)(const char *, char *, int *)) { - int i, x, len; + int i, x, len = 0; char rv[IWINFO_BUFSIZE]; char macstr[18]; const char *ifname = luaL_checkstring(L, 1); diff --git a/package/network/utils/iwinfo/src/iwinfo_nl80211.c b/package/network/utils/iwinfo/src/iwinfo_nl80211.c index 98200bfef7..33c62387e3 100644 --- a/package/network/utils/iwinfo/src/iwinfo_nl80211.c +++ b/package/network/utils/iwinfo/src/iwinfo_nl80211.c @@ -215,6 +215,9 @@ static struct nl80211_msg_conveyor * nl80211_msg(const char *ifname, int ifidx = -1, phyidx = -1; struct nl80211_msg_conveyor *cv; + if (ifname == NULL) + return NULL; + if (nl80211_init() < 0) return NULL; @@ -227,7 +230,8 @@ static struct nl80211_msg_conveyor * nl80211_msg(const char *ifname, else ifidx = if_nametoindex(ifname); - if ((ifidx < 0) && (phyidx < 0)) + /* Valid ifidx must be greater than 0 */ + if ((ifidx <= 0) && (phyidx < 0)) return NULL; cv = nl80211_new(nls->nl80211, cmd, flags); @@ -500,12 +504,15 @@ static char * nl80211_phy2ifname(const char *ifname) DIR *d; struct dirent *e; + /* Only accept phy name of the form phy%d or radio%d */ if (!ifname) return NULL; else if (!strncmp(ifname, "phy", 3)) phyidx = atoi(&ifname[3]); else if (!strncmp(ifname, "radio", 5)) phyidx = atoi(&ifname[5]); + else + return NULL; memset(nif, 0, sizeof(nif));