Signedness security patch from Sebastian Krahmer <krahmer@suse.de> --
authorMartin Pool <mbp@samba.org>
Wed, 23 Jan 2002 04:57:18 +0000 (04:57 +0000)
committerMartin Pool <mbp@samba.org>
Wed, 23 Jan 2002 04:57:18 +0000 (04:57 +0000)
in some cases we were not sufficiently careful about reading integers
from the network.

Also, make sure log messages are always nul-terminated.

NEWS
exclude.c
fileio.c
flist.c
io.c
log.c
receiver.c
rsync.h
util.c

diff --git a/NEWS b/NEWS
index 55ee031..0d6b9c6 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,7 +1,15 @@
 rsync 2.5.2 (???)
 
 rsync 2.5.2 (???)
 
+  SECURITY FIXES:
+
+    * Signedness security patch from Sebastian Krahmer
+      <krahmer@suse.de> -- in some cases we were not sufficiently
+      careful about reading integers from the network.
+
   BUG FIXES:
 
   BUG FIXES:
 
+    * Fix possible string mangling in log files.
+
     * Fix for setting local address of outgoing sockets.
 
     * Better handling of hardlinks and devices on platforms with
     * Fix for setting local address of outgoing sockets.
 
     * Better handling of hardlinks and devices on platforms with
index 53852f6..a9d32a3 100644 (file)
--- a/exclude.c
+++ b/exclude.c
@@ -299,7 +299,8 @@ void send_exclude_list(int f)
 void recv_exclude_list(int f)
 {
        char line[MAXPATHLEN];
 void recv_exclude_list(int f)
 {
        char line[MAXPATHLEN];
-       int l;
+       unsigned int l;
+
        while ((l=read_int(f))) {
                if (l >= MAXPATHLEN) overflow("recv_exclude_list");
                read_sbuf(f,line,l);
        while ((l=read_int(f))) {
                if (l >= MAXPATHLEN) overflow("recv_exclude_list");
                read_sbuf(f,line,l);
index c39d6b0..3ed2803 100644 (file)
--- a/fileio.c
+++ b/fileio.c
@@ -36,7 +36,7 @@ int sparse_end(int f)
 }
 
 
 }
 
 
-static int write_sparse(int f,char *buf,int len)
+static int write_sparse(int f,char *buf,size_t len)
 {
        int l1=0,l2=0;
        int ret;
 {
        int l1=0,l2=0;
        int ret;
@@ -69,7 +69,7 @@ static int write_sparse(int f,char *buf,int len)
 
 
 
 
 
 
-int write_file(int f,char *buf,int len)
+int write_file(int f,char *buf,size_t len)
 {
        int ret = 0;
 
 {
        int ret = 0;
 
diff --git a/flist.c b/flist.c
index 843cf9e..5d1a259 100644 (file)
--- a/flist.c
+++ b/flist.c
@@ -375,7 +375,7 @@ static void receive_file_entry(struct file_struct **fptr,
        static gid_t last_gid;
        static char lastname[MAXPATHLEN];
        char thisname[MAXPATHLEN];
        static gid_t last_gid;
        static char lastname[MAXPATHLEN];
        char thisname[MAXPATHLEN];
-       int l1=0,l2=0;
+       unsigned int l1=0,l2=0;
        char *p;
        struct file_struct *file;
 
        char *p;
        struct file_struct *file;
 
@@ -442,6 +442,10 @@ static void receive_file_entry(struct file_struct **fptr,
 
        if (preserve_links && S_ISLNK(file->mode)) {
                int l = read_int(f);
 
        if (preserve_links && S_ISLNK(file->mode)) {
                int l = read_int(f);
+               if (l < 0) {
+                       rprintf(FERROR,"overflow: l=%d\n", l);
+                       overflow("receive_file_entry");
+               }
                file->link = (char *)malloc(l+1);
                if (!file->link) out_of_memory("receive_file_entry 2");
                read_sbuf(f,file->link,l);
                file->link = (char *)malloc(l+1);
                if (!file->link) out_of_memory("receive_file_entry 2");
                read_sbuf(f,file->link,l);
diff --git a/io.c b/io.c
index e57d070..95fb73b 100644 (file)
--- a/io.c
+++ b/io.c
@@ -49,7 +49,7 @@ int kludge_around_eof = False;
 
 static int io_error_fd = -1;
 
 
 static int io_error_fd = -1;
 
-static void read_loop(int fd, char *buf, int len);
+static void read_loop(int fd, char *buf, size_t len);
 
 static void check_timeout(void)
 {
 
 static void check_timeout(void)
 {
@@ -163,7 +163,7 @@ static void die_from_readerr (int err)
  * give a better explanation.  We can tell whether the connection has
  * started by looking e.g. at whether the remote version is known yet.
  */
  * give a better explanation.  We can tell whether the connection has
  * started by looking e.g. at whether the remote version is known yet.
  */
-static int read_timeout (int fd, char *buf, int len)
+static int read_timeout (int fd, char *buf, size_t len)
 {
        int n, ret=0;
 
 {
        int n, ret=0;
 
@@ -236,7 +236,7 @@ static int read_timeout (int fd, char *buf, int len)
 
 /*! Continue trying to read len bytes - don't return until len has
   been read.   */
 
 /*! Continue trying to read len bytes - don't return until len has
   been read.   */
-static void read_loop (int fd, char *buf, int len)
+static void read_loop (int fd, char *buf, size_t len)
 {
        while (len) {
                int n = read_timeout(fd, buf, len);
 {
        while (len) {
                int n = read_timeout(fd, buf, len);
@@ -253,7 +253,7 @@ static void read_loop (int fd, char *buf, int len)
  * 
  * Never returns <= 0. 
  */
  * 
  * Never returns <= 0. 
  */
-static int read_unbuffered(int fd, char *buf, int len)
+static int read_unbuffered(int fd, char *buf, size_t len)
 {
        static int remaining;
        int tag, ret=0;
 {
        static int remaining;
        int tag, ret=0;
@@ -305,7 +305,7 @@ static int read_unbuffered(int fd, char *buf, int len)
 
 /* do a buffered read from fd. don't return until all N bytes
    have been read. If all N can't be read then exit with an error */
 
 /* do a buffered read from fd. don't return until all N bytes
    have been read. If all N can't be read then exit with an error */
-static void readfd (int fd, char *buffer, int N)
+static void readfd (int fd, char *buffer, size_t N)
 {
        int  ret;
        int total=0;  
 {
        int  ret;
        int total=0;  
@@ -356,12 +356,12 @@ int64 read_longint(int f)
        return ret;
 }
 
        return ret;
 }
 
-void read_buf(int f,char *buf,int len)
+void read_buf(int f,char *buf,size_t len)
 {
        readfd(f,buf,len);
 }
 
 {
        readfd(f,buf,len);
 }
 
-void read_sbuf(int f,char *buf,int len)
+void read_sbuf(int f,char *buf,size_t len)
 {
        read_buf (f,buf,len);
        buf[len] = 0;
 {
        read_buf (f,buf,len);
        buf[len] = 0;
@@ -375,7 +375,7 @@ unsigned char read_byte(int f)
 }
 
 /* write len bytes to fd */
 }
 
 /* write len bytes to fd */
-static void writefd_unbuffered(int fd,char *buf,int len)
+static void writefd_unbuffered(int fd,char *buf,size_t len)
 {
        int total = 0;
        fd_set w_fds, r_fds;
 {
        int total = 0;
        fd_set w_fds, r_fds;
@@ -483,7 +483,7 @@ void io_start_buffering(int fd)
 
 /* write an message to a multiplexed stream. If this fails then rsync
    exits */
 
 /* write an message to a multiplexed stream. If this fails then rsync
    exits */
-static void mplex_write(int fd, enum logcode code, char *buf, int len)
+static void mplex_write(int fd, enum logcode code, char *buf, size_t len)
 {
        char buffer[4096];
        int n = len;
 {
        char buffer[4096];
        int n = len;
@@ -533,7 +533,7 @@ void io_end_buffering(int fd)
        }
 }
 
        }
 }
 
-static void writefd(int fd,char *buf,int len)
+static void writefd(int fd,char *buf,size_t len)
 {
        stats.total_written += len;
 
 {
        stats.total_written += len;
 
@@ -587,7 +587,7 @@ void write_longint(int f, int64 x)
        writefd(f,b,8);
 }
 
        writefd(f,b,8);
 }
 
-void write_buf(int f,char *buf,int len)
+void write_buf(int f,char *buf,size_t len)
 {
        writefd(f,buf,len);
 }
 {
        writefd(f,buf,len);
 }
@@ -606,7 +606,7 @@ void write_byte(int f,unsigned char c)
 
 
 
 
 
 
-int read_line(int f, char *buf, int maxlen)
+int read_line(int f, char *buf, size_t maxlen)
 {
        while (maxlen) {
                buf[0] = 0;
 {
        while (maxlen) {
                buf[0] = 0;
@@ -664,7 +664,7 @@ void io_start_multiplex_in(int fd)
 }
 
 /* write an message to the multiplexed error stream */
 }
 
 /* write an message to the multiplexed error stream */
-int io_multiplex_write(enum logcode code, char *buf, int len)
+int io_multiplex_write(enum logcode code, char *buf, size_t len)
 {
        if (!io_multiplexing_out) return 0;
 
 {
        if (!io_multiplexing_out) return 0;
 
diff --git a/log.c b/log.c
index 3b53a9a..421829b 100644 (file)
--- a/log.c
+++ b/log.c
@@ -466,7 +466,7 @@ static void log_formatted(enum logcode code,
 
                l = strlen(n);
 
 
                l = strlen(n);
 
-               if ((l-1) + ((int)(s - &buf[0])) > sizeof(buf)) {
+               if (l + ((int)(s - &buf[0])) >= sizeof(buf)) {
                        rprintf(FERROR,"buffer overflow expanding %%%c - exiting\n",
                                p[0]);
                        exit_cleanup(RERR_MESSAGEIO);
                        rprintf(FERROR,"buffer overflow expanding %%%c - exiting\n",
                                p[0]);
                        exit_cleanup(RERR_MESSAGEIO);
index a574ea6..7628b10 100644 (file)
@@ -206,7 +206,8 @@ static int get_tmpname(char *fnametmp, char *fname)
 static int receive_data(int f_in,struct map_struct *buf,int fd,char *fname,
                        OFF_T total_size)
 {
 static int receive_data(int f_in,struct map_struct *buf,int fd,char *fname,
                        OFF_T total_size)
 {
-       int i,n,remainder,len,count;
+       int i;
+       unsigned int n,remainder,len,count;
        OFF_T offset = 0;
        OFF_T offset2;
        char *data;
        OFF_T offset = 0;
        OFF_T offset2;
        char *data;
diff --git a/rsync.h b/rsync.h
index d18540f..9565ed7 100644 (file)
--- a/rsync.h
+++ b/rsync.h
@@ -374,9 +374,9 @@ struct sum_buf {
 
 struct sum_struct {
   OFF_T flength;               /* total file length */
 
 struct sum_struct {
   OFF_T flength;               /* total file length */
-  int count;                   /* how many chunks */
-  int remainder;               /* flength % block_length */
-  int n;                       /* block_length */
+  size_t count;                        /* how many chunks */
+  size_t remainder;            /* flength % block_length */
+  size_t n;                    /* block_length */
   struct sum_buf *sums;                /* points to info for each chunk */
 };
 
   struct sum_buf *sums;                /* points to info for each chunk */
 };
 
diff --git a/util.c b/util.c
index c5bd662..e6acf50 100644 (file)
--- a/util.c
+++ b/util.c
@@ -275,7 +275,7 @@ int create_directory_path(char *fname)
 
    derived from GNU C's cccp.c.
 */
 
    derived from GNU C's cccp.c.
 */
-static int full_write(int desc, char *ptr, int len)
+static int full_write(int desc, char *ptr, size_t len)
 {
        int total_written;
        
 {
        int total_written;
        
@@ -301,11 +301,11 @@ static int full_write(int desc, char *ptr, int len)
    for an error.  
 
    derived from GNU C's cccp.c. */
    for an error.  
 
    derived from GNU C's cccp.c. */
-static int safe_read(int desc, char *ptr, int len)
+static int safe_read(int desc, char *ptr, size_t len)
 {
        int n_chars;
  
 {
        int n_chars;
  
-       if (len <= 0)
+       if (len == 0)
                return len;
  
 #ifdef EINTR
                return len;
  
 #ifdef EINTR