On a very very very rare number of occasions, we have seen an OOPS of this form: 500 OOPS: cannot open config file:/etc/vsftpd/vsftpd.conf.localhost when all the file permissions are seemingly correct. This was seen when using the tcp_wrappers env option VSFTPD_LOAD_CONF to load a secondary configuration file above and beyond /etc/vsftpd/vsftpd.conf. The result - on one occasion - was that vsftpd effectively refused ALL new connection attempts, always returning the same OOPS. Restarting vsftpd worked round the problem. No error logs of any kind - other than the OOPS on the FTP control connection - were seen. Hunting round the source code for explanations, I found that the RedHat version of vsftpd used this line in parseconf.c: (int)str_stat(&config_file_str, &p_statbuf); It appears that &config_file_str ACTUALLY contains a string containing the CONTENTS of the configuration file, rather than the filename itself. My supposition is that this is the more correct function to use: (int)vsf_sysutil_stat(p_filename, &p_statbuf); The invocation of str_stat() is included in the "nonrootconf" patch included in the RedHat releases, and is NOT part of vsftpd source itself. The broken code fragment, in my view, reads like this: retval = str_fileread(&config_file_str, p_filename, VSFTP_CONF_FILE_MAX); (int)str_stat(&config_file_str, &p_statbuf); /* Security - die unless the conf file is owned by root */ if (vsf_sysutil_retval_is_error(retval) || vsf_sysutil_statbuf_get_uid(p_statbuf) != VSFTP_ROOT_UID) { if (errs_fatal) { die2("cannot open config file:", p_filename); } else { return; } } What seems to be happening is that the config file contents are read into config_file_str, and then str_stat tries to use the file contents as a filename so as to return a p_statbuf. My reasoning is that somehow ( heaven knows how ) vsf_sysutil_statbuf_get_uid() almost always returns zero despite being passed an invalid p_statbuf, and the configuration file is accepted. On very very rare occasions, probably due to subtle changes in malloc'ed memory usage, vsf_sysutil_statbuf_get_uid() returns non-zero, and the configuration file raises an OOPS. I've seen this explicitly on Fedora Core 4, but the source code bug - if it is a bug - is still in the FC6 Devel tree. I attached a revised nonrootconf patch against the FC6 v2.0.5 SRPM which uses vsf_sysutil_stat instead.
Created attachment 136448 [details] Repaired version of vsftpd-1.2.1-nonrootconf.patch for vsftpd-2.0.5
The orignal vsftpd RPM DOES appear to detect changes of ownership of configuration files, despite the broken call to str_stat(). This was completely bizarre, and explaining this had me very confused. Musing on the matter a bit longer, I think I have an hypothesis which fits the observed behaviour: My reasoning goes that str_stat() is indeed passed a string containing the contents of the p_filename file rather than its filename. This is garbage, and hence str_stat() actually returns < 0, but the code fragment IGNORES the return value from str_stat() - even executing str_stat() when str_fileread() returns < 0. Meanwhile, vfs_sysutil_stat() which is called by str_stat() has already allocated memory for a statbuf, and has called the kernel via stat() itself. Now if stat() were to temporarily, and very wrongly, return a buffer filled with the last successful stat() call, AND that last stat() call to the kernel referred to the same p_filename configuration file, then p_statbuf would miraculously contain the correct statbuf even though stat() itself returned an error code. This would then mean that the only way for p_statbuf to contain the wrong inode's statbuf would be if another process called stat() between the call to str_fileread() and str_stat(). This would then mean we had a race condition which nearly always succeeded, which fits in with the observed behaviour. If this is true, it also implies that there maybe a sort of "information leakage bug" in the kernel itself, as stat() probably shouldn't share inode information between processes, and should also return "cleansed memory" in the statbuf if the stat() call fails overall. I hope this help to clear the muddy waters a little more...
Try please the last version of vsftpd (2.0.5-16) if problems still present. Thanks
Whilst I haven't had a chance to try the 2.0.5-16 version, I'm happy that the new vsftpd-2.0.5-file_stat.patch fixes the bug; I've had several machines running chroot'ed configurations with no ill-effects since I applied my corresponding version of the fix. Please feel free to close the bug, but please also create an FC6-Updates version of the RPM. Thanks, Ted
Thanks, update for FC6 will be pushed soon, now closing as rawhide fix.