Skip to content
Snippets Groups Projects
Commit 4ce85afc authored by Daniel Golle's avatar Daniel Golle
Browse files

gluon-status-page-api: support batadv-in-VLAN on ibss interface

introduce function to recurse down to the lowest layer-2 interface
corresponding to a given interface.
also re-introduce some of the previously removed input validation plus
some more to protect against glob and path based exploits.
parent e012e67b
No related branches found
No related tags found
No related merge requests found
...@@ -4,7 +4,12 @@ ...@@ -4,7 +4,12 @@
#include <json-c/json.h> #include <json-c/json.h>
#include <iwinfo.h> #include <iwinfo.h>
#include <net/if.h> #include <net/if.h>
#include <glob.h>
#include <alloca.h>
#define NETIF_PREFIX "/sys/class/net/"
#define VIRTIF_PREFIX "/sys/devices/virtual/net/"
#define LOWERGLOB_SUFFIX "/lower_*"
static struct json_object *get_stations(const struct iwinfo_ops *iw, const char *ifname) { static struct json_object *get_stations(const struct iwinfo_ops *iw, const char *ifname) {
int len; int len;
...@@ -40,12 +45,68 @@ static void badrequest() { ...@@ -40,12 +45,68 @@ static void badrequest() {
exit(1); exit(1);
} }
// recurse down to the lowest layer-2 interface
static int interface_get_lowest(const char *ifname, char *hwifname);
static int interface_get_lowest(const char *ifname, char *hwifname) {
glob_t globbuf;
char *fnamebuf = alloca(1 + strlen(VIRTIF_PREFIX) + IF_NAMESIZE +
strlen(LOWERGLOB_SUFFIX));
char *lowentry = NULL;
sprintf(fnamebuf, "%s%s%s", VIRTIF_PREFIX, ifname, LOWERGLOB_SUFFIX);
glob(fnamebuf, GLOB_NOSORT | GLOB_NOESCAPE, NULL, &globbuf);
if (globbuf.gl_pathc == 1) {
lowentry = alloca(1 + strlen(globbuf.gl_pathv[0]));
strncpy(lowentry, globbuf.gl_pathv[0], 1 + strlen(globbuf.gl_pathv[0]));
}
globfree(&globbuf);
if (!lowentry) {
char *path = alloca(1 + strlen(NETIF_PREFIX) + strlen(ifname));
sprintf(path, "%s%s", NETIF_PREFIX, ifname);
if(access(path, F_OK) != 0)
return false;
strncpy(hwifname, ifname, IF_NAMESIZE - 1);
return true;
} else {
char buf[PATH_MAX];
ssize_t len;
if ((len = readlink(lowentry, buf, sizeof(buf)-1)) != -1)
buf[len] = '\0';
else
return false;
if (strncmp(buf, "../", 3) == 0) {
return interface_get_lowest(strrchr(buf, '/') + 1, hwifname);
} else {
return false;
}
}
}
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
if (argc != 2) if (argc != 2)
badrequest(); badrequest();
const char *ifname = argv[1]; const char *ifname = argv[1];
const struct iwinfo_ops *iw = iwinfo_backend(ifname); char hwifname[IF_NAMESIZE] = "";
if (strlen(ifname) >= IF_NAMESIZE)
badrequest();
if (strcspn(ifname, "/\\[]{}*?") != strlen(ifname))
badrequest();
if (!interface_get_lowest(ifname, hwifname))
badrequest();
const struct iwinfo_ops *iw = iwinfo_backend(hwifname);
if (iw == NULL) if (iw == NULL)
badrequest(); badrequest();
...@@ -54,7 +115,7 @@ int main(int argc, char *argv[]) { ...@@ -54,7 +115,7 @@ int main(int argc, char *argv[]) {
while (true) { while (true) {
struct json_object *obj; struct json_object *obj;
obj = get_stations(iw, ifname); obj = get_stations(iw, hwifname);
printf("data: %s\n\n", json_object_to_json_string_ext(obj, JSON_C_TO_STRING_PLAIN)); printf("data: %s\n\n", json_object_to_json_string_ext(obj, JSON_C_TO_STRING_PLAIN));
fflush(stdout); fflush(stdout);
json_object_put(obj); json_object_put(obj);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment