bin/143570: [patch] stock ftpd does not handle "filesize" limit
right
Eugene Grosbein
egrosbein at rdtc.ru
Fri Feb 5 06:40:02 UTC 2010
>Number: 143570
>Category: bin
>Synopsis: [patch] stock ftpd does not handle "filesize" limit right
>Confidential: no
>Severity: non-critical
>Priority: medium
>Responsible: freebsd-bugs
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: sw-bug
>Submitter-Id: current-users
>Arrival-Date: Fri Feb 05 06:40:01 UTC 2010
>Closed-Date:
>Last-Modified:
>Originator: Eugene Grosbein
>Release: FreeBSD 6.4-STABLE i386
>Organization:
RDTC JSC
>Environment:
System: FreeBSD hq.delikates-nk.ru 6.4-STABLE FreeBSD 6.4-STABLE #8: Mon Feb 1 22:28:06 KRAT 2010 root at hq.delikates-nk.ru:/usr/local/obj/usr/local/src/sys/HQ i386
>Description:
There are some problems with stock ftpd concerning
"filesize" limit processing.
1. ftpd calls setusercontext() for authenticated user
with LOGIN_SETRESOURCES flag too early, before it updates wtmp.
It wtmp is large enough and user has filesize limit low,
ftpd's write to wtmp fails.
2. ftpd may not revert to superuser's context at the end
of user session and therefore fail to note session end in wtmp
(see above).
3. If ftpd hits limit while writing to disk file at user's request
it is instantly killed with SIGXFSZ. Instead, it should process it
gracefully, report an error to the user and contiue with the session.
>How-To-Repeat:
Add new login class with "filesize=NNN" to /etc/login.conf
(don't forget to run cap_mkdb /etc/login.conf after).
assign this class to a user and try to login to ftp server
as this user:
- if your wtmp file size is greater than NNN, you'll be instantly
disconnected;
- otherwise, try to upload a file bigger than NNN in size,
your connection will break after uploading NNN bytes.
>Fix:
--- libexec/ftpd/ftpd.c.orig 2010-02-05 11:19:23.000000000 +0700
+++ libexec/ftpd/ftpd.c 2010-02-05 13:02:10.000000000 +0700
@@ -428,6 +428,10 @@
}
}
+ /* handge filesize limit gracefully */
+ sa.sa_handler = SIG_IGN;
+ (void)sigaction(SIGXFSZ, &sa, NULL);
+
if (daemon_mode) {
int *ctl_sock, fd, maxfd = -1, nfds, i;
fd_set defreadfds, readfds;
@@ -1183,14 +1187,16 @@
#endif
(void) seteuid(0);
- if (logged_in && dowtmp)
- ftpd_logwtmp(ttyline, "", NULL);
- pw = NULL;
#ifdef LOGIN_CAP
setusercontext(NULL, getpwuid(0), 0,
LOGIN_SETPRIORITY|LOGIN_SETRESOURCES|LOGIN_SETUMASK|
LOGIN_SETMAC);
#endif
+
+ if (logged_in && dowtmp)
+ ftpd_logwtmp(ttyline, "", NULL);
+ pw = NULL;
+
#ifdef USE_PAM
if (pamh) {
if ((e = pam_setcred(pamh, PAM_DELETE_CRED)) != PAM_SUCCESS)
@@ -1463,7 +1469,7 @@
}
setusercontext(lc, pw, 0,
LOGIN_SETLOGIN|LOGIN_SETGROUP|LOGIN_SETPRIORITY|
- LOGIN_SETRESOURCES|LOGIN_SETUMASK|LOGIN_SETMAC);
+ LOGIN_SETUMASK|LOGIN_SETMAC);
#else
setlogin(pw->pw_name);
(void) initgroups(pw->pw_name, pw->pw_gid);
@@ -1485,6 +1491,10 @@
(struct sockaddr *)&his_addr);
logged_in = 1;
+#ifdef LOGIN_CAP
+ setusercontext(lc, pw, 0,LOGIN_SETRESOURCES);
+#endif
+
if (guest && stats && statfd < 0)
#ifdef VIRTUAL_HOSTING
statfd = open(thishost->statfile, O_WRONLY|O_APPEND);
@@ -2743,6 +2753,13 @@
dologout(int status)
{
+ (void) seteuid(0);
+#ifdef LOGIN_CAP
+ setusercontext(NULL, getpwuid(0), 0,
+ LOGIN_SETPRIORITY|LOGIN_SETRESOURCES|LOGIN_SETUMASK|
+ LOGIN_SETMAC);
+#endif
+
if (logged_in && dowtmp) {
(void) seteuid(0);
ftpd_logwtmp(ttyline, "", NULL);
>Release-Note:
>Audit-Trail:
>Unformatted:
More information about the freebsd-bugs
mailing list