虽说是通用堆喷,但是局限性很大,很多保护技术无法绕过

userfaultfd 系统调用

为用户提供了一个用户空间处理缺页异常的接口,用户可以自定义缺页处理程序。

setxattr

static long
setxattr(struct dentry *d, const char __user *name, const void __user *value,
     size_t size, int flags)
{
    int error;
    void *kvalue = NULL;
    char kname[XATTR_NAME_MAX + 1];

    if (flags & ~(XATTR_CREATE|XATTR_REPLACE))
        return -EINVAL;

    error = strncpy_from_user(kname, name, sizeof(kname));
    if (error == 0 || error == sizeof(kname))
        error = -ERANGE;
    if (error < 0)
        return error;

    if (size) {
        if (size > XATTR_SIZE_MAX)
            return -E2BIG;
        kvalue = kmalloc(size, GFP_KERNEL | __GFP_NOWARN);【1】
        if (!kvalue) {
            kvalue = vmalloc(size);
            if (!kvalue)
                return -ENOMEM;
        }
        if (copy_from_user(kvalue, value, size)) {        【2】
            error = -EFAULT;
            goto out;
        }
        if ((strcmp(kname, XATTR_NAME_POSIX_ACL_ACCESS) == 0) ||
            (strcmp(kname, XATTR_NAME_POSIX_ACL_DEFAULT) == 0))
            posix_acl_fix_xattr_from_user(kvalue, size);
    }

    error = vfs_setxattr(d, kname, kvalue, size, flags);
out:
    kvfree(kvalue);

    return error;
}
  • 【1】:内核调用kmalloc 申请了size大小的空间,size实在用户态传入的,因此,可以申请任意大小的空间。
  • 【2】:调用copy_from_user ,把用户空间的值复制到内核

步骤

两个线程:

  1. 主线程触发缺页,执行handler
  2. handler 使主线程睡眠

fork:

  1. 执行两个线程
  2. 执行喷射完的函数

preView