Fixed memory leaks in namesys and path.

yamux
Jose Marcial Vieira Bisneto 2016-12-08 06:48:38 -03:00
parent e69f10a68f
commit 84f24797f4
7 changed files with 70 additions and 38 deletions

View File

@ -4,6 +4,7 @@
#ifdef IPFS_PATH_C #ifdef IPFS_PATH_C
char *ErrPath[] = { char *ErrPath[] = {
NULL, NULL,
"ErrAllocFailed",
// ErrBadPath is returned when a given path is incorrectly formatted // ErrBadPath is returned when a given path is incorrectly formatted
"invalid 'ipfs ref' path", "invalid 'ipfs ref' path",
// Paths after a protocol must contain at least one component // Paths after a protocol must contain at least one component
@ -17,7 +18,8 @@
#endif // IPFS_PATH_C #endif // IPFS_PATH_C
enum { enum {
ErrBadPath = 1, ErrAllocFailed = 1,
ErrBadPath,
ErrNoComponents, ErrNoComponents,
ErrCidDecode, ErrCidDecode,
ErrNoLink, ErrNoLink,

View File

@ -51,7 +51,7 @@ type lookupRes struct {
int ipfs_dns_resolver_resolve_once (char **path, char *name) int ipfs_dns_resolver_resolve_once (char **path, char *name)
{ {
char **segments, *domain, *dnslink, buf[500], dlprefix[] = "_dnslink."; char **segments, *domain, *dnslink, buf[500], dlprefix[] = "_dnslink.";
int p1[2], p2[2], r, c=2; int p1[2], p2[2], r, l, c=2;
struct pollfd event[2], *e; struct pollfd event[2], *e;
segments = ipfs_path_split_n(name, "/", 2); segments = ipfs_path_split_n(name, "/", 2);
@ -84,12 +84,14 @@ int ipfs_dns_resolver_resolve_once (char **path, char *name)
case 0: // child case 0: // child
close(p2[STDIN_FILENO]); // we don't need to read at child process. close(p2[STDIN_FILENO]); // we don't need to read at child process.
dnslink = malloc(strlen(domain) + sizeof(dlprefix)); l = strlen(domain) + sizeof(dlprefix);
dnslink = malloc(l);
if (!dnslink) { if (!dnslink) {
return ErrAllocFailed; return ErrAllocFailed;
} }
strcpy (dnslink, dlprefix); dnslink[--l] = '\0';
strcat (dnslink, domain); strncpy (dnslink, dlprefix, l);
strncat (dnslink, domain, l - strlen(dnslink));
return ipfs_dns_work_domain (p2[STDOUT_FILENO], r, dnslink); return ipfs_dns_work_domain (p2[STDOUT_FILENO], r, dnslink);
} }
@ -114,7 +116,8 @@ int ipfs_dns_resolver_resolve_once (char **path, char *name)
buf[r] = '\0'; buf[r] = '\0';
*path = malloc(r+1); *path = malloc(r+1);
if (*path) { if (*path) {
strcpy(*path, buf); *path[r] = '\0';
strncpy(*path, buf, r);
} }
} else if (r <= 0) { } else if (r <= 0) {
return ErrPoll; return ErrPoll;
@ -187,7 +190,7 @@ int ipfs_dns_parse_entry (char **path, char *txt)
if (!*path) { if (!*path) {
return ErrAllocFailed; return ErrAllocFailed;
} }
strcpy(*path, buf); memcpy(*path, buf, strlen(buf) + 1);
return 0; return 0;
} }
return ipfs_dns_try_parse_dns_link(path, txt); return ipfs_dns_try_parse_dns_link(path, txt);
@ -205,7 +208,7 @@ int ipfs_dns_try_parse_dns_link(char **path, char *txt)
if (! *parts) { if (! *parts) {
return ErrAllocFailed; return ErrAllocFailed;
} }
strcpy(*parts, buf); memcpy(*parts, buf, strlen(buf) + 1);
return 0; return 0;
} }
return err; return err;

View File

@ -90,10 +90,14 @@ int ipfs_isdomain_is_tld (char *s)
// It first checks the TLD, and then uses a regular expression. // It first checks the TLD, and then uses a regular expression.
int ipfs_isdomain_is_domain (char *s) int ipfs_isdomain_is_domain (char *s)
{ {
char str[strlen(s)]; int err;
char *tld; char *str, *tld;
strcpy(str, s); str = malloc(strlen(s) + 1);
if (!str) {
return ErrAllocFailed;
}
memcpy(str, s, strlen(s) + 1);
s = str; // work with local copy. s = str; // work with local copy.
if (ipfs_isdomain_has_suffix (s, ".")) { if (ipfs_isdomain_has_suffix (s, ".")) {
@ -112,5 +116,7 @@ int ipfs_isdomain_is_domain (char *s)
return 0; return 0;
} }
return ipfs_isdomain_match_string(s); err = ipfs_isdomain_match_string(s);
free (s);
return err;
} }

View File

@ -55,7 +55,7 @@ int ipfs_namesys_resolve_n(char **path, char *name, int depth)
ipfs_path_parse(p, name); ipfs_path_parse(p, name);
*path = malloc(strlen(p) + 1); *path = malloc(strlen(p) + 1);
if (*p) { if (*p) {
strcpy(*path, p); memcpy(*path, p, strlen(p) + 1);
} else { } else {
err = ErrAllocFailed; err = ErrAllocFailed;
} }
@ -63,18 +63,22 @@ int ipfs_namesys_resolve_n(char **path, char *name, int depth)
} }
if (*name == '/') { if (*name == '/') {
int err; int err, l;
char *str = malloc(sizeof(ipfs_prefix) + strlen(name)); char *str;
l = sizeof(ipfs_prefix) + strlen(name);
str = malloc(l);
if (!str) { if (!str) {
return ErrAllocFailed; return ErrAllocFailed;
} }
strcpy(str, ipfs_prefix); str[--l] = '\0';
strcat(str, name+1); // ignore inital / from name, because ipfs_prefix already has it. strncpy(str, ipfs_prefix, l);
strncat(str, name+1, l - strlen (str)); // ignore inital / from name, because ipfs_prefix already has it.
err = ipfs_path_parse(p, str); // save return value. err = ipfs_path_parse(p, str); // save return value.
free (str); // so we can free allocated memory before return. free (str); // so we can free allocated memory before return.
*path = malloc(strlen(p) + 1); *path = malloc(strlen(p) + 1);
if (*p) { if (*p) {
strcpy(*path, p); memcpy(*path, p, strlen(p) + 1);
} else { } else {
err = ErrAllocFailed; err = ErrAllocFailed;
} }
@ -97,12 +101,14 @@ int ipfs_namesys_resolve_once (char **path, char *name)
} }
if (memcmp (name, ipns_prefix, strlen(ipns_prefix)) == 0) { // prefix missing. if (memcmp (name, ipns_prefix, strlen(ipns_prefix)) == 0) { // prefix missing.
ptr = malloc(strlen(name) + sizeof(ipns_prefix)); i = strlen(name) + sizeof(ipns_prefix);
ptr = malloc(i);
if (!ptr) { // allocation fail. if (!ptr) { // allocation fail.
return ErrAllocFailed; return ErrAllocFailed;
} }
strcpy(ptr, ipns_prefix); ptr[--i] = '\0';
strcat(ptr, name); strncpy(ptr, ipns_prefix, i);
strncat(ptr, name, i - strlen(ptr));
segs = ipfs_path_split_segments(ptr); segs = ipfs_path_split_segments(ptr);
free (ptr); free (ptr);
} else { } else {

View File

@ -176,7 +176,7 @@ int ipfs_proquint_resolve_once (char **p, char *name)
if (!err) { if (!err) {
*p = malloc (strlen(buf) + 1); *p = malloc (strlen(buf) + 1);
if (p) { if (p) {
strcpy(*p, buf); memcpy(*p, buf, strlen(buf) + 1);
} }
} }
} }

View File

@ -9,11 +9,14 @@ char* ipfs_path_from_cid (struct Cid *c)
{ {
const char prefix[] = "/ipfs/"; const char prefix[] = "/ipfs/";
char *rpath, *cidstr = CidString(c); char *rpath, *cidstr = CidString(c);
int l;
rpath = malloc(sizeof(prefix) + strlen(cidstr)); l = sizeof(prefix) + strlen(cidstr);
rpath = malloc(l);
if (!rpath) return NULL; if (!rpath) return NULL;
strcpy(rpath, prefix); rpath[--l] = '\0';
strcat(rpath, cidstr); strncpy(rpath, prefix, l);
strncat(rpath, cidstr, l - strlen(rpath));
return rpath; return rpath;
} }
@ -48,7 +51,7 @@ char** ipfs_path_split_n (char *p, char *delim, int n)
return NULL; return NULL;
} }
strcpy(rbuf, p); // keep original memcpy(rbuf, p, strlen(p) + 1); // keep original
for (c = rbuf, i = 0 ; i < n && c ; i++) { for (c = rbuf, i = 0 ; i < n && c ; i++) {
r[i] = c; r[i] = c;
c = strstr(c, delim); c = strstr(c, delim);
@ -206,10 +209,11 @@ char *ipfs_path_from_segments(char *prefix, char **seg)
ret = malloc(retlen + 1); // allocate final string size + null terminator. ret = malloc(retlen + 1); // allocate final string size + null terminator.
if (!ret) return NULL; if (!ret) return NULL;
strcpy(ret, prefix); ret[retlen] = '\0';
strncpy(ret, prefix, retlen);
for (i = 0 ; seg[i] ; i++) { for (i = 0 ; seg[i] ; i++) {
strcat(ret, "/"); strncat(ret, "/", retlen - strlen(ret));
strcat(ret, seg[i]); strncat(ret, seg[i], retlen - strlen(ret));
} }
return ret; return ret;
} }
@ -232,7 +236,7 @@ int ipfs_path_parse_from_cid (char *dst, char *txt)
if (!r) { if (!r) {
return ErrCidDecode; return ErrCidDecode;
} }
strcpy (dst, r); memcpy (dst, r, strlen(r) + 1);
free (r); free (r);
return 0; return 0;
} }
@ -252,7 +256,7 @@ int ipfs_path_parse (char *dst, char *txt)
} }
err = ipfs_path_parse_from_cid (dst+plen, txt); err = ipfs_path_parse_from_cid (dst+plen, txt);
if (err == 0) { // only change dst if ipfs_path_parse_from_cid returned success. if (err == 0) { // only change dst if ipfs_path_parse_from_cid returned success.
// Use memcpy instead of strcpy to avoid overwriting // Use memcpy instead of strncpy to avoid overwriting
// result of ipfs_path_parse_from_cid with a null terminator. // result of ipfs_path_parse_from_cid with a null terminator.
memcpy (dst, prefix, plen); memcpy (dst, prefix, plen);
} }
@ -264,11 +268,21 @@ int ipfs_path_parse (char *dst, char *txt)
if (i < 3) return ErrBadPath; if (i < 3) return ErrBadPath;
if (strcmp (txt, prefix) == 0) { if (strcmp (txt, prefix) == 0) {
char buf[strlen(txt+5)]; char *buf;
strcpy (buf, txt+6); // copy to temp buffer. i = strlen(txt+6);
buf = malloc(i + 1);
if (!buf) {
return ErrAllocFailed;
}
buf[i] = '\0';
strncpy (buf, txt+6, i); // copy to temp buffer.
c = strchr(buf, '/'); c = strchr(buf, '/');
if (c) *c = '\0'; if (c) {
return ipfs_path_parse_from_cid(dst, buf); *c = '\0';
}
err = ipfs_path_parse_from_cid(dst, buf);
free (buf);
return err;
} else if (strcmp (txt, "/ipns/") != 0) { } else if (strcmp (txt, "/ipns/") != 0) {
return ErrBadPath; return ErrBadPath;
} }

View File

@ -87,7 +87,7 @@ int ipfs_path_resolve_path_components(Node ***nd, Context ctx, Resolver *s, char
// would retrieve "baz" in ("bar" in ("foo" in nd.Links).Links).Links // would retrieve "baz" in ("bar" in ("foo" in nd.Links).Links).Links
int ipfs_path_resolve_links(Node ***result, Context ctx, Node *ndd, char **names) int ipfs_path_resolve_links(Node ***result, Context ctx, Node *ndd, char **names)
{ {
int err, idx = 0; int err, idx = 0, l;
NodeLink *lnk; NodeLink *lnk;
Node *nd; Node *nd;
@ -115,9 +115,10 @@ int ipfs_path_resolve_links(Node ***result, Context ctx, Node *ndd, char **names
if (ErrPath[ErrNoLink]) { if (ErrPath[ErrNoLink]) {
free(ErrPath[ErrNoLink]); free(ErrPath[ErrNoLink]);
} }
ErrPath[ErrNoLink] = malloc(strlen(msg) + 1); l = strlen(msg) + 1;
ErrPath[ErrNoLink] = malloc(l);
if (ErrPath[ErrNoLink]) { if (ErrPath[ErrNoLink]) {
strcpy(ErrPath[ErrNoLink], msg); memcpy(ErrPath[ErrNoLink], msg, l);
} }
free (*result); free (*result);
return ErrNoLink; return ErrNoLink;