Gitweb:
http://git.fedorahosted.org/git/?p=cluster.git;a=commitdiff;h=d55fe105fd6...
Commit: d55fe105fd6c3dc5ceafb60e08880a5653440732
Parent: 07766f691733c71344a703eff31636fac3ca1d30
Author: Jan Pokorný <jpokorny(a)redhat.com>
AuthorDate: Wed Apr 17 15:21:54 2013 +0200
Committer: Jan Pokorný <jpokorny(a)redhat.com>
CommitterDate: Wed Apr 17 15:21:54 2013 +0200
ccs_tool: fix several segfaults
(1) input file = output file and subcommand gets some options
(2) update gets no input file
+ several overflows in case the output file was specified explicitly
and contained, as a global path, around 255 bytes or more
Signed-off-by: Jan Pokorný <jpokorny(a)redhat.com>
---
ccs/ccs_tool/ccs_tool.c | 2 +-
ccs/ccs_tool/update.c | 28 ++++++++++++++++++++--------
2 files changed, 21 insertions(+), 9 deletions(-)
diff --git a/ccs/ccs_tool/ccs_tool.c b/ccs/ccs_tool/ccs_tool.c
index 5fcd667..bde7d30 100644
--- a/ccs/ccs_tool/ccs_tool.c
+++ b/ccs/ccs_tool/ccs_tool.c
@@ -12,7 +12,7 @@ static void print_usage(FILE *stream);
int main(int argc, char *argv[])
{
- optind = 1;
+ /* implicitly initialized by the library: optind = 1; */
if (argc < 2 || !strcmp(argv[optind], "-h")) {
print_usage(stdout);
diff --git a/ccs/ccs_tool/update.c b/ccs/ccs_tool/update.c
index 3af779b..c6f4362 100644
--- a/ccs/ccs_tool/update.c
+++ b/ccs/ccs_tool/update.c
@@ -15,6 +15,7 @@
#include <unistd.h>
#include <fcntl.h>
#include <ctype.h>
+#include <getopt.h>
#include <libxml/parser.h>
#include <libxml/tree.h>
#include <libxml/xpath.h>
@@ -117,6 +118,7 @@ static int parse_args(int argc, char **argv, char **loc)
{
int c, error, ret;
+ optind = 1; /* reset the global for getopt from previous use */
while ((c = getopt(argc, argv, "P:")) != EOF) {
switch(c) {
case 'P':
@@ -191,19 +193,28 @@ int update2(int argc, char **argv)
struct timeval tv;
- if (parse_args(argc, argv, &location))
+ if (parse_args(argc, argv, &location) || !location) {
+ if (!location)
+ fprintf(stderr, "Source configuration file not specified.\n");
return -1;
+ }
if (location[0] != '/') {
- memset(true_location, 0, 256);
- if (!getcwd(true_location, 256)) {
+ if (!getcwd(true_location, sizeof(true_location))) {
fprintf(stderr, "Unable to get the current working directory.\n");
return -errno;
}
- true_location[strlen(true_location)] = '/';
- strncpy(true_location+strlen(true_location), location, 256-strlen(true_location));
+ i = (int) strlen(true_location);
+ if (i >= sizeof(true_location) - 2
+ || strlen(location) + i > sizeof(true_location) - 2) {
+ /* tl[254]='/', tl[255]=first char of location ... nul-termination? */
+ fprintf(stderr, "Overly nested location a/o a long relative path.\n");
+ return -1;
+ }
+ true_location[i] = '/';
+ strcpy(true_location + (i+1), location);
} else {
- strncpy(true_location, location, 256);
+ true_location[0] = '\0';
}
desc = ccs_connect();
@@ -232,10 +243,11 @@ int update2(int argc, char **argv)
v1 = atoi(v1_str);
free(v1_str);
- doc = xmlParseFile(true_location);
+ doc = xmlParseFile(true_location[0] ? true_location : location);
if (!doc) {
- fprintf(stderr, "Unable to parse %s\n", true_location);
+ fprintf(stderr, "Unable to parse %s\n",
+ true_location[0] ? true_location : location);
return -EINVAL;
}