webmin
webmin copied to clipboard
Endless loop in foreign_require when ReadParse is called in module lib
When the ReadParse
function is called in a module's core lib (rather than individual cgi scripts) it triggers an endless loop if you call foreign_require($module)
where $module is the name of the module in question.
This becomes a big problem because this is exactly what webmin's config-lib.pl does when you try to save the module config in the Web UI.
One test case is the vsftpd-webmin module. This is the code tree before I committed a workaround: https://github.com/rdmark/vsftpd-webmin/tree/37521b686f7d63d891a71c91665dda4a1534ef41
See also https://forum.virtualmin.com/t/endless-loop-in-foreign-require/123882
Thanks for reporting this. But how does ReadParse end up calling itself when it never calls any other foreign functions?
Good question! I didn't trace this further because I couldn't find where foreign_require
is implemented...
FWIW I don't think it's a correct usecase to call ReadParse
from the module library (I'm not the original author of this module, only its caretaker.) However what might be fruitful is to look into error handling and bail out rather than getting stuck in a hard-to-debug endless loop in foreign_require
. Just a thought!
Yeah normally it's only called from a .cgi script. Where in the module library is it called? I couldn't find this when searching the git repo for vsftpd-webmin
Right after init_config() -- https://github.com/rdmark/vsftpd-webmin/blob/37521b686f7d63d891a71c91665dda4a1534ef41/vsftpd-lib.pl#L15
BEGIN {
push(@INC, "..");
$DEBUG = 0;
if ($DEBUG) {
use warnings;
use CGI::Carp qw(carpout);
open(ERROR_LOG, ">>/tmp/webmin_vsftpd_error_log")
or die("Can't setup error log: $!\n");
carpout(\*ERROR_LOG);
}
};
use WebminCore;
init_config();
ReadParse();
%access = get_module_acl();
@EXPORT = qw($tabs);
# [module functions defined after this]
I think that's a bug the module author should fix .. ReadParse()
just isn't going to work in that context.
Well noted. I'll have a fix in the next release tag from my fork.