From 2464455fea66090ca799ac8327a3934a445d9eae Mon Sep 17 00:00:00 2001 From: Vreixo Formoso Date: Tue, 8 Jan 2008 20:05:01 +0100 Subject: [PATCH] Guard against bad link destinations. --- src/libisofs.h | 4 +++- src/node.c | 58 +++++++++++++++++++++++++++++++++++++++++++++----- src/node.h | 8 +++++++ src/tree.c | 6 ++++++ 4 files changed, 70 insertions(+), 6 deletions(-) diff --git a/src/libisofs.h b/src/libisofs.h index e7f43be..0152db0 100644 --- a/src/libisofs.h +++ b/src/libisofs.h @@ -819,8 +819,10 @@ const char *iso_symlink_get_dest(const IsoSymlink *link); * @param dest * New destination for the link. It must be a non-empty string, otherwise * this function doesn't modify previous destination. + * @return + * 1 on success, < 0 on error */ -void iso_symlink_set_dest(IsoSymlink *link, const char *dest); +int iso_symlink_set_dest(IsoSymlink *link, const char *dest); /** * Sets the order in which a node will be written on image. High weihted files diff --git a/src/node.c b/src/node.c index 52ddc31..56f2595 100644 --- a/src/node.c +++ b/src/node.c @@ -14,6 +14,7 @@ #include #include #include +#include /** * Increments the reference counting of the given node. @@ -541,15 +542,20 @@ const char *iso_symlink_get_dest(const IsoSymlink *link) /** * Set the destination of a link. */ -void iso_symlink_set_dest(IsoSymlink *link, const char *dest) +int iso_symlink_set_dest(IsoSymlink *link, const char *dest) { - // TODO guard against bad destinations, such as components bigger than 255 - if (dest == NULL || dest[0] == '\0') { + char *d; + if (!iso_node_is_valid_link_dest(dest)) { /* guard against null or empty dest */ - return; + return ISO_WRONG_ARG_VALUE; + } + d = strdup(dest); + if (d == NULL) { + return ISO_MEM_ERROR; } free(link->dest); - link->dest = strdup(dest); + link->dest = d; + return ISO_SUCCESS; } /** @@ -615,6 +621,48 @@ int iso_node_is_valid_name(const char *name) return 1; } +int iso_node_is_valid_link_dest(const char *dest) +{ + int ret; + char *ptr, *brk_info, *component; + + /* a dest can't be NULL */ + if (dest == NULL) { + return 0; + } + + /* guard against the empty string or big dest... */ + if (dest[0] == '\0' || strlen(dest) > PATH_MAX) { + return 0; + } + + /* check that all components are valid */ + if (!strcmp(dest, "/")) { + /* "/" is a valid component */ + return 1; + } + + ptr = strdup(dest); + if (ptr == NULL) { + return 0; + } + + ret = 1; + component = strtok_r(ptr, "/", &brk_info); + while (component) { + if (strcmp(component, ".") && strcmp(component, "..")) { + ret = iso_node_is_valid_name(component); + if (ret == 0) { + break; + } + } + component = strtok_r(NULL, "/", &brk_info); + } + free(ptr); + + return ret; +} + int iso_node_new_root(IsoDir **root) { IsoDir *dir; diff --git a/src/node.h b/src/node.h index f1787f3..d7cda2d 100644 --- a/src/node.h +++ b/src/node.h @@ -115,4 +115,12 @@ int iso_node_new_root(IsoDir **root); */ int iso_node_is_valid_name(const char *name); +/** + * Check if a given path is valid for the destination of a link. + * + * @return + * 1 if yes, 0 if not + */ +int iso_node_is_valid_link_dest(const char *dest); + #endif /*LIBISO_NODE_H_*/ diff --git a/src/tree.c b/src/tree.c index 1b92585..7d380b9 100644 --- a/src/tree.c +++ b/src/tree.c @@ -150,6 +150,12 @@ int iso_tree_add_new_symlink(IsoDir *parent, const char *name, if (!iso_node_is_valid_name(name)) { return ISO_WRONG_ARG_VALUE; } + + /* check if destination is valid */ + if (!iso_node_is_valid_link_dest(dest)) { + /* guard against null or empty dest */ + return ISO_WRONG_ARG_VALUE; + } /* find place where to insert */ pos = &(parent->children);