Running static analysis on UWSGi identified several potential handle leaks that I believe are confirmed. They are quite minor, but still could be fixed.
The findings are:
- Handle leak in
create_server_socket
File: /core/socket.c
Problem:
Socket desciptor serverfd is acquired on line 82:
|
int serverfd = socket(domain, type, 0); |
On certain error paths (e.g. lines 94-98) uwsgi_nuclear_blast is called:
|
if (setsockopt(serverfd, SOL_SOCKET, SO_REUSEADDR, (const void *) &reuse, sizeof(int)) < 0) { |
|
uwsgi_error("SO_REUSEADDR setsockopt()"); |
|
uwsgi_nuclear_blast(); |
|
return -1; |
|
} |
Which terminates the process with
exit in most cases, however, it may simply return in some scenarios (e.g. when running as Emperor):
|
void uwsgi_nuclear_blast() { |
|
|
|
// the Emperor (as an example) cannot nuke itself |
|
if (uwsgi.disable_nuclear_blast) return; |
If the process survives, the function returns without closing serverfd, resulting in a handle leak.
Suggested patch:
Close serverfd before returning if the process survived nuclear blast:
if (setsockopt(serverfd, SOL_SOCKET, SO_REUSEADDR, (const void *) &reuse, sizeof(int)) < 0) {
uwsgi_error("SO_REUSEADDR setsockopt()");
uwsgi_nuclear_blast();
close(serverfd);
return -1;
}
- Handle leak in
uwsgi_load_plugin
File: /core/plugins.c
Problem:
Plugin handle plugin_handle is acquired via dlopen (e.g. on line 157):
|
plugin_handle = dlopen(plugin_filename, RTLD_NOW | RTLD_GLOBAL); |
Then, under the success label, the first dlsym call on line 175 may fail:
|
up = dlsym(plugin_handle, plugin_entry_symbol); |
And the subsequent dlsym call on line 197 may also fail:
|
up = dlsym(plugin_handle, plugin_entry_symbol); |
(Seems like an unlikely scenario, but I believe it is still possible if the user provided a regular .so file instead of a valid uwsgi plugin. Please correct me if I'm wrong though).
If both dlsym calls fail, the function reaches the end block at lines 268–275 and returns without closing plugin_handle:
|
end: |
|
if (need_free) |
|
free(plugin_name); |
|
if (plugin_filename) |
|
free(plugin_filename); |
|
|
|
return NULL; |
|
} |
This results in a handle leak.
Suggested patch:
Close plugin_handle in the end block if needed:
end:
if (need_free)
free(plugin_name);
if (plugin_filename)
free(plugin_filename);
if (plugin_handle && dlclose(plugin_handle)) {
uwsgi_error("dlclose()");
}
return NULL;
}
Please feel free to get back to me and reject any of the findings described above if you believe they are false positives, or discuss any of my suggested patches. I will adjust the linked PR accordingly.
Thank you for your time and consideration.
Found by Linux Verification Center with SVACE
Running static analysis on UWSGi identified several potential handle leaks that I believe are confirmed. They are quite minor, but still could be fixed.
The findings are:
create_server_socketFile: /core/socket.c
Problem:
Socket desciptor
serverfdis acquired on line 82:uwsgi/core/socket.c
Line 82 in 8d116f7
On certain error paths (e.g. lines 94-98)
uwsgi_nuclear_blastis called:uwsgi/core/socket.c
Lines 94 to 98 in 8d116f7
Which terminates the process with
exitin most cases, however, it may simply return in some scenarios (e.g. when running as Emperor):uwsgi/core/uwsgi.c
Lines 1455 to 1458 in 8d116f7
If the process survives, the function returns without closing
serverfd, resulting in a handle leak.Suggested patch:
Close
serverfdbefore returning if the process survived nuclear blast:uwsgi_load_pluginFile: /core/plugins.c
Problem:
Plugin handle
plugin_handleis acquired viadlopen(e.g. on line 157):uwsgi/core/plugins.c
Line 157 in 8d116f7
Then, under the
successlabel, the firstdlsymcall on line 175 may fail:uwsgi/core/plugins.c
Line 175 in 8d116f7
And the subsequent
dlsymcall on line 197 may also fail:uwsgi/core/plugins.c
Line 197 in 8d116f7
(Seems like an unlikely scenario, but I believe it is still possible if the user provided a regular .so file instead of a valid uwsgi plugin. Please correct me if I'm wrong though).
If both
dlsymcalls fail, the function reaches theendblock at lines 268–275 and returns without closingplugin_handle:uwsgi/core/plugins.c
Lines 268 to 275 in 8d116f7
This results in a handle leak.
Suggested patch:
Close
plugin_handlein theendblock if needed:Please feel free to get back to me and reject any of the findings described above if you believe they are false positives, or discuss any of my suggested patches. I will adjust the linked PR accordingly.
Thank you for your time and consideration.
Found by Linux Verification Center with SVACE