summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSamuel Lidén Borell <samuel@slbdata.se>2010-01-02 02:39:12 +0100
committerSamuel Lidén Borell <samuel@slbdata.se>2010-01-02 22:30:16 +0100
commitc1d1c1c94eb5cbfc1fa150c350926c396e0ad218 (patch)
treeeb25ad27d0f953d85d90b32a05e69ca7b187bf73
parent37ca45a80227449a1ec4303c14d8cca227f39e1f (diff)
downloadfribid-c1d1c1c94eb5cbfc1fa150c350926c396e0ad218.tar.gz
fribid-c1d1c1c94eb5cbfc1fa150c350926c396e0ad218.tar.bz2
fribid-c1d1c1c94eb5cbfc1fa150c350926c396e0ad218.zip
Handle memory allocation errors
Also fixes a couple of very unlikely integer overflows.
-rw-r--r--CHANGELOG2
-rw-r--r--common/pipe.c9
-rw-r--r--plugin/npobject.c50
-rw-r--r--plugin/plugin.c11
4 files changed, 52 insertions, 20 deletions
diff --git a/CHANGELOG b/CHANGELOG
index 4719bf9..ee56f57 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -4,7 +4,7 @@
no longer needed.
* Fixed an error that occurred on sites that were sending null bytes in
the challenge parameter.
- * Fixed the cause of the harmless but annoying "pipe error" messages.
+ * Better error handling.
* Renamed the plugin filename to libfribidplugin.so to prevent
installation conflicts with Nexus Personal.
* Fixed two compile errors on 64-bit platforms.
diff --git a/common/pipe.c b/common/pipe.c
index 38e399e..481b0c1 100644
--- a/common/pipe.c
+++ b/common/pipe.c
@@ -1,6 +1,6 @@
/*
- Copyright (c) 2009 Samuel Lidén Borell <samuel@slbdata.se>
+ Copyright (c) 2009-2010 Samuel Lidén Borell <samuel@slbdata.se>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
@@ -54,7 +54,10 @@ static gboolean stopWaiting(GIOChannel *source,
void pipe_waitData(FILE *file) {
bool hasData = false;
GIOChannel *channel = g_io_channel_unix_new(fileno(file));
- assert(channel != NULL);
+ if (!channel) {
+ fprintf(stderr, BINNAME ": failed to create I/O channel\n");
+ return;
+ }
g_io_channel_set_encoding(channel, NULL, NULL);
g_io_add_watch(channel, G_IO_IN | G_IO_HUP | G_IO_ERR,
stopWaiting, &hasData);
@@ -94,7 +97,7 @@ void pipe_readData(FILE *in, char **data, int *length) {
*data = malloc(*length);
if ((*data == NULL) || (fread(*data, *length, 1, in) != 1)) {
pipeError();
- *data = realloc(*data, 0);
+ free(*data);
*length = 0;
}
}
diff --git a/plugin/npobject.c b/plugin/npobject.c
index 2de8eab..4322013 100644
--- a/plugin/npobject.c
+++ b/plugin/npobject.c
@@ -1,6 +1,6 @@
/*
- Copyright (c) 2009 Samuel Lidén Borell <samuel@slbdata.se>
+ Copyright (c) 2009-2010 Samuel Lidén Borell <samuel@slbdata.se>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
@@ -27,6 +27,7 @@
#include <string.h>
#include <stdlib.h>
#include <assert.h>
+#include <stdint.h>
#include <sys/types.h>
#include <sys/socket.h>
@@ -38,13 +39,14 @@
#include "npobject.h"
-static char *strndup(const char *source, int maxLength) {
- int i;
+static char *strndup(const char *source, size_t maxLength) {
+ size_t i;
for (i = 0;; i++) {
if ((i >= maxLength) || (source[i] == '\0')) break;
}
char *ret = malloc(i+1);
+ if (!ret) return NULL;
memcpy(ret, source, i);
ret[i] = '\0';
return ret;
@@ -52,15 +54,18 @@ static char *strndup(const char *source, int maxLength) {
// Re-allocates a string with NPN_MemAlloc instead of malloc
static char *npstr(char *source) {
- int size = strlen(source)+1;
- char *dest = NPN_MemAlloc(size);
- memcpy(dest, source, size);
+ size_t size = strlen(source)+1;
+ char *dest = NULL;
+ if (size <= INT32_MAX && (dest = NPN_MemAlloc(size)) != NULL) {
+ memcpy(dest, source, size);
+ }
free(source);
return dest;
}
static bool getProperty(NPP instance, NPObject *obj, const char *name, NPVariant *result) {
NPIdentifier ident = NPN_GetStringIdentifier(name);
+ if (!ident) return NULL;
return NPN_GetProperty(instance, obj, ident, result);
}
@@ -68,6 +73,7 @@ static char *getWindowProperty(NPP instance, const char *const identifiers[]) {
NPObject *obj;
NPN_GetValue(instance, NPNVWindowNPObject, &obj);
+ if (!obj) return NULL;
const char *const *identifier = &identifiers[0];
while (1) {
@@ -120,6 +126,7 @@ static char *getDocumentIP(NPP instance) {
// since the browser might have loaded a maliciuous page while
// the plugin authenticates with the real IP.
char *hostname = getDocumentHostname(instance);
+ if (!hostname) return NULL;
struct addrinfo *firstAddrInfo;
int ret = getaddrinfo(hostname, NULL, NULL, &firstAddrInfo);
@@ -167,11 +174,11 @@ static void objDeallocate(NPObject *npobj) {
free(this);
}
-static bool copyIdentifierName(NPIdentifier ident, char *name, int maxLength) {
+static bool copyIdentifierName(NPIdentifier ident, char *name, size_t maxLength) {
char *heapStr = NPN_UTF8FromIdentifier(ident);
if (!heapStr) return false;
- int len = strlen(heapStr);
- if (len+1 >= maxLength) return false;
+ size_t len = strlen(heapStr);
+ if (len >= maxLength-1) return false;
memcpy(name, heapStr, len+1);
NPN_MemFree(heapStr);
return true;
@@ -206,7 +213,10 @@ static bool objInvoke(NPObject *npobj, NPIdentifier ident,
switch (this->plugin->type) {
case PT_Version:
if (!strcmp(name, "GetVersion") && (argCount == 0)) {
- char *s = npstr(version_getVersion(this->plugin));
+ char *version = version_getVersion(this->plugin);
+ if (!version) return false;
+ char *s = npstr(version);
+ if (!s) return false;
STRINGZ_TO_NPVARIANT(s, *result);
return true;
}
@@ -217,7 +227,7 @@ static bool objInvoke(NPObject *npobj, NPIdentifier ident,
NPVARIANT_IS_STRING(args[0])) {
// Get parameter
char *param = strndup(NPVARIANT_TO_STRING(args[0]).utf8characters, NPVARIANT_TO_STRING(args[0]).utf8length);
-
+ if (!param) return false;
char *value = sign_getParam(this->plugin, param);
free(param);
@@ -225,6 +235,7 @@ static bool objInvoke(NPObject *npobj, NPIdentifier ident,
// The macro below evaluates it's first parameter twice
// and npstr frees it's input...
value = npstr(value);
+ if (!value) return false;
STRINGZ_TO_NPVARIANT(value, *result);
} else NULL_TO_NPVARIANT(*result);
@@ -239,17 +250,21 @@ static bool objInvoke(NPObject *npobj, NPIdentifier ident,
char *param = strndup(NPVARIANT_TO_STRING(args[0]).utf8characters, NPVARIANT_TO_STRING(args[0]).utf8length);
char *value = strndup(NPVARIANT_TO_STRING(args[1]).utf8characters, NPVARIANT_TO_STRING(args[1]).utf8length);
+ bool ok = (param && value);
- sign_setParam(this->plugin, param, value);
+ if (ok) {
+ sign_setParam(this->plugin, param, value);
+ VOID_TO_NPVARIANT(*result);
+ }
free(param);
free(value);
- VOID_TO_NPVARIANT(*result);
- return true;
+ return ok;
} else if (!strcmp(name, "PerformAction") && (argCount == 1) &&
NPVARIANT_IS_STRING(args[0])) {
// Perform action
char *action = strndup(NPVARIANT_TO_STRING(args[0]).utf8characters, NPVARIANT_TO_STRING(args[0]).utf8length);
+ if (!action) return false;
int ret = sign_performAction(this->plugin, action);
@@ -316,6 +331,7 @@ static NPClass baseClass = {
/* Object construction */
static NPObject *npobject_new(NPP instance, PluginType pluginType) {
PluginObject *obj = (PluginObject*)NPN_CreateObject(instance, &baseClass);
+ if (!obj) return NULL;
assert(obj->base._class != NULL);
char *url = getDocumentURL(instance);
@@ -330,6 +346,12 @@ static NPObject *npobject_new(NPP instance, PluginType pluginType) {
free(ip);
free(hostname);
free(url);
+
+ if (!obj->plugin) {
+ NPN_ReleaseObject((NPObject*)obj);
+ return NULL;
+ }
+
return (NPObject*)obj;
}
diff --git a/plugin/plugin.c b/plugin/plugin.c
index 00a69c8..83f125e 100644
--- a/plugin/plugin.c
+++ b/plugin/plugin.c
@@ -1,6 +1,6 @@
/*
- Copyright (c) 2009 Samuel Lidén Borell <samuel@slbdata.se>
+ Copyright (c) 2009-2010 Samuel Lidén Borell <samuel@slbdata.se>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
@@ -34,11 +34,18 @@ Plugin *plugin_new(PluginType pluginType, const char *url,
const char *hostname, const char *ip,
int windowId) {
Plugin *plugin = calloc(1, sizeof(Plugin));
+ if (!plugin) return NULL;
plugin->type = pluginType;
plugin->url = strdup(url);
plugin->hostname = strdup(hostname);
plugin->ip = strdup(ip);
plugin->windowId = windowId;
+
+ if (!plugin->url || !plugin->hostname || !plugin->ip) {
+ plugin_free(plugin);
+ return NULL;
+ }
+
return plugin;
}
@@ -101,7 +108,7 @@ bool sign_setParam(Plugin *plugin, const char *name, const char *value) {
free(*valuePtr);
*valuePtr = strdup(value);
- return true;
+ return (*valuePtr != NULL);
}
static bool hasSignParams(const Plugin *plugin) {