webmin icon indicating copy to clipboard operation
webmin copied to clipboard

Endless loop in foreign_require when ReadParse is called in module lib

Open rdmark opened this issue 1 year ago • 6 comments

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

rdmark avatar Dec 09 '23 23:12 rdmark

Thanks for reporting this. But how does ReadParse end up calling itself when it never calls any other foreign functions?

jcameron avatar Dec 09 '23 23:12 jcameron

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!

rdmark avatar Dec 09 '23 23:12 rdmark

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

jcameron avatar Dec 09 '23 23:12 jcameron

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]

rdmark avatar Dec 09 '23 23:12 rdmark

I think that's a bug the module author should fix .. ReadParse() just isn't going to work in that context.

jcameron avatar Dec 09 '23 23:12 jcameron

Well noted. I'll have a fix in the next release tag from my fork.

rdmark avatar Dec 10 '23 00:12 rdmark