sudo_dso_load: add AIX fallback path from shlib.so to shlib.a(shlib.so).

If the .so file is missing but the .a file exists, try to dlopen()
the AIX .a file using the .so name as the member.  We need to avoid
breaking existing configurations if the type of AIX shared library
changes when sudo is upgraded.
This commit is contained in:
Todd C. Miller
2022-12-26 07:43:55 -07:00
parent 206700c3f0
commit 97fb4eae72
2 changed files with 79 additions and 27 deletions

View File

@@ -81,14 +81,35 @@ sudo_stat_plugin(struct plugin_info *info, char *fullpath,
}
#ifdef _AIX
if (status == -1 && errno == ENOENT) {
/* Check for AIX path(module) syntax. */
char *cp = strrchr(fullpath, '(');
if (cp != NULL) {
/* Only for archive files (e.g. sudoers.a). */
if (cp > fullpath + 2 && cp[-2] == '.' && cp[-1] == 'a') {
*cp = '\0';
status = stat(fullpath, sb);
*cp = '(';
len = strlen(fullpath);
if (len > 2 && fullpath[len - 1] == ')') {
/* Check for AIX shlib.a(member) dlopen(3) syntax. */
char *cp = strrchr(fullpath, '(');
if (cp != NULL) {
/* Only for archive files (e.g. sudoers.a). */
if (cp > fullpath + 2 && cp[-2] == '.' && cp[-1] == 'a') {
*cp = '\0';
status = stat(fullpath, sb);
*cp = '(';
}
}
} else if (len > 3 && strcmp(&fullpath[len - 3], ".so") == 0) {
/*
* Check for AIX-style shlib.a if shlib.so does not exist for
* compatibility with sudo versions that use SVR4-style shlibs.
*/
fullpath[len - 2] = 'a';
fullpath[len - 1] = '\0';
len--;
status = stat(fullpath, sb);
if (status == 0) {
/* Use info->path as the member of the .a file. */
int n = snprintf(fullpath + len, pathsize - len, "(%s)",
sudo_basename(info->path));
if (n < 0 || (size_t)n >= pathsize - len) {
errno = ENAMETOOLONG;
goto done;
}
}
}
}