Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 10 Jan 2002 11:39:15 -0800 (PST)
From:      Vladislav Shabanov <vs@rambler-co.ru>
To:        freebsd-gnats-submit@FreeBSD.org
Subject:   bin/33770: ftpd performs an infinite loop after sending >4Gb file via sendfile
Message-ID:  <200201101939.g0AJdFc10108@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help

>Number:         33770
>Category:       bin
>Synopsis:       ftpd performs an infinite loop after sending >4Gb file via sendfile
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Thu Jan 10 11:40:01 PST 2002
>Closed-Date:
>Last-Modified:
>Originator:     Vladislav Shabanov
>Release:        RELENG_4
>Organization:
Rambler
>Environment:
FreeBSD index2.park.rambler.ru 4.4-RC FreeBSD 4.4-RC #2: Mon Oct  1 14:27:56 MSD
 2001     root@index2.park.rambler.ru:/usr/src/sys/compile/INDEX2  i386      
>Description:
When ftpd sends a large file it hungs up.
The file sent seems to be good (no corruption), but its impossible
to retreive next one or do something else with this ftpd.

This occures because 

size_t len;
...

off_t filesize;

len = filesize; /* len < filesize if filesize > 4 Gb */
sendfile ( ... , len, &cnt, ...)

len -= cnt; /* len will be zero */

after second call to sendfile ( ... , len, &cnt, ...)
system will send the tail of the file, and we have
an infinite loop because always (cnt < filesize)


>How-To-Repeat:
dd if=/dev/zero of=./mylargefile bs=1M count=8192
fetch -o /dev/null ftp://me:mypassword@127.0.0.1/....mylargefile

fetch will retrieve all file but it will infinitely wait for ftpd to
send a reply(226, "Transfer complete.");

>Fix:
--- ftpd.c-old  Tue Aug 21 18:14:38 2001
+++ ftpd.c      Thu Jan 10 22:10:41 2002
@@ -1753,12 +1753,12 @@
                        len = filesize;
                        err = cnt = offset = 0;

-                       while (err != -1 && cnt < filesize) {
-                               err = sendfile(filefd, netfd, offset, len,
+                       while (err != -1 && filesize > 0) {
+                               err = sendfile(filefd, netfd, offset, 0,
                                        (struct sf_hdtr *) NULL, &cnt, 0);
                                byte_count += cnt;
                                offset += cnt;
-                               len -= cnt;
+                               filesize -= cnt;

                                if (err == -1) {
                                        if (!cnt)      
>Release-Note:
>Audit-Trail:
>Unformatted:

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200201101939.g0AJdFc10108>