Exemplo n.º 1
0
int __init xsm_dt_policy_init(void **policy_buffer, size_t *policy_size)
{
    struct bootmodule *mod = boot_module_find_by_kind(BOOTMOD_XSM);
    paddr_t paddr, len;

    if ( !mod || !mod->size )
        return 0;

    paddr = mod->start;
    len = mod->size;

    if ( !has_xsm_magic(paddr) )
    {
        printk(XENLOG_ERR "xsm: Invalid magic for XSM blob\n");
        return -EINVAL;
    }

    printk("xsm: Policy len = 0x%"PRIpaddr" start at 0x%"PRIpaddr"\n",
           len, paddr);

    *policy_buffer = xmalloc_bytes(len);
    if ( !*policy_buffer )
        return -ENOMEM;

    copy_from_paddr(*policy_buffer, paddr, len);
    *policy_size = len;

    return 0;
}
Exemplo n.º 2
0
static int install_equiv_cpu_table(
    struct microcode_amd *mc_amd,
    const void *data,
    size_t *offset)
{
    const struct mpbhdr *mpbuf = data + *offset + 4;

    *offset += mpbuf->len + CONT_HDR_SIZE;	/* add header length */

    if ( mpbuf->type != UCODE_EQUIV_CPU_TABLE_TYPE )
    {
        printk(KERN_ERR "microcode: Wrong microcode equivalent cpu table type field\n");
        return -EINVAL;
    }

    if ( mpbuf->len == 0 )
    {
        printk(KERN_ERR "microcode: Wrong microcode equivalent cpu table length\n");
        return -EINVAL;
    }

    mc_amd->equiv_cpu_table = xmalloc_bytes(mpbuf->len);
    if ( !mc_amd->equiv_cpu_table )
    {
        printk(KERN_ERR "microcode: Cannot allocate memory for equivalent cpu table\n");
        return -ENOMEM;
    }

    memcpy(mc_amd->equiv_cpu_table, mpbuf->data, mpbuf->len);
    mc_amd->equiv_cpu_table_size = mpbuf->len;

    return 0;
}
Exemplo n.º 3
0
static int microcode_resume_match(int cpu, const void *mc)
{
    struct ucode_cpu_info *uci = &per_cpu(ucode_cpu_info, cpu);
    struct microcode_amd *mc_amd = uci->mc.mc_amd;
    const struct microcode_amd *src = mc;

    if ( !microcode_fits(src, cpu) )
        return 0;

    if ( src != mc_amd )
    {
        if ( mc_amd )
        {
            xfree(mc_amd->equiv_cpu_table);
            xfree(mc_amd->mpb);
            xfree(mc_amd);
        }

        mc_amd = xmalloc(struct microcode_amd);
        uci->mc.mc_amd = mc_amd;
        if ( !mc_amd )
            return -ENOMEM;
        mc_amd->equiv_cpu_table = xmalloc_bytes(src->equiv_cpu_table_size);
        if ( !mc_amd->equiv_cpu_table )
            goto err1;
        mc_amd->mpb = xmalloc_bytes(src->mpb_size);
        if ( !mc_amd->mpb )
            goto err2;

        mc_amd->equiv_cpu_table_size = src->equiv_cpu_table_size;
        mc_amd->mpb_size = src->mpb_size;
        memcpy(mc_amd->mpb, src->mpb, src->mpb_size);
        memcpy(mc_amd->equiv_cpu_table, src->equiv_cpu_table,
               src->equiv_cpu_table_size);
    }

    return 1;

err2:
    xfree(mc_amd->equiv_cpu_table);
err1:
    xfree(mc_amd);
    uci->mc.mc_amd = NULL;
    return -ENOMEM;
}
Exemplo n.º 4
0
static int get_ucode_from_buffer_amd(
    struct microcode_amd *mc_amd,
    const void *buf,
    size_t bufsize,
    size_t *offset)
{
    const uint8_t *bufp = buf;
    size_t off;
    const struct mpbhdr *mpbuf;

    off = *offset;

    /* No more data */
    if ( off >= bufsize )
    {
        printk(KERN_ERR "microcode: Microcode buffer overrun\n");
        return -EINVAL;
    }

    mpbuf = (const struct mpbhdr *)&bufp[off];
    if ( mpbuf->type != UCODE_UCODE_TYPE )
    {
        printk(KERN_ERR "microcode: Wrong microcode payload type field\n");
        return -EINVAL;
    }

    if ( (off + mpbuf->len) > bufsize )
    {
        printk(KERN_ERR "microcode: Bad data in microcode data file\n");
        return -EINVAL;
    }

    if ( mc_amd->mpb_size < mpbuf->len )
    {
        if ( mc_amd->mpb )
        {
            xfree(mc_amd->mpb);
            mc_amd->mpb_size = 0;
        }
        mc_amd->mpb = xmalloc_bytes(mpbuf->len);
        if ( mc_amd->mpb == NULL )
            return -ENOMEM;
        mc_amd->mpb_size = mpbuf->len;
    }
    memcpy(mc_amd->mpb, mpbuf->data, mpbuf->len);

    *offset = off + mpbuf->len + 8;

    printk(KERN_DEBUG "microcode: CPU%d size %zu, block size %u offset %zu equivID %#x rev %#x\n",
           raw_smp_processor_id(), bufsize, mpbuf->len, off,
           ((struct microcode_header_amd *)mc_amd->mpb)->processor_rev_id,
           ((struct microcode_header_amd *)mc_amd->mpb)->patch_id);

    return 0;
}
Exemplo n.º 5
0
static int get_next_ucode_from_buffer_amd(
    void **mc,
    size_t *mc_size,
    const void *buf,
    size_t size,
    unsigned long *offset)
{
    struct microcode_header_amd *mc_header;
    size_t total_size;
    const uint8_t *bufp = buf;
    unsigned long off;

    off = *offset;

    /* No more data */
    if ( off >= size )
        return 1;

    if ( bufp[off] != UCODE_UCODE_TYPE )
    {
        printk(KERN_ERR "microcode: error! "
               "Wrong microcode payload type field\n");
        return -EINVAL;
    }

    mc_header = (struct microcode_header_amd *)(&bufp[off+8]);

    total_size = (unsigned long) (bufp[off+4] + (bufp[off+5] << 8));

    printk(KERN_DEBUG "microcode: size %lu, total_size %lu, offset %ld\n",
           (unsigned long)size, total_size, off);

    if ( (off + total_size) > size )
    {
        printk(KERN_ERR "microcode: error! Bad data in microcode data file\n");
        return -EINVAL;
    }

    if ( *mc_size < total_size )
    {
        xfree(*mc);
        *mc = xmalloc_bytes(total_size);
        if ( !*mc )
            return -ENOMEM;
        *mc_size = total_size;
    }
    else if ( *mc_size > total_size )
        memset(*mc + total_size, 0, *mc_size - total_size);
    memcpy(*mc, mc_header, total_size);

    *offset = off + total_size + 8;

    return 0;
}
Exemplo n.º 6
0
static int kexec_get_cpu(xen_kexec_range_t *range)
{
    int nr = range->nr;
    int nr_bytes = 0;

    if ( nr < 0 || nr >= num_present_cpus() )
        return -EINVAL;

    nr_bytes += sizeof_note("CORE", sizeof(ELF_Prstatus));
    nr_bytes += sizeof_note("Xen", sizeof(crash_xen_core_t));

    /* The Xen info note is included in CPU0's range. */
    if ( nr == 0 )
        nr_bytes += sizeof_note("Xen", sizeof(crash_xen_info_t));

    if ( per_cpu(crash_notes, nr) == NULL )
    {
        Elf_Note *note;

        note = per_cpu(crash_notes, nr) = xmalloc_bytes(nr_bytes);

        if ( note == NULL )
            return -ENOMEM;

        /* Setup CORE note. */
        setup_note(note, "CORE", NT_PRSTATUS, sizeof(ELF_Prstatus));

        /* Setup Xen CORE note. */
        note = ELFNOTE_NEXT(note);
        setup_note(note, "Xen", XEN_ELFNOTE_CRASH_REGS, sizeof(crash_xen_core_t));

        if (nr == 0)
        {
            /* Setup system wide Xen info note. */
            xen_crash_note = note = ELFNOTE_NEXT(note);
            setup_note(note, "Xen", XEN_ELFNOTE_CRASH_INFO, sizeof(crash_xen_info_t));
        }
    }

    range->start = __pa((unsigned long)per_cpu(crash_notes, nr));
    range->size = nr_bytes;
    return 0;
}
Exemplo n.º 7
0
static int flask_security_load(struct xen_flask_load *load)
{
    int ret;
    void *buf = NULL;
    bool is_reload = ss_initialized;

    ret = domain_has_security(current->domain, SECURITY__LOAD_POLICY);
    if ( ret )
        return ret;

    if ( load->size > MAX_POLICY_SIZE )
        return -EINVAL;

    buf = xmalloc_bytes(load->size);
    if ( !buf )
        return -ENOMEM;

    if ( _copy_from_guest(buf, load->buffer, load->size) )
    {
        ret = -EFAULT;
        goto out_free;
    }

    spin_lock(&sel_sem);

    ret = security_load_policy(buf, load->size);
    if ( ret )
        goto out;

    if ( !is_reload )
        printk(XENLOG_INFO "Flask: Policy loaded, continuing in %s mode.\n",
            flask_enforcing ? "enforcing" : "permissive");

    xfree(bool_pending_values);
    bool_pending_values = NULL;
    ret = 0;

 out:
    spin_unlock(&sel_sem);
 out_free:
    xfree(buf);
    return ret;
}
Exemplo n.º 8
0
static int install_equiv_cpu_table(const void *buf, uint32_t size,
                                   unsigned long *offset)
{
    const uint32_t *buf_pos = buf;
    unsigned long off;

    off = *offset;
    *offset = 0;

    /* No more data */
    if ( off >= size )
        return -EINVAL;

    if ( buf_pos[1] != UCODE_EQUIV_CPU_TABLE_TYPE )
    {
        printk(KERN_ERR "microcode: error! "
               "Wrong microcode equivalent cpu table type field\n");
        return -EINVAL;
    }

    if ( size == 0 )
    {
        printk(KERN_ERR "microcode: error! "
               "Wrong microcode equivalnet cpu table length\n");
        return -EINVAL;
    }

    equiv_cpu_table = xmalloc_bytes(size);
    if ( equiv_cpu_table == NULL )
    {
        printk(KERN_ERR "microcode: error, can't allocate "
               "memory for equiv CPU table\n");
        return -ENOMEM;
    }

    memset(equiv_cpu_table, 0, size);
    memcpy(equiv_cpu_table, (const void *)&buf_pos[3], size);

    *offset = size + 12;	/* add header length */

    return 0;
}
Exemplo n.º 9
0
static int install_equiv_cpu_table(
    struct microcode_amd *mc_amd,
    const uint32_t *buf,
    size_t *offset)
{
    const struct mpbhdr *mpbuf = (const struct mpbhdr *)&buf[1];

    /* No more data */
    if ( mpbuf->len + 12 >= *offset )
        return -EINVAL;

    if ( mpbuf->type != UCODE_EQUIV_CPU_TABLE_TYPE )
    {
        printk(KERN_ERR "microcode: Wrong microcode equivalent cpu table type field\n");
        return -EINVAL;
    }

    if ( mpbuf->len == 0 )
    {
        printk(KERN_ERR "microcode: Wrong microcode equivalent cpu table length\n");
        return -EINVAL;
    }

    mc_amd->equiv_cpu_table = xmalloc_bytes(mpbuf->len);
    if ( !mc_amd->equiv_cpu_table )
    {
        printk(KERN_ERR "microcode: Cannot allocate memory for equivalent cpu table\n");
        return -ENOMEM;
    }

    memcpy(mc_amd->equiv_cpu_table, mpbuf->data, mpbuf->len);
    mc_amd->equiv_cpu_table_size = mpbuf->len;

    *offset = mpbuf->len + 12;	/* add header length */

    return 0;
}
Exemplo n.º 10
0
void __init microcode_scan_module(
    unsigned long *module_map,
    const multiboot_info_t *mbi,
    void *(*bootmap)(const module_t *))
{
    module_t *mod = (module_t *)__va(mbi->mods_addr);
    uint64_t *_blob_start;
    unsigned long _blob_size;
    struct cpio_data cd;
    long offset;
    const char *p = NULL;
    int i;

    ucode_blob.size = 0;
    if ( !ucode_scan )
        return;

    if ( boot_cpu_data.x86_vendor == X86_VENDOR_AMD )
        p = "kernel/x86/microcode/AuthenticAMD.bin";
    else if ( boot_cpu_data.x86_vendor == X86_VENDOR_INTEL )
        p = "kernel/x86/microcode/GenuineIntel.bin";
    else
        return;

    /*
     * Try all modules and see whichever could be the microcode blob.
     */
    for ( i = 1 /* Ignore dom0 kernel */; i < mbi->mods_count; i++ )
    {
        if ( !test_bit(i, module_map) )
            continue;

        _blob_start = bootmap(&mod[i]);
        _blob_size = mod[i].mod_end;
        if ( !_blob_start )
        {
            printk("Could not map multiboot module #%d (size: %ld)\n",
                   i, _blob_size);
            continue;
        }
        cd.data = NULL;
        cd.size = 0;
        cd = find_cpio_data(p, _blob_start, _blob_size, &offset /* ignore */);
        if ( cd.data )
        {
                /*
                 * This is an arbitrary check - it would be sad if the blob
                 * consumed most of the memory and did not allow guests
                 * to launch.
                 */
                if ( cd.size > MAX_EARLY_CPIO_MICROCODE )
                {
                    printk("Multiboot %d microcode payload too big! (%ld, we can do %d)\n",
                           i, cd.size, MAX_EARLY_CPIO_MICROCODE);
                    goto err;
                }
                ucode_blob.size = cd.size;
                ucode_blob.data = xmalloc_bytes(cd.size);
                if ( !ucode_blob.data )
                    cd.data = NULL;
                else
                    memcpy(ucode_blob.data, cd.data, cd.size);
        }
        bootmap(NULL);
        if ( cd.data )
            break;
    }
    return;
err:
    bootmap(NULL);
}
Exemplo n.º 11
0
int main( int argc, char ** argv )
{
    int    i,n=10;
    KMAP * km;
    char * p;
    char   str[80];

    str[79] = '\0';

    printf("usage: kmap nkeys (default=10)\n\n");

    km = KMapNew( free );  /* use 'free' to free 'userdata' */

    KMapSetNoCase(km,1);  //need to add xlat....

    if( argc > 1 )
    {
        n = atoi(argv[1]);
    }

    for(i=1;i<=n;i++)
    {
        snprintf(str, sizeof(str) - 1, "KeyWord%d",i);
        KMapAdd( km, str, 0 /* strlen(str) */, strupr(strdup(str)) );
        printf("Adding Key=%s\n",str);
    }
    printf("xmem: %u bytes, %d chars\n",xmalloc_bytes(),km->nchars);

    printf("\nKey Find test...\n");
    for(i=1;i<=n;i++)
    {
        snprintf(str, sizeof(str) - 1, "KeyWord%d",i);
        p = (char*) KMapFind( km, str,  0 /*strlen(str) */ );
        if(p)printf("key=%s, data=%*s\n",str,strlen(str),p);
        else printf("'%s' NOT found.\n",str);
    }

    KMapSetNoCase(km,0);  // this should fail all key searches
    printf("\nKey Find test2...\n");
    for(i=1;i<=n;i++)
    {
        snprintf(str, sizeof(str) - 1, "KeyWord%d",i);
        p = (char*) KMapFind( km, str,  0 /*strlen(str) */ );
        if(p)printf("key=%s, data=%*s\n",str,strlen(str),p);
        else printf("'%s' NOT found.\n",str);
    }

    printf("\nKey FindFirst/Next test...\n");
    for(p = (char*) KMapFindFirst(km); p; p=(char*)KMapFindNext(km) )
        printf("data=%s\n",p);

    printf("\nKey FindFirst/Next test done.\n");

    KMapDelete( km );

    printf("xmem: %u bytes\n",xmalloc_bytes());

    printf("normal pgm finish.\n");

    return 0;
}
Exemplo n.º 12
0
static int cpu_request_microcode(int cpu, const void *buf, size_t size)
{
    const uint32_t *buf_pos;
    unsigned long offset = 0;
    int error;
    struct ucode_cpu_info *uci = &per_cpu(ucode_cpu_info, cpu);
    void *mc;
    size_t mc_size;

    /* We should bind the task to the CPU */
    BUG_ON(cpu != raw_smp_processor_id());

    buf_pos = (const uint32_t *)buf;

    if ( buf_pos[0] != UCODE_MAGIC )
    {
        printk(KERN_ERR "microcode: error! Wrong "
               "microcode patch file magic\n");
        return -EINVAL;
    }

    error = install_equiv_cpu_table(buf, (uint32_t)(buf_pos[2]), &offset);
    if ( error )
    {
        printk(KERN_ERR "microcode: installing equivalent cpu table failed\n");
        return -EINVAL;
    }

    /* Size of 1st microcode patch in bytes */
    mc_size = buf_pos[offset / sizeof(*buf_pos) + 1];
    mc = xmalloc_bytes(mc_size);
    if ( mc == NULL )
    {
        printk(KERN_ERR "microcode: error! "
               "Can not allocate memory for microcode patch\n");
        error = -ENOMEM;
        goto out;
    }

    /* implicitely validates uci->mc.mc_valid */
    uci->mc.mc_amd = mc;

    /*
     * It's possible the data file has multiple matching ucode,
     * lets keep searching till the latest version
     */
    while ( (error = get_next_ucode_from_buffer_amd(&mc, &mc_size, buf, size,
                                                    &offset)) == 0 )
    {
        uci->mc.mc_amd = mc;

        error = microcode_fits(mc, cpu);
        if (error <= 0)
            continue;

        error = apply_microcode(cpu);
        if (error == 0)
        {
            error = 1;
            break;
        }
    }

    /* On success keep the microcode patch for
     * re-apply on resume.
     */
    if ( error <= 0 )
    {
        xfree(mc);
        mc = NULL;
    }
    else
        error = 0;
    uci->mc.mc_amd = mc;

out:
    xfree(equiv_cpu_table);
    equiv_cpu_table = NULL;

    return error;
}
Exemplo n.º 13
0
static int domain_has_security(struct domain *d, u32 perms)
{
    struct domain_security_struct *dsec;
    
    dsec = d->ssid;
    if ( !dsec )
        return -EACCES;
        
    return avc_has_perm(dsec->sid, SECINITSID_SECURITY, SECCLASS_SECURITY, 
                        perms, NULL);
}

static int flask_copyin_string(XEN_GUEST_HANDLE_PARAM(char) u_buf, char **buf, uint32_t size)
{
    char *tmp = xmalloc_bytes(size + 1);
    if ( !tmp )
        return -ENOMEM;

    if ( copy_from_guest(tmp, u_buf, size) )
    {
        xfree(tmp);
        return -EFAULT;
    }
    tmp[size] = 0;

    *buf = tmp;
    return 0;
}

static int flask_security_user(struct xen_flask_userlist *arg)