diff options
author | Wayne Davison <wayned@samba.org> | 2010-03-26 16:56:40 -0700 |
---|---|---|
committer | Wayne Davison <wayned@samba.org> | 2010-03-26 16:58:39 -0700 |
commit | 9a7532e516a6153ba6c59a59c329345509536a98 (patch) | |
tree | 84d32151aa05cfa3ce3908d996870d3a01624314 /flist.c | |
parent | 9b594a530ffdac3a7ec919fe891bda154fd297b0 (diff) | |
download | rsync-9a7532e516a6153ba6c59a59c329345509536a98.tar.gz rsync-9a7532e516a6153ba6c59a59c329345509536a98.tar.bz2 rsync-9a7532e516a6153ba6c59a59c329345509536a98.zip |
Fix directory-length overflow bug (7057).
Diffstat (limited to 'flist.c')
-rw-r--r-- | flist.c | 20 |
1 files changed, 14 insertions, 6 deletions
@@ -1728,21 +1728,29 @@ static void send_directory(int f, struct file_list *flist, char *fbuf, int len, } p = fbuf + len; - if (len != 1 || *fbuf != '/') + if (len == 1 && *fbuf == '/') + remainder = MAXPATHLEN - 1; + else if (len < MAXPATHLEN-1) { *p++ = '/'; - *p = '\0'; - remainder = MAXPATHLEN - (p - fbuf); + *p = '\0'; + remainder = MAXPATHLEN - (len + 1); + } else + remainder = 0; for (errno = 0, di = readdir(d); di; errno = 0, di = readdir(d)) { char *dname = d_name(di); if (dname[0] == '.' && (dname[1] == '\0' || (dname[1] == '.' && dname[2] == '\0'))) continue; - if (strlcpy(p, dname, remainder) >= remainder) { + unsigned name_len = strlcpy(p, dname, remainder); + if (name_len >= remainder) { + char save = fbuf[len]; + fbuf[len] = '\0'; io_error |= IOERR_GENERAL; rprintf(FERROR_XFER, - "cannot send long-named file %s\n", - full_fname(fbuf)); + "filename overflows max-path len by %u: %s/%s\n", + name_len - remainder + 1, fbuf, dname); + fbuf[len] = save; continue; } if (dname[0] == '\0') { |