Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 11 May 2003 15:20:13 -0700 (PDT)
From:      Nick Leuta <skynick@stu.lipetsk.ru>
To:        freebsd-bugs@FreeBSD.org
Subject:   Re: bin/52072: Wrong behaviour of the ftpd when the OOB data received
Message-ID:  <200305112220.h4BMKDNQ005222@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help
The following reply was made to PR bin/52072; it has been noted by GNATS.

From: Nick Leuta <skynick@stu.lipetsk.ru>
To: freebsd-gnats-submit@FreeBSD.org, alexs@ratmir.ru
Cc:  
Subject: Re: bin/52072: Wrong behaviour of the ftpd when the OOB data received
Date: Mon, 12 May 2003 02:12:57 +0400

 There is another approach to the solution. I don't know what's better...
 
 This patch tries to fix a potential incomplite write() call - SIGURG signal
 may be received at a time of writing a data to a socket. Also I don't know
 the reasons for "sa.sa_flags = 0;", but it's possible that I simple don't
 know them...
 
 --- ftpd.ori/ftpd.c	Tue Feb 11 17:10:48 2003
 +++ ftpd/ftpd.c	Mon May 12 01:42:35 2003
 @@ -239,8 +239,7 @@
  static void	selecthost(union sockunion *);
  #endif
  static void	 ack(char *);
 -static void	 sigurg(int);
 -static void	 myoob(void);
 +static void	 myoob(int signo);
  static int	 checkuser(char *, char *, int, char **);
  static FILE	*dataconn(char *, off_t, char *);
  static void	 dolog(struct sockaddr *);
 @@ -546,8 +545,8 @@
  	sa.sa_handler = SIG_DFL;
  	(void)sigaction(SIGCHLD, &sa, NULL);
  
 -	sa.sa_handler = sigurg;
 -	sa.sa_flags = 0;		/* don't restart syscalls for SIGURG */
 +	sa.sa_handler = myoob;
 +	sa.sa_flags = SA_RESTART;
  	(void)sigaction(SIGURG, &sa, NULL);
  
  	sigfillset(&sa.sa_mask);	/* block all signals in handler */
 @@ -1991,8 +1990,8 @@
  send_data(FILE *instr, FILE *outstr, off_t blksize, off_t filesize, int isreg)
  {
  	int c, filefd, netfd;
 -	char *buf;
 -	off_t cnt;
 +	char *buf, *bp;
 +	off_t cnt = 0, len;
  
  	transflag++;
  	switch (type) {
 @@ -2069,16 +2068,23 @@
  			return (-1);
  		}
  
 -		while ((cnt = read(filefd, buf, (u_int)blksize)) > 0 &&
 -		    write(netfd, buf, cnt) == cnt)
 -			byte_count += cnt;
 +		while ((len = read(filefd, buf, (u_int)blksize)) > 0) {
 +			bp = buf;
 +			do {
 +				cnt = write(netfd, bp, len);
 +				len -= cnt;
 +				bp += cnt;
 +				if (cnt > 0) byte_count += cnt;
 +				if (recvurg)
 +					goto got_oob;
 +			} while (cnt > 0 && len > 0);
 +		}
  		transflag = 0;
  		(void)free(buf);
 -		if (cnt != 0) {
 -			if (cnt < 0)
 -				goto file_err;
 -			goto data_err;
 -		}
 +		if (len < 0)
 +		    goto file_err;
 +		if (cnt < 0)
 +		    goto data_err;
  		reply(226, "Transfer complete.");
  		return (0);
  	default:
 @@ -2098,7 +2104,6 @@
  	return (-1);
  
  got_oob:
 -	myoob();
  	recvurg = 0;
  	transflag = 0;
  	return (-1);
 @@ -2194,7 +2199,6 @@
  	return (-1);
  
  got_oob:
 -	myoob();
  	recvurg = 0;
  	transflag = 0;
  	return (-1);
 @@ -2612,14 +2616,7 @@
  }
  
  static void
 -sigurg(int signo)
 -{
 -
 -	recvurg = 1;
 -}
 -
 -static void
 -myoob(void)
 +myoob(int signo)
  {
  	char *cp;
  
 @@ -2636,6 +2633,9 @@
  		tmpline[0] = '\0';
  		reply(426, "Transfer aborted. Data connection closed.");
  		reply(226, "Abort successful");
 +
 +		recvurg = 1;
 +		return;
  	}
  	if (strcmp(cp, "STAT\r\n") == 0) {
  		tmpline[0] = '\0';
 @@ -3022,7 +3022,6 @@
  			char nbuf[MAXPATHLEN];
  
  			if (recvurg) {
 -				myoob();
  				recvurg = 0;
  				transflag = 0;
  				goto out;



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