SOLARIS: Reset syscalls on mod_install failure

If our call to mod_install fails for any reason (for example, if the
afs entry is missing from /etc/name_to_sysnum), we may still have set
the sysent structures for setgroups and ioctl to point at libafs code.
So calls to those syscalls will cause a panic, since the code they
point to is no longer loaded.

To avoid this, just reset the sysent entries back to what they were if
we fail to load, just like we do when unloading the module.

Change-Id: Ia0d6691780c749a0f550e640783c093ae45604ac
Reviewed-on: http://gerrit.openafs.org/4685
Reviewed-by: Derrick Brashear <shadow@dementia.org>
Tested-by: Derrick Brashear <shadow@dementia.org>
This commit is contained in:
Andrew Deason 2011-05-19 17:02:35 -05:00 committed by Derrick Brashear
parent 89b22dfe86
commit ca425b7d49

View File

@ -574,6 +574,19 @@ static struct modlinkage afs_modlinkage = {
NULL
};
static void
reset_sysent(void)
{
if (afs_sinited) {
sysent[SYS_setgroups].sy_callc = afs_orig_setgroups;
sysent[SYS_ioctl].sy_call = afs_orig_ioctl;
#if defined(AFS_SUN57_64BIT_ENV)
sysent32[SYS_setgroups].sy_callc = afs_orig_setgroups32;
sysent32[SYS_ioctl].sy_call = afs_orig_ioctl32;
#endif
}
}
/** This is the function that modload calls when loading the afs kernel
* extensions. The solaris modload program searches for the _init
* function in a module and calls it when modloading
@ -670,6 +683,11 @@ _init()
osi_Init(); /* initialize global lock, etc */
code = mod_install(&afs_modlinkage);
if (code) {
/* we failed to load, so make sure we don't leave behind any
* references to our syscall handlers */
reset_sysent();
}
return code;
}
@ -689,14 +707,7 @@ _fini()
if (afs_globalVFS)
return EBUSY;
if (afs_sinited) {
sysent[SYS_setgroups].sy_callc = afs_orig_setgroups;
sysent[SYS_ioctl].sy_call = afs_orig_ioctl;
#if defined(AFS_SUN57_64BIT_ENV)
sysent32[SYS_setgroups].sy_callc = afs_orig_setgroups32;
sysent32[SYS_ioctl].sy_call = afs_orig_ioctl32;
#endif
}
reset_sysent();
code = mod_remove(&afs_modlinkage);
return code;
}