[SCM] The rsync repository. - branch master updated

Rsync CVS commit messages rsync-cvs at lists.samba.org
Mon Jul 13 06:34:30 UTC 2020


The branch, master has been updated
       via  f47e5a77 Mention file & line on OOM and overflow errors.
       via  91fff802 Check for overflow the right way.
      from  3c8ac20d Fix a typo.

https://git.samba.org/?p=rsync.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit f47e5a7732f9b5da71080fdc229acde4ec6da3c1
Author: Wayne Davison <wayne at opencoder.net>
Date:   Sun Jul 12 22:46:21 2020 -0700

    Mention file & line on OOM and overflow errors.
    
    Also simplify output of src file paths in errors & warnings when
    built in a alternate build dir.

commit 91fff802b9513cf0ed616d3aea170d561f899fae
Author: Wayne Davison <wayne at opencoder.net>
Date:   Sun Jul 12 21:51:51 2020 -0700

    Check for overflow the right way.

-----------------------------------------------------------------------

Summary of changes:
 cleanup.c        |  2 +-
 flist.c          | 12 ++++--------
 lib/pool_alloc.3 |  2 +-
 lib/pool_alloc.c |  6 +++---
 lib/pool_alloc.h |  2 +-
 log.c            |  4 ++--
 options.c        |  4 ++--
 rsync.h          |  7 +++++++
 util.c           | 25 ++++++++++++-------------
 util2.c          | 34 +++++++++++++++++++++++++---------
 xattrs.c         |  7 +++----
 11 files changed, 61 insertions(+), 44 deletions(-)


Changeset truncated at 500 lines:

diff --git a/cleanup.c b/cleanup.c
index f9a5d76b..40d26baa 100644
--- a/cleanup.c
+++ b/cleanup.c
@@ -137,7 +137,7 @@ NORETURN void _exit_cleanup(int code, const char *file, int line)
 		if (DEBUG_GTE(EXIT, 2)) {
 			rprintf(FINFO,
 				"[%s] _exit_cleanup(code=%d, file=%s, line=%d): entered\n",
-				who_am_i(), code, file, line);
+				who_am_i(), code, src_file(file), line);
 		}
 
 #include "case_N.h"
diff --git a/flist.c b/flist.c
index 39f942b0..6c2543cd 100644
--- a/flist.c
+++ b/flist.c
@@ -133,6 +133,7 @@ static char empty_sum[MAX_DIGEST_LEN];
 static int flist_count_offset; /* for --delete --progress */
 static int show_filelist_progress;
 
+static struct file_list *flist_new(int flags, const char *msg);
 static void flist_sort_and_clean(struct file_list *flist, int strip_root);
 static void output_flist(struct file_list *flist);
 
@@ -2797,25 +2798,20 @@ void clear_file(struct file_struct *file)
 }
 
 /* Allocate a new file list. */
-struct file_list *flist_new(int flags, char *msg)
+static struct file_list *flist_new(int flags, const char *msg)
 {
 	struct file_list *flist;
 
 	flist = new0(struct file_list);
 
 	if (flags & FLIST_TEMP) {
-		if (!(flist->file_pool = pool_create(SMALL_EXTENT, 0,
-						     out_of_memory,
-						     POOL_INTERN)))
+		if (!(flist->file_pool = pool_create(SMALL_EXTENT, 0, _out_of_memory, POOL_INTERN)))
 			out_of_memory(msg);
 	} else {
 		/* This is a doubly linked list with prev looping back to
 		 * the end of the list, but the last next pointer is NULL. */
 		if (!first_flist) {
-			flist->file_pool = pool_create(NORMAL_EXTENT, 0,
-						       out_of_memory,
-						       POOL_INTERN);
-			if (!flist->file_pool)
+			if (!(flist->file_pool = pool_create(NORMAL_EXTENT, 0, _out_of_memory, POOL_INTERN)))
 				out_of_memory(msg);
 
 			flist->ndx_start = flist->flist_num = inc_recurse ? 1 : 0;
diff --git a/lib/pool_alloc.3 b/lib/pool_alloc.3
index 6c22b924..128c1f7f 100644
--- a/lib/pool_alloc.3
+++ b/lib/pool_alloc.3
@@ -33,7 +33,7 @@ pool_alloc, pool_free, pool_free_old, pool_talloc, pool_tfree, pool_create, pool
 .SH SYNOPSIS
 .B #include "pool_alloc.h"
 
-\fBstruct alloc_pool *pool_create(size_t \fIsize\fB, size_t \fIquantum\fB, void (*\fIbomb\fB)(char *), int \fIflags\fB);
+\fBstruct alloc_pool *pool_create(size_t \fIsize\fB, size_t \fIquantum\fB, void (*\fIbomb\fB)(char*,char*,int), int \fIflags\fB);
 
 \fBvoid pool_destroy(struct alloc_pool *\fIpool\fB);
 
diff --git a/lib/pool_alloc.c b/lib/pool_alloc.c
index a70a3f1a..f6c6faf6 100644
--- a/lib/pool_alloc.c
+++ b/lib/pool_alloc.c
@@ -45,13 +45,13 @@ struct align_test {
 #define PTR_ADD(b,o)	( (void*) ((char*)(b) + (o)) )
 
 alloc_pool_t
-pool_create(size_t size, size_t quantum, void (*bomb)(const char *), int flags)
+pool_create(size_t size, size_t quantum, void (*bomb)(const char*, const char*, int), int flags)
 {
 	struct alloc_pool *pool;
 
 	if ((MINALIGN & (MINALIGN - 1)) != 0) {
 		if (bomb)
-			(*bomb)("Compiler error: MINALIGN is not a power of 2\n");
+			(*bomb)("Compiler error: MINALIGN is not a power of 2", __FILE__, __LINE__);
 		return NULL;
 	}
 
@@ -169,7 +169,7 @@ pool_alloc(alloc_pool_t p, size_t len, const char *bomb_msg)
 
   bomb_out:
 	if (pool->bomb)
-		(*pool->bomb)(bomb_msg);
+		(*pool->bomb)(bomb_msg, __FILE__, __LINE__);
 	return NULL;
 }
 
diff --git a/lib/pool_alloc.h b/lib/pool_alloc.h
index c7368a77..28059212 100644
--- a/lib/pool_alloc.h
+++ b/lib/pool_alloc.h
@@ -7,7 +7,7 @@
 
 typedef void *alloc_pool_t;
 
-alloc_pool_t pool_create(size_t size, size_t quantum, void (*bomb)(const char *), int flags);
+alloc_pool_t pool_create(size_t size, size_t quantum, void (*bomb)(const char*, const char*, int), int flags);
 void pool_destroy(alloc_pool_t pool);
 void *pool_alloc(alloc_pool_t pool, size_t size, const char *bomb_msg);
 void pool_free(alloc_pool_t pool, size_t size, void *addr);
diff --git a/log.c b/log.c
index 633bcdbc..85eae3d5 100644
--- a/log.c
+++ b/log.c
@@ -890,10 +890,10 @@ void log_exit(int code, const char *file, int line)
 		/* VANISHED is not an error, only a warning */
 		if (code == RERR_VANISHED) {
 			rprintf(FWARNING, "rsync warning: %s (code %d) at %s(%d) [%s=%s]\n",
-				name, code, file, line, who_am_i(), RSYNC_VERSION);
+				name, code, src_file(file), line, who_am_i(), RSYNC_VERSION);
 		} else {
 			rprintf(FERROR, "rsync error: %s (code %d) at %s(%d) [%s=%s]\n",
-				name, code, file, line, who_am_i(), RSYNC_VERSION);
+				name, code, src_file(file), line, who_am_i(), RSYNC_VERSION);
 		}
 	}
 }
diff --git a/options.c b/options.c
index 9ed16405..0ecabe8d 100644
--- a/options.c
+++ b/options.c
@@ -119,7 +119,6 @@ size_t bwlimit_writemax = 0;
 int ignore_existing = 0;
 int ignore_non_existing = 0;
 int need_messages_from_generator = 0;
-time_t stop_at_utime = 0;
 int max_delete = INT_MIN;
 OFF_T max_size = -1;
 OFF_T min_size = -1;
@@ -130,6 +129,7 @@ int checksum_seed = 0;
 int inplace = 0;
 int delay_updates = 0;
 int32 block_size = 0;
+time_t stop_at_utime = 0;
 char *skip_compress = NULL;
 char *copy_as = NULL;
 item_list dparam_list = EMPTY_ITEM_LIST;
@@ -2051,7 +2051,7 @@ int parse_arguments(int *argc_p, const char ***argv_p)
 			long val;
 			arg = poptGetOptArg(pc);
 			stop_at_utime = time(NULL);
-			if ((val = atol(arg) * 60) <= 0 || val + (long)stop_at_utime < 0) {
+			if ((val = atol(arg) * 60) <= 0 || LONG_MAX - val < stop_at_utime || (long)(time_t)val != val) {
 				snprintf(err_buf, sizeof err_buf, "invalid --stop-after value: %s\n", arg);
 				return 0;
 			}
diff --git a/rsync.h b/rsync.h
index be4d8550..c8715747 100644
--- a/rsync.h
+++ b/rsync.h
@@ -711,6 +711,10 @@ struct ht_int64_node {
 #define NAME_MAX 255
 #endif
 
+#ifndef SIZE_MAX
+#define SIZE_MAX ((size_t)-1)
+#endif
+
 #ifndef INADDR_NONE
 #define INADDR_NONE 0xffffffff
 #endif
@@ -1321,6 +1325,9 @@ extern char *do_malloc;
 #undef strdup
 #define strdup(s) my_strdup(s, __FILE__, __LINE__)
 
+#define out_of_memory(msg) _out_of_memory(msg, __FILE__, __LINE__)
+#define overflow_exit(msg) _overflow_exit(msg, __FILE__, __LINE__)
+
 /* use magic gcc attributes to catch format errors */
  void rprintf(enum logcode , const char *, ...)
      __attribute__((format (printf, 2, 3)))
diff --git a/util.c b/util.c
index 3a50e44f..f5588324 100644
--- a/util.c
+++ b/util.c
@@ -1632,28 +1632,27 @@ void *expand_item_list(item_list *lp, size_t item_size, const char *desc, int in
 	/* First time through, 0 <= 0, so list is expanded. */
 	if (lp->malloced <= lp->count) {
 		void *new_ptr;
-		size_t new_size = lp->malloced;
+		size_t expand_size;
 		if (incr < 0)
-			new_size += -incr; /* increase slowly */
-		else if (new_size < (size_t)incr)
-			new_size = incr;
-		else if (new_size)
-			new_size *= 2;
+			expand_size = -incr; /* increase slowly */
+		else if (lp->malloced < (size_t)incr)
+			expand_size = incr - lp->malloced;
+		else if (lp->malloced)
+			expand_size = lp->malloced; /* double in size */
 		else
-			new_size = 1;
-		if (new_size <= lp->malloced)
+			expand_size = 1;
+		if (SIZE_MAX/item_size - expand_size < lp->malloced)
 			overflow_exit("expand_item_list");
-		new_ptr = realloc_buf(lp->items, new_size * item_size);
+		expand_size += lp->malloced;
+		new_ptr = realloc_buf(lp->items, expand_size * item_size);
 		if (DEBUG_GTE(FLIST, 3)) {
 			rprintf(FINFO, "[%s] expand %s to %s bytes, did%s move\n",
-				who_am_i(), desc, big_num(new_size * item_size),
+				who_am_i(), desc, big_num(expand_size * item_size),
 				new_ptr == lp->items ? " not" : "");
 		}
-		if (!new_ptr)
-			out_of_memory("expand_item_list");
 
 		lp->items = new_ptr;
-		lp->malloced = new_size;
+		lp->malloced = expand_size;
 	}
 	return (char*)lp->items + (lp->count++ * item_size);
 }
diff --git a/util2.c b/util2.c
index 6ea6981d..8879c987 100644
--- a/util2.c
+++ b/util2.c
@@ -76,7 +76,7 @@ void *my_alloc(void *ptr, size_t num, size_t size, const char *file, int line)
 		if (!file)
 			return NULL;
 		rprintf(FERROR, "[%s] exceeded --max-alloc=%s setting (file=%s, line=%d)\n",
-			who_am_i(), do_big_num(max_alloc, 0, NULL), file, line);
+			who_am_i(), do_big_num(max_alloc, 0, NULL), src_file(file), line);
 		exit_cleanup(RERR_MALLOC);
 	}
 	if (!ptr)
@@ -85,10 +85,8 @@ void *my_alloc(void *ptr, size_t num, size_t size, const char *file, int line)
 		ptr = malloc(num * size);
 	else
 		ptr = realloc(ptr, num * size);
-	if (!ptr && file) {
-		rprintf(FERROR, "[%s] out of memory (file=%s, line=%d)\n", who_am_i(), file, line);
-		exit_cleanup(RERR_MALLOC);
-	}
+	if (!ptr && file)
+		_out_of_memory("my_alloc caller", file, line);
 	return ptr;
 }
 
@@ -119,14 +117,32 @@ const char *sum_as_hex(int csum_type, const char *sum, int flist_csum)
 	return buf;
 }
 
-NORETURN void out_of_memory(const char *str)
+NORETURN void _out_of_memory(const char *msg, const char *file, int line)
 {
-	rprintf(FERROR, "ERROR: out of memory in %s [%s]\n", str, who_am_i());
+	rprintf(FERROR, "[%s] out of memory: %s (file=%s, line=%d)\n", who_am_i(), msg, src_file(file), line);
 	exit_cleanup(RERR_MALLOC);
 }
 
-NORETURN void overflow_exit(const char *str)
+NORETURN void _overflow_exit(const char *msg, const char *file, int line)
 {
-	rprintf(FERROR, "ERROR: buffer overflow in %s [%s]\n", str, who_am_i());
+	rprintf(FERROR, "[%s] buffer overflow: %s (file=%s, line=%d)\n", who_am_i(), msg, src_file(file), line);
 	exit_cleanup(RERR_MALLOC);
 }
+
+const char *src_file(const char *file)
+{
+	static const char *util2 = __FILE__;
+	static int prefix = -1;
+
+	if (prefix < 0) {
+		const char *cp;
+		for (cp = util2, prefix = 0; *cp; cp++) {
+			if (*cp == '/')
+				prefix = cp - util2 + 1;
+		}
+	}
+
+	if (prefix && strncmp(file, util2, prefix) == 0)
+		return file + prefix;
+	return file;
+}
diff --git a/xattrs.c b/xattrs.c
index b10c2567..bcb4bcac 100644
--- a/xattrs.c
+++ b/xattrs.c
@@ -199,7 +199,7 @@ static char *get_xattr_data(const char *fname, const char *name, size_t *len_ptr
 
 	if (!datum_len && !extra_len)
 		extra_len = 1; /* request non-zero amount of memory */
-	if (datum_len + extra_len < datum_len)
+	if (SIZE_MAX - datum_len < extra_len)
 		overflow_exit("get_xattr_data");
 	ptr = new_array(char, datum_len + extra_len);
 
@@ -748,7 +748,7 @@ int recv_xattr_request(struct file_struct *file, int f_in)
 		old_datum = rxa->datum;
 		rxa->datum_len = read_varint(f_in);
 
-		if (rxa->name_len + rxa->datum_len < rxa->name_len)
+		if (SIZE_MAX - rxa->name_len < rxa->datum_len)
 			overflow_exit("recv_xattr_request");
 		rxa->datum = new_array(char, rxa->datum_len + rxa->name_len);
 		name = rxa->datum + rxa->datum_len;
@@ -799,8 +799,7 @@ void receive_xattr(int f, struct file_struct *file)
 		size_t datum_len = read_varint(f);
 		size_t dget_len = datum_len > MAX_FULL_DATUM ? 1 + MAX_DIGEST_LEN : datum_len;
 		size_t extra_len = MIGHT_NEED_RPRE ? RPRE_LEN : 0;
-		if ((dget_len + extra_len < dget_len)
-		 || (dget_len + extra_len + name_len < dget_len + extra_len))
+		if (SIZE_MAX - dget_len < extra_len || SIZE_MAX - dget_len - extra_len < name_len)
 			overflow_exit("receive_xattr");
 		ptr = new_array(char, dget_len + extra_len + name_len);
 		name = ptr + dget_len + extra_len;


-- 
The rsync repository.



More information about the rsync-cvs mailing list