kmod_util 内核服务
用途
调用指定系统调用之前和之后要调用的寄存器例程。
语法
参数
| 项 | 描述 |
|---|---|
| 标志 | 指定操作。 有效值为: KU_INTERCEPT, KU_INTERCEPT_STOP和 KU_INTERCEPT_CANCEL。 |
| 缓冲区 (buffer) | 指向包含系统调用拦截头和系统调用拦截结构的阵列的缓冲区。 |
| 布伦 | 指定该缓冲区的长度。 |
描述
kmod_util 内核服务允许对系统调用进行拦截。 名为 前 sc 函数的例程被指定为在被拦截的系统调用之前被调用。 名为 后 sc 函数的例程被指定为在所拦截的系统调用之后调用。 此外,允许 前 sc 函数异常中止系统调用,从而提供其自己的返回值并阻止后续 前 sc 函数和系统调用本身被调用。 同样,每个 后 sc 函数都可以检查和更改返回值。 如果系统调用未返回 (例如, thread_terminate) ,那么将不会调用 后 sc 函数。
对于每个拦截的系统调用,必须指定一个 前 sc 函数和/或一个 后 sc 函数。 如果在同一 kmod_util 调用中为同一系统调用注册了 前 sc 函数和 后 sc 函数,那么会将它们视为成对。 kmod_util 调用中指定的所有 前 sc 和 后 sc 函数都必须在与 kmod_util 内核服务的调用者相同的内核扩展中定义。 但是,其他内核扩展可拦截相同的系统调用。 首先调用最近注册的 前 sc 函数,最后调用其配对的 后 sc 函数。
实现对系统调用的拦截,以便拦截对系统调用的所有调用,即使对于现有进程也是如此。
可能有必要防止拦截某些系统调用,以避免破坏系统的稳定。 kmod_util 内核服务的未来版本或发行版可能会阻止拦截其他系统调用,并且此类更改将不会被视为违反二进制兼容性。
前 sc 函数的原型为:
int pre_sc(uintptr_t *rc, void *parms, uintptr_t cookie, void *buffer); 其中, 参数 是指向系统调用的参数的指针, 曲奇 是 kmod_util的调用者指定的不透明值, 缓冲 是供 前 sc 函数及其配对的 后 sc 函数使用的临时 128 字节缓冲区。
如果 前 sc 函数返回非零值,那么系统调用将异常中止。 返回码 参数是一个地址,可以在此地址指定备用返回值。 不调用后续 前 sc 函数,也不调用系统调用。 对于已调用的 前 sc 函数,将调用其配对的 后 sc 函数。
Post-sc 函数的原型是
void post_sc(uintptr_t *rc, void *parms, uintptr_t cookie,
void *buffer); 后 sc 函数的参数与 前 sc 函数的那些参数相同。 特别是, 缓冲 参数是传递给配对的 前 sc 函数的相同缓冲区。 返回值可以通过 后 sc 函数进行修改。
对于对 kmod_util 内核服务的调用,缓冲区包含一个头和一组有关要拦截的系统调用的元素。 这些结构的布局在 <sys/sysconfig.h>中定义。
如果在 kue_iflag 字段中设置了 KU_IGNORE 标志,那么将忽略数组元素。 否则,将验证输入缓冲区中的每个数组元素,如果发现任何错误,那么整个调用将失败而不执行任何部分。
- 拦截系统调用
- 对带有 KU_INTERCEPT 标志的 kmod_util () 的调用启动系统调用拦截。
- 正在停止系统呼叫拦截
对带有 KU_INTERCEPT_STOP 标志的 kmod_util () 的调用将暂挂对指定系统调用的拦截。 如果已针对指定的系统调用调用了 前 sc 函数,那么仍将调用其配对的 后 sc 函数,但将来对系统调用的调用将不会调用 前 sc 或 后 sc 函数。 对于最初未被调用内核扩展拦截的系统调用,停止拦截是无效的。
如果已暂挂对系统调用的拦截,那么只要指定相同的值 (例如 前 sc 和 后 sc 函数) ,就可以通过使用 KU_INTERCEPT 标志来调用 kmod_util () 函数来恢复该调用。
- 正在取消系统呼叫拦截
可以通过指定 KU_INTERCEPT_CANCEL 标志来取消系统调用拦截。 取消拦截时,即使调用了 后 sc 函数的配对 前 sc 函数,也不会调用该函数。 取消拦截原本不是由调用内核扩展所拦截的系统调用是无效的,但拦截可以取消,而不需要先停止拦截。
一旦取消了对系统调用的拦截,就可以通过调用带有 KU_INTERCEPT 标志的 kmod_util () 函数来重新拦截该系统调用。 在此情况下,可以指定不同的 前 sc 和 前 sc 函数。
返回值
如果可以对所有指定的系统调用执行指定的操作,那么将返回 0。 否则,将返回非零值,并且不会发生系统呼叫拦截状态的更改。 如果由于特定数组元素中的验证错误而发生错误,那么 kue_oflag 字段通常会更详细地标识该错误。
错误代码
如果产生错误,那么将返回下列其中一个错误值:
| 返回值 | 描述 |
|---|---|
| EINVAL | flags 参数不是 KU_INTERCEPT 和 KU_INTERCEPT_STOP,也不是 KU_INTERCEPT_CANCEL。 头中的字段无效,或者 布伦 参数与数组元素的数目不一致。 该缓冲区无效。 对于 KU_INTERCEPT,必须至少为要拦截的每个系统调用提供 前 sc 和 后 sc 中的一个。 所有 前 sc 和 后 sc 函数都必须与 kmod_util ()的调用者位于同一内核扩展中。 |
| EBUSY | 已发出拦截已被拦截的系统调用的请求。 |
| ENOENT | 已请求停止或取消对未被拦截的系统呼叫的拦截。 |
| ENOMEM | 无法分配内存以满足该请求。 |
| ENOTSUPP | 不允许对其中一个指定系统调用进行拦截。 |