[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] Merging with xen-unstable
# HG changeset patch # User djm@xxxxxxxxxxxxxxx # Node ID e173a853dc46f7b7f066a6dea2990a54e2a86295 # Parent 9be7fe98a5565bf8f6297332e0367cd6904f52af # Parent dcdcec634c2d5624988d9f4907ade378ff575c51 Merging with xen-unstable diff -r 9be7fe98a556 -r e173a853dc46 .hgignore --- a/.hgignore Tue Aug 2 10:47:41 2005 +++ b/.hgignore Tue Aug 2 17:20:46 2005 @@ -86,6 +86,8 @@ ^tools/check/\..*$ ^tools/cmdline/.*$ ^tools/cmdline/xen/.*$ +^tools/consoled/consoled$ +^tools/consoled/xc_console$ ^tools/debugger/pdb/pdb$ ^tools/debugger/pdb/linux-[0-9.]*-module/.*\.ko$ ^tools/debugger/pdb/linux-[0-9.]*-module/.*\.mod.c$ @@ -128,8 +130,8 @@ ^tools/misc/xc_shadow$ ^tools/misc/xen_cpuperf$ ^tools/misc/xenperf$ -^tools/policy/policy_tool$ -^tools/policy/xen/.*$ +^tools/security/secpol_tool$ +^tools/security/xen/.*$ ^tools/pygrub/build/.*$ ^tools/python/build/.*$ ^tools/tests/test_x86_emulator$ diff -r 9be7fe98a556 -r e173a853dc46 linux-2.6-xen-sparse/arch/xen/configs/xen0_defconfig_x86_32 --- a/linux-2.6-xen-sparse/arch/xen/configs/xen0_defconfig_x86_32 Tue Aug 2 10:47:41 2005 +++ b/linux-2.6-xen-sparse/arch/xen/configs/xen0_defconfig_x86_32 Tue Aug 2 17:20:46 2005 @@ -18,8 +18,8 @@ CONFIG_XEN_NETDEV_BACKEND=y CONFIG_XEN_BLKDEV_FRONTEND=y CONFIG_XEN_NETDEV_FRONTEND=y -CONFIG_XEN_NETDEV_GRANT_TX=y - CONFIG_XEN_NETDEV_GRANT_RX=y +#CONFIG_XEN_NETDEV_GRANT_TX=y +#CONFIG_XEN_NETDEV_GRANT_RX=y # CONFIG_XEN_NETDEV_FRONTEND_PIPELINED_TRANSMITTER is not set # CONFIG_XEN_BLKDEV_TAP is not set # CONFIG_XEN_SHADOW_MODE is not set diff -r 9be7fe98a556 -r e173a853dc46 linux-2.6-xen-sparse/arch/xen/configs/xenU_defconfig_x86_32 --- a/linux-2.6-xen-sparse/arch/xen/configs/xenU_defconfig_x86_32 Tue Aug 2 10:47:41 2005 +++ b/linux-2.6-xen-sparse/arch/xen/configs/xenU_defconfig_x86_32 Tue Aug 2 17:20:46 2005 @@ -15,8 +15,8 @@ CONFIG_XEN_BLKDEV_GRANT=y CONFIG_XEN_BLKDEV_FRONTEND=y CONFIG_XEN_NETDEV_FRONTEND=y -CONFIG_XEN_NETDEV_GRANT_TX=y -CONFIG_XEN_NETDEV_GRANT_RX=y +#CONFIG_XEN_NETDEV_GRANT_TX=y +#CONFIG_XEN_NETDEV_GRANT_RX=y # CONFIG_XEN_NETDEV_FRONTEND_PIPELINED_TRANSMITTER is not set # CONFIG_XEN_BLKDEV_TAP is not set # CONFIG_XEN_SHADOW_MODE is not set diff -r 9be7fe98a556 -r e173a853dc46 linux-2.6-xen-sparse/arch/xen/i386/mm/fault.c --- a/linux-2.6-xen-sparse/arch/xen/i386/mm/fault.c Tue Aug 2 10:47:41 2005 +++ b/linux-2.6-xen-sparse/arch/xen/i386/mm/fault.c Tue Aug 2 17:20:46 2005 @@ -204,6 +204,63 @@ fastcall void do_invalid_op(struct pt_regs *, unsigned long); +#ifdef CONFIG_X86_PAE +static void dump_fault_path(unsigned long address) +{ + unsigned long *p, page; + + page = __pa(per_cpu(cur_pgd, smp_processor_id())); + p = (unsigned long *)__va(page); + p += (address >> 30) * 2; + printk(KERN_ALERT "%08lx -> *pde = %08lx:%08lx\n", page, p[1], p[0]); + if (p[0] & 1) { + page = p[0] & PAGE_MASK; + address &= 0x3fffffff; + page = machine_to_phys(page); + p = (unsigned long *)__va(page); + p += (address >> 21) * 2; + printk(KERN_ALERT "%08lx -> *pme = %08lx:%08lx\n", page, p[1], p[0]); +#ifndef CONFIG_HIGHPTE + if (p[0] & 1) { + page = p[0] & PAGE_MASK; + address &= 0x001fffff; + page = machine_to_phys(page); + p = (unsigned long *) __va(page); + p += (address >> 12) * 2; + printk(KERN_ALERT "%08lx -> *pte = %08lx:%08lx\n", page, p[1], p[0]); + } +#endif + } +} +#else +static void dump_fault_path(unsigned long address) +{ + unsigned long page; + + page = ((unsigned long *) per_cpu(cur_pgd, smp_processor_id())) + [address >> 22]; + printk(KERN_ALERT "*pde = ma %08lx pa %08lx\n", page, + machine_to_phys(page)); + /* + * We must not directly access the pte in the highpte + * case, the page table might be allocated in highmem. + * And lets rather not kmap-atomic the pte, just in case + * it's allocated already. + */ +#ifndef CONFIG_HIGHPTE + if (page & 1) { + page &= PAGE_MASK; + address &= 0x003ff000; + page = machine_to_phys(page); + page = ((unsigned long *) __va(page))[address >> PAGE_SHIFT]; + printk(KERN_ALERT "*pte = ma %08lx pa %08lx\n", page, + machine_to_phys(page)); + } +#endif +} +#endif + + /* * This routine handles page faults. It determines the address, * and the problem, and then passes it off to one of the appropriate @@ -220,7 +277,6 @@ struct task_struct *tsk; struct mm_struct *mm; struct vm_area_struct * vma; - unsigned long page; int write; siginfo_t info; @@ -454,26 +510,7 @@ printk(" at virtual address %08lx\n",address); printk(KERN_ALERT " printing eip:\n"); printk("%08lx\n", regs->eip); - page = ((unsigned long *) per_cpu(cur_pgd, smp_processor_id())) - [address >> 22]; - printk(KERN_ALERT "*pde = ma %08lx pa %08lx\n", page, - machine_to_phys(page)); - /* - * We must not directly access the pte in the highpte - * case, the page table might be allocated in highmem. - * And lets rather not kmap-atomic the pte, just in case - * it's allocated already. - */ -#ifndef CONFIG_HIGHPTE - if (page & 1) { - page &= PAGE_MASK; - address &= 0x003ff000; - page = machine_to_phys(page); - page = ((unsigned long *) __va(page))[address >> PAGE_SHIFT]; - printk(KERN_ALERT "*pte = ma %08lx pa %08lx\n", page, - machine_to_phys(page)); - } -#endif + dump_fault_path(address); die("Oops", regs, error_code); bust_spinlocks(0); do_exit(SIGKILL); diff -r 9be7fe98a556 -r e173a853dc46 linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c --- a/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c Tue Aug 2 10:47:41 2005 +++ b/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c Tue Aug 2 17:20:46 2005 @@ -5,6 +5,7 @@ * * Copyright (c) 2003, B Dragovic * Copyright (c) 2003-2004, M Williamson, K Fraser + * Copyright (c) 2005 Dan M. Smith, IBM Corporation * * This file may be distributed separately from the Linux kernel, or * incorporated into other software packages, subject to the following license: @@ -42,7 +43,6 @@ #include <linux/vmalloc.h> #include <asm-xen/xen_proc.h> #include <asm-xen/hypervisor.h> -#include <asm-xen/ctrl_if.h> #include <asm-xen/balloon.h> #include <asm/pgalloc.h> #include <asm/pgtable.h> @@ -50,6 +50,10 @@ #include <asm/tlb.h> #include <linux/list.h> +#include<asm-xen/xenbus.h> + +#define PAGES2KB(_p) ((_p)<<(PAGE_SHIFT-10)) + static struct proc_dir_entry *balloon_pde; static DECLARE_MUTEX(balloon_mutex); @@ -77,11 +81,17 @@ static DECLARE_WORK(balloon_worker, balloon_process, NULL); static struct timer_list balloon_timer; +/* Flag for dom0 xenstore workaround */ +static int balloon_xenbus_init=0; + +/* Init Function */ +void balloon_init_watcher(void); + #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) /* Use the private and mapping fields of struct page as a list. */ #define PAGE_TO_LIST(p) ( (struct list_head *)&p->private ) #define LIST_TO_PAGE(l) ( list_entry( ((unsigned long *)l), \ - struct page, private ) ) + struct page, private ) ) #define UNLIST_PAGE(p) do { list_del(PAGE_TO_LIST(p)); \ p->mapping = NULL; \ p->private = 0; } while(0) @@ -297,25 +307,96 @@ schedule_work(&balloon_worker); } -static void balloon_ctrlif_rx(ctrl_msg_t *msg, unsigned long id) -{ - switch ( msg->subtype ) - { - case CMSG_MEM_REQUEST_SET: - { - mem_request_t *req = (mem_request_t *)&msg->msg[0]; - set_new_target(req->target); - req->status = 0; - } - break; - - default: - msg->length = 0; - break; - } - - ctrl_if_send_response(msg); -} +static struct xenbus_watch xb_watch = +{ + .node = "memory" +}; + +/* FIXME: This is part of a dom0 sequencing workaround */ +static struct xenbus_watch root_watch = +{ + .node = "/" +}; + +/* React to a change in the target key */ +static void watch_target(struct xenbus_watch *watch, const char *node) +{ + unsigned long new_target; + int err; + + if(watch == &root_watch) + { + /* FIXME: This is part of a dom0 sequencing workaround */ + if(register_xenbus_watch(&xb_watch) == 0) + { + /* + We successfully set a watch on memory/target: + now we can stop watching root + */ + unregister_xenbus_watch(&root_watch); + balloon_xenbus_init=1; + } + else + { + return; + } + } + + err = xenbus_scanf("memory", "target", "%lu", &new_target); + + if(err != 1) + { + IPRINTK("Unable to read memory/target\n"); + return; + } + + set_new_target(new_target >> PAGE_SHIFT); + +} + +/* + Try to set up our watcher, if not already set + +*/ +void balloon_init_watcher(void) +{ + int err; + + if(!xen_start_info.store_evtchn) + { + IPRINTK("Delaying watcher init until xenstore is available\n"); + return; + } + + down(&xenbus_lock); + + if(! balloon_xenbus_init) + { + err = register_xenbus_watch(&xb_watch); + if(err) + { + /* BIG FAT FIXME: dom0 sequencing workaround + * dom0 can't set a watch on memory/target until + * after the tools create it. So, we have to watch + * the whole store until that happens. + * + * This will go away when we have the ability to watch + * non-existant keys + */ + register_xenbus_watch(&root_watch); + } + else + { + IPRINTK("Balloon xenbus watcher initialized\n"); + balloon_xenbus_init = 1; + } + } + + up(&xenbus_lock); + +} + +EXPORT_SYMBOL(balloon_init_watcher); static int balloon_write(struct file *file, const char __user *buffer, unsigned long count, void *data) @@ -346,7 +427,6 @@ { int len; -#define K(_p) ((_p)<<(PAGE_SHIFT-10)) len = sprintf( page, "Current allocation: %8lu kB\n" @@ -354,13 +434,14 @@ "Low-mem balloon: %8lu kB\n" "High-mem balloon: %8lu kB\n" "Xen hard limit: ", - K(current_pages), K(target_pages), K(balloon_low), K(balloon_high)); + PAGES2KB(current_pages), PAGES2KB(target_pages), + PAGES2KB(balloon_low), PAGES2KB(balloon_high)); if ( hard_limit != ~0UL ) len += sprintf( page + len, "%8lu kB (inc. %8lu kB driver headroom)\n", - K(hard_limit), K(driver_pages)); + PAGES2KB(hard_limit), PAGES2KB(driver_pages)); else len += sprintf( page + len, @@ -396,9 +477,7 @@ balloon_pde->read_proc = balloon_read; balloon_pde->write_proc = balloon_write; - - (void)ctrl_if_register_receiver(CMSG_MEM_REQUEST, balloon_ctrlif_rx, 0); - + /* Initialise the balloon with excess memory space. */ for ( pfn = xen_start_info.nr_pages; pfn < max_pfn; pfn++ ) { @@ -406,6 +485,11 @@ if ( !PageReserved(page) ) balloon_append(page); } + + xb_watch.callback = watch_target; + root_watch.callback = watch_target; + + balloon_init_watcher(); return 0; } diff -r 9be7fe98a556 -r e173a853dc46 linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c --- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c Tue Aug 2 10:47:41 2005 +++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c Tue Aug 2 17:20:46 2005 @@ -309,6 +309,9 @@ return err; } + /* Initialize non-xenbus drivers */ + balloon_init_watcher(); + down(&xenbus_lock); /* Enumerate devices in xenstore. */ xenbus_probe_devices("device"); diff -r 9be7fe98a556 -r e173a853dc46 linux-2.6-xen-sparse/mm/memory.c --- a/linux-2.6-xen-sparse/mm/memory.c Tue Aug 2 10:47:41 2005 +++ b/linux-2.6-xen-sparse/mm/memory.c Tue Aug 2 17:20:46 2005 @@ -1814,12 +1814,12 @@ page_add_anon_rmap(page, vma, addr); } - set_pte_at(vma, addr, page_table, entry); + set_pte_at(mm, addr, page_table, entry); pte_unmap(page_table); /* No need to invalidate - it was non-present before */ update_mmu_cache(vma, addr, entry); - lazy_mmu_prot_update(entry); + lazy_mmu_prot_update(entry); spin_unlock(&mm->page_table_lock); out: return VM_FAULT_MINOR; @@ -1928,7 +1928,7 @@ entry = mk_pte(new_page, vma->vm_page_prot); if (write_access) entry = maybe_mkwrite(pte_mkdirty(entry), vma); - set_pte_at(vma, address, page_table, entry); + set_pte_at(mm, address, page_table, entry); if (anon) { lru_cache_add_active(new_page); page_add_anon_rmap(new_page, vma, address); diff -r 9be7fe98a556 -r e173a853dc46 tools/Makefile --- a/tools/Makefile Tue Aug 2 10:47:41 2005 +++ b/tools/Makefile Tue Aug 2 17:20:46 2005 @@ -10,9 +10,10 @@ SUBDIRS += python SUBDIRS += xcs SUBDIRS += xcutils -SUBDIRS += pygrub +#SUBDIRS += pygrub SUBDIRS += firmware -SUBDIRS += policy +SUBDIRS += security +#SUBDIRS += consoled .PHONY: all install clean check check_clean ioemu eioemuinstall ioemuclean diff -r 9be7fe98a556 -r e173a853dc46 tools/Rules.mk --- a/tools/Rules.mk Tue Aug 2 10:47:41 2005 +++ b/tools/Rules.mk Tue Aug 2 17:20:46 2005 @@ -4,6 +4,8 @@ XEN_XC = $(XEN_ROOT)/tools/python/xen/lowlevel/xc XEN_LIBXC = $(XEN_ROOT)/tools/libxc +XEN_XCS = $(XEN_ROOT)/tools/xcs +XEN_XENSTORE = $(XEN_ROOT)/tools/xenstore ifeq ($(XEN_TARGET_ARCH),x86_32) CFLAGS += -m32 -march=i686 diff -r 9be7fe98a556 -r e173a853dc46 tools/misc/policyprocessor/XmlToBin.java --- a/tools/misc/policyprocessor/XmlToBin.java Tue Aug 2 10:47:41 2005 +++ b/tools/misc/policyprocessor/XmlToBin.java Tue Aug 2 17:20:46 2005 @@ -4,6 +4,9 @@ * $Id: XmlToBin.java,v 1.3 2005/06/20 21:07:37 rvaldez Exp $ * * Author: Ray Valdez + * + * Contributors: + * Reiner Sailer - adjust type-lengths * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -490,175 +493,139 @@ try { - /* Write magic */ - writeIntToStream(binBuffer,ACM_MAGIC,index); - index = u32Size; - - /* Write policy version */ - writeIntToStream(binBuffer,POLICY_INTERFACE_VERSION,index); - index = index + u32Size; - - /* write len */ - writeIntToStream(binBuffer,binBuffer.length,index); - index = index + u32Size; + index = 0; + /* fill in General Policy Version */ + writeIntToStream(binBuffer, ACM_POLICY_VERSION, index); + index += u32Size; + + /* Write magic */ + writeIntToStream(binBuffer, ACM_MAGIC, index); + index += u32Size; + + /* write len */ + writeIntToStream(binBuffer, binBuffer.length, index); + index += u32Size; } catch (IOException ee) { - System.out.println(" GBPB:: got exception : " + ee); - return null; + System.out.println(" GBPB:: got exception : " + ee); + return null; } int offset, address; address = index; if (null != partMap) - offset = binaryBufferHeaderSz + resourceOffsetSz; + offset = binaryBufferHeaderSz + resourceOffsetSz; else - offset = binaryBufferHeaderSz; + offset = binaryBufferHeaderSz; try { - - if (null == chwPolicy || null == stePolicy) - { - writeShortToStream(binBuffer,ACM_NULL_POLICY,index); - index = index + u16Size; - - writeShortToStream(binBuffer,(short) 0,index); - index = index + u16Size; - - writeShortToStream(binBuffer,ACM_NULL_POLICY,index); - index = index + u16Size; - - writeShortToStream(binBuffer,(short) 0,index); - index = index + u16Size; - - } - index = address; - if (null != chwPolicy) - { + int skip = 0; + + /* init with NULL policy setting */ + writeIntToStream(binBuffer, ACM_NULL_POLICY, index); + writeIntToStream(binBuffer, 0, index + u32Size); + writeIntToStream(binBuffer, ACM_NULL_POLICY, index + 2*u32Size); + writeIntToStream(binBuffer, 0, index + 3*u32Size); - /* Write policy name */ - writeShortToStream(binBuffer,ACM_CHINESE_WALL_POLICY,index); - index = index + u16Size; - - /* Write offset */ - writeShortToStream(binBuffer,(short) offset,index); - index = index + u16Size; - - /* Write payload. No need increment index */ - address = offset; - System.arraycopy(chwPolicy, 0, binBuffer,address, chwPolicy.length); - address = address + chwPolicy.length; + index = address; + if (null != chwPolicy) { + /* Write policy name */ + writeIntToStream(binBuffer, ACM_CHINESE_WALL_POLICY, index); + index += u32Size; + + /* Write offset */ + writeIntToStream(binBuffer, offset, index); + index += u32Size; + + /* Write payload. No need increment index */ + address = offset; + System.arraycopy(chwPolicy, 0, binBuffer,address, chwPolicy.length); + address = address + chwPolicy.length; + } else + skip += 2*u32Size; + if (null != stePolicy) { /* Write policy name */ - writeShortToStream(binBuffer,ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY,index); - index = index + u16Size; + writeIntToStream(binBuffer, ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, index); + index += u32Size; /* Write offset */ - writeShortToStream(binBuffer,(short) address,index); - index = index + u16Size; + writeIntToStream(binBuffer, address, index); + index += u32Size; /* Copy array */ System.arraycopy(stePolicy, 0, binBuffer,address, stePolicy.length); /* Update address */ address = address + stePolicy.length; + } else + skip += 2*u32Size; + + /* Skip writing policy name and offset for each null policy*/ + index += skip; + + int size; + /* Assumes that you will always have a partition defined in policy */ + if ( 0 < partMap.length) { + writeIntToStream(binBuffer, address, index); + index = address; + + /* Compute num of VMs */ + size = partMap.length / (3 * u16Size); + + writeShortToStream(binBuffer, (short)size,index); + index = index + u16Size; + + /* part, vlan and slot: each one consists of two entries */ + offset = 3 * (2 * u16Size); + writeShortToStream(binBuffer, (short) offset,index); + + /* Write partition array at offset */ + System.arraycopy(partMap, 0, binBuffer,(offset + address), partMap.length); + index = index + u16Size; + offset = offset + partMap.length; + } + + if ( 0 < vlanMap.length) { + size = vlanMap.length / (2 * u16Size); + writeShortToStream(binBuffer, (short) size,index); + index = index + u16Size; + + writeShortToStream(binBuffer, (short) offset,index); + index = index + u16Size; + System.arraycopy(vlanMap, 0, binBuffer,(offset + address), vlanMap.length); } else { - /* Skip writing policy name and offset */ - index = index + 2 * u16Size; - - } - - } else { - - if (null != stePolicy) - { - /* Write policy name */ - writeShortToStream(binBuffer,ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY,index); - index = index + u16Size; - - /* Write offset */ - address = offset; - writeShortToStream(binBuffer, (short) offset,index); - index = index + u16Size; - - /* Copy array */ - System.arraycopy(stePolicy, 0, binBuffer,address, stePolicy.length); - /* Update address */ - address = address + stePolicy.length; - - /* Increment index, since there is no secondary */ - index = index + secondaryPolicyCodeSz + secondaryBufferOffsetSz; - - } - - } - int size; - /* Assumes that you will always have a partition defined in policy */ - if ( 0 < partMap.length) - { - writeShortToStream(binBuffer, (short) address,index); - index = address; - - /* Compute num of VMs */ - size = partMap.length / (3 * u16Size); - - writeShortToStream(binBuffer, (short)size,index); - index = index + u16Size; - - /* part, vlan and slot: each one consists of two entries */ - offset = 3 * (2 * u16Size); - writeShortToStream(binBuffer, (short) offset,index); - - /* Write partition array at offset */ - System.arraycopy(partMap, 0, binBuffer,(offset + address), partMap.length); - index = index + u16Size; - offset = offset + partMap.length; - } - - if ( 0 < vlanMap.length) - { - size = vlanMap.length / (2 * u16Size); - writeShortToStream(binBuffer, (short) size,index); - index = index + u16Size; - - writeShortToStream(binBuffer, (short) offset,index); - index = index + u16Size; - System.arraycopy(vlanMap, 0, binBuffer,(offset + address), vlanMap.length); - } else { - /* Write vlan max */ - writeShortToStream(binBuffer, (short) 0,index); - index = index + u16Size; + /* Write vlan max */ + writeShortToStream(binBuffer, (short) 0,index); + index = index + u16Size; - /* Write vlan offset */ - writeShortToStream(binBuffer, (short) 0,index); - index = index + u16Size; - - } - - offset = offset + vlanMap.length; - if ( 0 < slotMap.length) - { - size = slotMap.length / (3 * u16Size); - writeShortToStream(binBuffer, (short) size,index); - index = index + u16Size; - - writeShortToStream(binBuffer, (short) offset,index); - index = index + u16Size; - System.arraycopy(slotMap, 0, binBuffer,(offset + address), slotMap.length); - } - - } catch (IOException ee) - { - System.out.println(" GBPB:: got exception : " + ee); - return null; - } - - printDebug(" GBP:: Binary Policy ==> length " + binBuffer.length); - if (debug) - printHex(binBuffer,binBuffer.length); - - return binBuffer; + /* Write vlan offset */ + writeShortToStream(binBuffer, (short) 0,index); + index = index + u16Size; + } + + offset = offset + vlanMap.length; + if ( 0 < slotMap.length) { + size = slotMap.length / (3 * u16Size); + writeShortToStream(binBuffer, (short) size,index); + index = index + u16Size; + + writeShortToStream(binBuffer, (short) offset,index); + index = index + u16Size; + System.arraycopy(slotMap, 0, binBuffer,(offset + address), slotMap.length); + } + } catch (IOException ee) { + System.out.println(" GBPB:: got exception : " + ee); + return null; + } + + printDebug(" GBP:: Binary Policy ==> length " + binBuffer.length); + if (debug) + printHex(binBuffer,binBuffer.length); + + return binBuffer; } public byte[] generateChwBuffer(Vector Ssids, Vector ConflictSsids, Vector ColorTypes) @@ -668,28 +635,20 @@ int position = 0; /* Get number of rTypes */ - short maxTypes = (short) ColorTypes.size(); + int maxTypes = ColorTypes.size(); /* Get number of SSids entry */ - short maxSsids = (short) Ssids.size(); + int maxSsids = Ssids.size(); /* Get number of conflict sets */ - short maxConflict = (short) ConflictSsids.size(); + int maxConflict = ConflictSsids.size(); if (maxTypes * maxSsids == 0) return null; /* - data structure acm_chwall_policy_buffer_t; - - uint16 policy_code; - uint16 chwall_max_types; - uint16 chwall_max_ssidrefs; - uint16 chwall_max_conflictsets; - uint16 chwall_ssid_offset; - uint16 chwall_conflict_sets_offset; - uint16 chwall_running_types_offset; - uint16 chwall_conflict_aggregate_offset; + data structure acm_chwall_policy_buffer + se XmlToBinInterface.java */ int totalBytes = chwHeaderSize + u16Size *(maxTypes * (maxSsids + maxConflict)); @@ -699,34 +658,38 @@ printDebug(" gCB:: chwall totalbytes : "+totalBytes); try { - index = 0; - writeShortToStream(chwBuffer,ACM_CHINESE_WALL_POLICY,index); - index = u16Size; - - writeShortToStream(chwBuffer,maxTypes,index); - index = index + u16Size; - - writeShortToStream(chwBuffer,maxSsids,index); - index = index + u16Size; - - writeShortToStream(chwBuffer,maxConflict,index); - index = index + u16Size; - - /* Write chwall_ssid_offset */ - writeShortToStream(chwBuffer,chwHeaderSize,index); - index = index + u16Size; - - /* Write chwall_conflict_sets_offset */ - writeShortToStream(chwBuffer,(short) address,index); - index = index + u16Size; - - /* Write chwall_running_types_offset */ - writeShortToStream(chwBuffer,(short) 0,index); - index = index + u16Size; - - /* Write chwall_conflict_aggregate_offset */ - writeShortToStream(chwBuffer,(short) 0,index); - index = index + u16Size; + index = 0; + /* fill in General Policy Version */ + writeIntToStream(chwBuffer, ACM_CHWALL_VERSION, index); + index += u32Size; + + writeIntToStream(chwBuffer, ACM_CHINESE_WALL_POLICY, index); + index += u32Size; + + writeIntToStream(chwBuffer, maxTypes, index); + index += u32Size; + + writeIntToStream(chwBuffer, maxSsids, index); + index += u32Size; + + writeIntToStream(chwBuffer, maxConflict, index); + index += u32Size; + + /* Write chwall_ssid_offset */ + writeIntToStream(chwBuffer, chwHeaderSize, index); + index += u32Size; + + /* Write chwall_conflict_sets_offset */ + writeIntToStream(chwBuffer, address, index); + index += u32Size; + + /* Write chwall_running_types_offset */ + writeIntToStream(chwBuffer, 0, index); + index += u32Size; + + /* Write chwall_conflict_aggregate_offset */ + writeIntToStream(chwBuffer, 0, index); + index += u32Size; } catch (IOException ee) { System.out.println(" gCB:: got exception : " + ee); @@ -737,7 +700,6 @@ /* Create the SSids entry */ for (int i = 0; i < maxSsids; i++) { - SecurityLabel ssidEntry = (SecurityLabel) Ssids.elementAt(i); /* Get chwall types */ ssidEntry.chwSsidPosition = i; @@ -821,22 +783,16 @@ int position = 0; /* Get number of colorTypes */ - short numColorTypes = (short) ColorTypes.size(); + int numColorTypes = ColorTypes.size(); /* Get number of SSids entry */ - short numSsids = (short) Ssids.size(); + int numSsids = Ssids.size(); if (numColorTypes * numSsids == 0) return null; - /* data structure: acm_ste_policy_buffer_t - * - * policy code (uint16) > - * max_types (uint16) > - * max_ssidrefs (uint16) > steHeaderSize - * ssid_offset (uint16) > - * DATA (colorTypes(size) * Ssids(size) *unit16) - * + /* data structure: acm_ste_policy_buffer + * see XmlToBinInterface.java * total bytes: steHeaderSize * 2B + colorTypes(size) * Ssids(size) * */ @@ -844,18 +800,22 @@ try { - index = 0; - writeShortToStream(steBuffer,ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY,index); - index = u16Size; - - writeShortToStream(steBuffer,numColorTypes,index); - index = index + u16Size; - - writeShortToStream(steBuffer,numSsids,index); - index = index + u16Size; - - writeShortToStream(steBuffer,(short)steHeaderSize,index); - index = index + u16Size; + index = 0; + writeIntToStream(steBuffer, ACM_STE_VERSION, index); + index += u32Size; + + writeIntToStream(steBuffer, ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, index); + index += u32Size; + + writeIntToStream(steBuffer, numColorTypes, index); + index += u32Size; + + writeIntToStream(steBuffer, numSsids, index); + index += u32Size; + + writeIntToStream(steBuffer, steHeaderSize, index); + index += u32Size; + } catch (IOException ee) { System.out.println(" gSB:: got exception : " + ee); @@ -1469,6 +1429,17 @@ XmlToBin genObj = new XmlToBin(); + policy_version active_policy = new policy_version(); + + if ((active_policy.ACM_POLICY_VERSION != ACM_POLICY_VERSION) || + (active_policy.ACM_CHWALL_VERSION != ACM_CHWALL_VERSION) || + (active_policy.ACM_STE_VERSION != ACM_STE_VERSION)) { + System.out.println("ACM policy versions differ."); + System.out.println("Please verify that data structures are correct"); + System.out.println("and then adjust the version numbers in XmlToBinInterface.java."); + return; + } + for (int i = 0 ; i < args.length ; i++) { diff -r 9be7fe98a556 -r e173a853dc46 tools/misc/policyprocessor/XmlToBinInterface.java --- a/tools/misc/policyprocessor/XmlToBinInterface.java Tue Aug 2 10:47:41 2005 +++ b/tools/misc/policyprocessor/XmlToBinInterface.java Tue Aug 2 17:20:46 2005 @@ -19,37 +19,37 @@ * * policy binary structures * - * typedef struct { - * u32 magic; + * struct acm_policy_buffer { + * u32 policy_version; * ACM_POLICY_VERSION * + * u32 magic; + * u32 len; + * u32 primary_policy_code; + * u32 primary_buffer_offset; + * u32 secondary_policy_code; + * u32 secondary_buffer_offset; + * +u32 resource offset (not used yet in Xen) + * }; * - * u32 policyversion; - * u32 len; * - * u16 primary_policy_code; - * u16 primary_buffer_offset; - * u16 secondary_policy_code; - * u16 secondary_buffer_offset; - * u16 resource_offset; + * struct acm_ste_policy_buffer { + * u32 policy_version; * ACM_STE_VERSION * + * u32 policy_code; + * u32 ste_max_types; + * u32 ste_max_ssidrefs; + * u32 ste_ssid_offset; + * }; * - * } acm_policy_buffer_t; - * - * typedef struct { - * u16 policy_code; - * u16 ste_max_types; - * u16 ste_max_ssidrefs; - * u16 ste_ssid_offset; - * } acm_ste_policy_buffer_t; - * - * typedef struct { - * uint16 policy_code; - * uint16 chwall_max_types; - * uint16 chwall_max_ssidrefs; - * uint16 chwall_max_conflictsets; - * uint16 chwall_ssid_offset; - * uint16 chwall_conflict_sets_offset; - * uint16 chwall_running_types_offset; - * uint16 chwall_conflict_aggregate_offset; - * } acm_chwall_policy_buffer_t; + * struct acm_chwall_policy_buffer { + * u32 policy_version; * ACM_CHWALL_VERSION * + * u32 policy_code; + * u32 chwall_max_types; + * u32 chwall_max_ssidrefs; + * u32 chwall_max_conflictsets; + * u32 chwall_ssid_offset; + * u32 chwall_conflict_sets_offset; + * u32 chwall_running_types_offset; + * u32 chwall_conflict_aggregate_offset; + * }; * * typedef struct { * u16 partition_max; @@ -100,16 +100,17 @@ final int u16Size = 2; /* num of bytes for acm_ste_policy_buffer_t */ - final short steHeaderSize = (4 * u16Size); + final int steHeaderSize = (5 * u32Size); + /* byte for acm_chinese_wall_policy_buffer_t */ - final short chwHeaderSize = (8 * u16Size); + final int chwHeaderSize = (9 * u32Size); - final short primaryPolicyCodeSize = u16Size; - final short primaryBufferOffsetSize = u16Size ; + final int primaryPolicyCodeSize = u32Size; + final int primaryBufferOffsetSize = u32Size ; - final int secondaryPolicyCodeSz = u16Size; - final int secondaryBufferOffsetSz = u16Size; - final short resourceOffsetSz = u16Size; + final int secondaryPolicyCodeSz = u32Size; + final int secondaryBufferOffsetSz = u32Size; + final int resourceOffsetSz = u32Size; final short partitionBufferSz = (2 * u16Size); final short partitionEntrySz = (3 * u16Size); @@ -120,16 +121,18 @@ final short vlanBufferSz = (2 * u16Size); final short vlanEntrySz = (2 * u16Size); - final short binaryBufferHeaderSz = (3 * u32Size + 4* u16Size); - - /* copied directlty from policy_ops.h */ - final int POLICY_INTERFACE_VERSION = 0xAAAA0003; + final int binaryBufferHeaderSz = (8 * u32Size); /* 8th not used in Xen */ /* copied directly from acm.h */ final int ACM_MAGIC = 0x0001debc; - final short ACM_NULL_POLICY = 0; - final short ACM_CHINESE_WALL_POLICY = 1; - final short ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY = 2; - final short ACM_CHINESE_WALL_AND_SIMPLE_TYPE_ENFORCEMENT_POLICY = 3; - final short ACM_EMPTY_POLICY = 4; + final int ACM_NULL_POLICY = 0; + final int ACM_CHINESE_WALL_POLICY = 1; + final int ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY = 2; + final int ACM_CHINESE_WALL_AND_SIMPLE_TYPE_ENFORCEMENT_POLICY = 3; + final int ACM_EMPTY_POLICY = 4; + + /* version for compatibility check */ + final int ACM_POLICY_VERSION = 1; + final int ACM_STE_VERSION = 1; + final int ACM_CHWALL_VERSION = 1; } diff -r 9be7fe98a556 -r e173a853dc46 tools/misc/policyprocessor/xen_sample_def.xml --- a/tools/misc/policyprocessor/xen_sample_def.xml Tue Aug 2 10:47:41 2005 +++ b/tools/misc/policyprocessor/xen_sample_def.xml Tue Aug 2 17:20:46 2005 @@ -37,7 +37,7 @@ </ConflictSet> <ConflictSet> - <ChWall>Q-Company</ChWall> + <ChWall>R-Company</ChWall> <ChWall>V-Company</ChWall> <ChWall>W-Company</ChWall> </ConflictSet> diff -r 9be7fe98a556 -r e173a853dc46 tools/pygrub/setup.py --- a/tools/pygrub/setup.py Tue Aug 2 10:47:41 2005 +++ b/tools/pygrub/setup.py Tue Aug 2 17:20:46 2005 @@ -23,7 +23,7 @@ fsys_pkgs.append("grub.fsys.reiser") setup(name='pygrub', - version='0.2', + version='0.3', description='Boot loader that looks a lot like grub for Xen', author='Jeremy Katz', author_email='katzj@xxxxxxxxxx', diff -r 9be7fe98a556 -r e173a853dc46 tools/pygrub/src/fsys/ext2/__init__.py --- a/tools/pygrub/src/fsys/ext2/__init__.py Tue Aug 2 10:47:41 2005 +++ b/tools/pygrub/src/fsys/ext2/__init__.py Tue Aug 2 17:20:46 2005 @@ -32,7 +32,7 @@ def open_fs(self, fn, offset = 0): if not self.sniff_magic(fn, offset): raise ValueError, "Not an ext2 filesystem" - return Ext2Fs(fn) + return Ext2Fs(fn, offset = offset) register_fstype(Ext2FileSystemType()) diff -r 9be7fe98a556 -r e173a853dc46 tools/pygrub/src/fsys/ext2/ext2module.c --- a/tools/pygrub/src/fsys/ext2/ext2module.c Tue Aug 2 10:47:41 2005 +++ b/tools/pygrub/src/fsys/ext2/ext2module.c Tue Aug 2 17:20:46 2005 @@ -208,23 +208,29 @@ ext2_fs_open (Ext2Fs *fs, PyObject *args, PyObject *kwargs) { static char *kwlist[] = { "name", "flags", "superblock", - "block_size", NULL }; + "block_size", "offset", NULL }; char * name; - int flags = 0, superblock = 0, err; + int flags = 0, superblock = 0, offset = 0, err; unsigned int block_size = 0; ext2_filsys efs; - - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|iii", kwlist, - &name, &flags, &superblock, &block_size)) - return NULL; + char offsetopt[30]; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|iiii", kwlist, + &name, &flags, &superblock, + &block_size, &offset)) + return NULL; if (fs->fs != NULL) { PyErr_SetString(PyExc_ValueError, "already have an fs object"); return NULL; } - err = ext2fs_open(name, flags, superblock, block_size, - unix_io_manager, &efs); + if (offset != 0) { + snprintf(offsetopt, 29, "offset=%d", offset); + } + + err = ext2fs_open2(name, offsetopt, flags, superblock, block_size, + unix_io_manager, &efs); if (err) { PyErr_SetString(PyExc_ValueError, "unable to open file"); return NULL; @@ -323,14 +329,15 @@ ext2_fs_new(PyObject *o, PyObject *args, PyObject *kwargs) { static char *kwlist[] = { "name", "flags", "superblock", - "block_size", NULL }; + "block_size", "offset", NULL }; char * name; - int flags = 0, superblock = 0; + int flags = 0, superblock = 0, offset; unsigned int block_size = 0; Ext2Fs *pfs; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|iii", kwlist, - &name, &flags, &superblock, &block_size)) + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|iiii", kwlist, + &name, &flags, &superblock, &block_size, + &offset)) return NULL; pfs = (Ext2Fs *) PyObject_NEW(Ext2Fs, &Ext2FsType); @@ -339,8 +346,8 @@ pfs->fs = NULL; if (!ext2_fs_open(pfs, - Py_BuildValue("siii", name, flags, superblock, block_size), - NULL)) + Py_BuildValue("siiii", name, flags, superblock, + block_size, offset), NULL)) return NULL; return (PyObject *)pfs; diff -r 9be7fe98a556 -r e173a853dc46 tools/pygrub/src/pygrub --- a/tools/pygrub/src/pygrub Tue Aug 2 10:47:41 2005 +++ b/tools/pygrub/src/pygrub Tue Aug 2 17:20:46 2005 @@ -24,7 +24,7 @@ import grub.GrubConf import grub.fsys -PYGRUB_VER = 0.02 +PYGRUB_VER = 0.3 def draw_window(): @@ -77,9 +77,21 @@ buf = os.read(fd, 512) os.close(fd) - if len(buf) >= 512 and struct.unpack("H", buf[0x1fe: 0x200]) == (0xaaff): + if len(buf) >= 512 and struct.unpack("H", buf[0x1fe: 0x200]) == (0xaa55,): return True return False + +SECTOR_SIZE=512 +def get_active_offset(file): + """Find the offset for the start of the first active partition in the + disk image file.""" + fd = os.open(file, os.O_RDONLY) + buf = os.read(fd, 512) + for poff in (446, 462, 478, 494): # partition offsets + # active partition has 0x80 as the first byte + if struct.unpack("<c", buf[p:p+1]) == ('\x80',): + return struct.unpack("<", buf[p+8:p+12])[0] * SECTOR_SIZE + return -1 def get_config(fn): if not os.access(fn, os.R_OK): @@ -87,14 +99,17 @@ cf = grub.GrubConf.GrubConfigFile() + offset = 0 if is_disk_image(fn): - raise RuntimeError, "appears to be a full disk image... unable to handle this yet" + offset = get_active_offset(fn) + if offset == -1: + raise RuntimeError, "Unable to find active partition on disk" # open the image and read the grub config fs = None for fstype in grub.fsys.fstypes.values(): - if fstype.sniff_magic(fn): - fs = fstype.open_fs(fn) + if fstype.sniff_magic(fn, offset): + fs = fstype.open_fs(fn, offset) break if fs is not None: @@ -244,14 +259,17 @@ if img.initrd: print " initrd: %s" %(img.initrd[1],) + offset = 0 if is_disk_image(file): - raise RuntimeError, "unable to handle full disk images yet" + offset = get_active_offset(fn) + if offset == -1: + raise RuntimeError, "Unable to find active partition on disk" # read the kernel and initrd onto the hostfs fs = None for fstype in grub.fsys.fstypes.values(): - if fstype.sniff_magic(file): - fs = fstype.open_fs(file) + if fstype.sniff_magic(file, offset): + fs = fstype.open_fs(file, offset) break if fs is None: diff -r 9be7fe98a556 -r e173a853dc46 tools/python/xen/util/blkif.py --- a/tools/python/xen/util/blkif.py Tue Aug 2 10:47:41 2005 +++ b/tools/python/xen/util/blkif.py Tue Aug 2 17:20:46 2005 @@ -24,14 +24,17 @@ log.debug("exception looking up device number for %s: %s", name, ex) pass - if re.match( '/dev/sd[a-p]([0-9]|1[0-5])', n): - return 8 * 256 + 16 * (ord(n[7:8]) - ord('a')) + int(n[8:]) + if re.match( '/dev/sd[a-p]([1-9]|1[0-5])?', n): + return 8 * 256 + 16 * (ord(n[7:8]) - ord('a')) + int(n[8:] or 0) if re.match( '/dev/hd[a-t]([1-9]|[1-5][0-9]|6[0-3])?', n): ide_majors = [ 3, 22, 33, 34, 56, 57, 88, 89, 90, 91 ] major = ide_majors[(ord(n[7:8]) - ord('a')) / 2] minor = ((ord(n[7:8]) - ord('a')) % 2) * 64 + int(n[8:] or 0) return major * 256 + minor + + if re.match( '/dev/xvd[a-p]([1-9]|1[0-5])?', n): + return 202 * 256 + 16 * (ord(n[8:9]) - ord('a')) + int(n[9:] or 0) # see if this is a hex device number if re.match( '^(0x)?[0-9a-fA-F]+$', name ): diff -r 9be7fe98a556 -r e173a853dc46 tools/python/xen/xend/XendDomainInfo.py --- a/tools/python/xen/xend/XendDomainInfo.py Tue Aug 2 10:47:41 2005 +++ b/tools/python/xen/xend/XendDomainInfo.py Tue Aug 2 17:20:46 2005 @@ -152,6 +152,9 @@ vm = cls(db) vm.construct(config) vm.saveToDB(sync=True) + # Flush info to xenstore immediately + vm.exportToDB() + return vm create = classmethod(create) @@ -172,6 +175,7 @@ log.debug('config=' + prettyprintstring(config)) vm.memory = info['mem_kb']/1024 + vm.target = info['mem_kb'] * 1024 if config: try: @@ -222,6 +226,7 @@ DBVar('restart_state', ty='str'), DBVar('restart_time', ty='float'), DBVar('restart_count', ty='int'), + DBVar('target', ty='long', path="memory/target"), ] def __init__(self, db): @@ -239,6 +244,8 @@ self.memory = None self.ssidref = None self.image = None + + self.target = None self.channel = None self.store_channel = None @@ -315,6 +322,7 @@ self.info = info self.memory = self.info['mem_kb'] / 1024 self.ssidref = self.info['ssidref'] + self.target = self.info['mem_kb'] * 1024 def state_set(self, state): self.state_updated.acquire() @@ -399,7 +407,8 @@ ['id', self.id], ['name', self.name], ['memory', self.memory], - ['ssidref', self.ssidref] ] + ['ssidref', self.ssidref], + ['target', self.target] ] if self.uuid: sxpr.append(['uuid', self.uuid]) if self.info: @@ -536,6 +545,7 @@ self.memory = int(sxp.child_value(config, 'memory')) if self.memory is None: raise VmError('missing memory size') + self.target = self.memory * (1 << 20) self.ssidref = int(sxp.child_value(config, 'ssidref')) cpu = sxp.child_value(config, 'cpu') if self.recreate and self.id and cpu is not None and int(cpu) >= 0: @@ -947,11 +957,12 @@ index[field_name] = field_index + 1 def mem_target_set(self, target): - """Set domain memory target in pages. - """ - if self.channel: - msg = messages.packMsg('mem_request_t', { 'target' : target * (1 << 8)} ) - self.channel.writeRequest(msg) + """Set domain memory target in bytes. + """ + if target: + self.target = target * (1 << 20) + # Commit to XenStore immediately + self.exportToDB() def vcpu_hotplug(self, vcpu, state): """Disable or enable VCPU in domain. diff -r 9be7fe98a556 -r e173a853dc46 xen/acm/acm_chinesewall_hooks.c --- a/xen/acm/acm_chinesewall_hooks.c Tue Aug 2 10:47:41 2005 +++ b/xen/acm/acm_chinesewall_hooks.c Tue Aug 2 17:20:46 2005 @@ -110,45 +110,45 @@ struct acm_chwall_policy_buffer *chwall_buf = (struct acm_chwall_policy_buffer *)buf; int ret = 0; - chwall_buf->chwall_max_types = htons(chwall_bin_pol.max_types); - chwall_buf->chwall_max_ssidrefs = htons(chwall_bin_pol.max_ssidrefs); - chwall_buf->policy_code = htons(ACM_CHINESE_WALL_POLICY); - chwall_buf->chwall_ssid_offset = htons(sizeof(struct acm_chwall_policy_buffer)); - chwall_buf->chwall_max_conflictsets = htons(chwall_bin_pol.max_conflictsets); + chwall_buf->chwall_max_types = htonl(chwall_bin_pol.max_types); + chwall_buf->chwall_max_ssidrefs = htonl(chwall_bin_pol.max_ssidrefs); + chwall_buf->policy_code = htonl(ACM_CHINESE_WALL_POLICY); + chwall_buf->chwall_ssid_offset = htonl(sizeof(struct acm_chwall_policy_buffer)); + chwall_buf->chwall_max_conflictsets = htonl(chwall_bin_pol.max_conflictsets); chwall_buf->chwall_conflict_sets_offset = - htons( - ntohs(chwall_buf->chwall_ssid_offset) + + htonl( + ntohl(chwall_buf->chwall_ssid_offset) + sizeof(domaintype_t) * chwall_bin_pol.max_ssidrefs * chwall_bin_pol.max_types); chwall_buf->chwall_running_types_offset = - htons( - ntohs(chwall_buf->chwall_conflict_sets_offset) + + htonl( + ntohl(chwall_buf->chwall_conflict_sets_offset) + sizeof(domaintype_t) * chwall_bin_pol.max_conflictsets * chwall_bin_pol.max_types); chwall_buf->chwall_conflict_aggregate_offset = - htons( - ntohs(chwall_buf->chwall_running_types_offset) + + htonl( + ntohl(chwall_buf->chwall_running_types_offset) + sizeof(domaintype_t) * chwall_bin_pol.max_types); - ret = ntohs(chwall_buf->chwall_conflict_aggregate_offset) + + ret = ntohl(chwall_buf->chwall_conflict_aggregate_offset) + sizeof(domaintype_t) * chwall_bin_pol.max_types; /* now copy buffers over */ - arrcpy16((u16 *)(buf + ntohs(chwall_buf->chwall_ssid_offset)), + arrcpy16((u16 *)(buf + ntohl(chwall_buf->chwall_ssid_offset)), chwall_bin_pol.ssidrefs, chwall_bin_pol.max_ssidrefs * chwall_bin_pol.max_types); - arrcpy16((u16 *)(buf + ntohs(chwall_buf->chwall_conflict_sets_offset)), + arrcpy16((u16 *)(buf + ntohl(chwall_buf->chwall_conflict_sets_offset)), chwall_bin_pol.conflict_sets, chwall_bin_pol.max_conflictsets * chwall_bin_pol.max_types); - arrcpy16((u16 *)(buf + ntohs(chwall_buf->chwall_running_types_offset)), + arrcpy16((u16 *)(buf + ntohl(chwall_buf->chwall_running_types_offset)), chwall_bin_pol.running_types, chwall_bin_pol.max_types); - arrcpy16((u16 *)(buf + ntohs(chwall_buf->chwall_conflict_aggregate_offset)), + arrcpy16((u16 *)(buf + ntohl(chwall_buf->chwall_conflict_aggregate_offset)), chwall_bin_pol.conflict_aggregate_set, chwall_bin_pol.max_types); return ret; @@ -226,14 +226,20 @@ void *ssids = NULL, *conflict_sets = NULL, *running_types = NULL, *conflict_aggregate_set = NULL; /* rewrite the policy due to endianess */ - chwall_buf->policy_code = ntohs(chwall_buf->policy_code); - chwall_buf->chwall_max_types = ntohs(chwall_buf->chwall_max_types); - chwall_buf->chwall_max_ssidrefs = ntohs(chwall_buf->chwall_max_ssidrefs); - chwall_buf->chwall_max_conflictsets = ntohs(chwall_buf->chwall_max_conflictsets); - chwall_buf->chwall_ssid_offset = ntohs(chwall_buf->chwall_ssid_offset); - chwall_buf->chwall_conflict_sets_offset = ntohs(chwall_buf->chwall_conflict_sets_offset); - chwall_buf->chwall_running_types_offset = ntohs(chwall_buf->chwall_running_types_offset); - chwall_buf->chwall_conflict_aggregate_offset = ntohs(chwall_buf->chwall_conflict_aggregate_offset); + chwall_buf->policy_code = ntohl(chwall_buf->policy_code); + chwall_buf->policy_version = ntohl(chwall_buf->policy_version); + chwall_buf->chwall_max_types = ntohl(chwall_buf->chwall_max_types); + chwall_buf->chwall_max_ssidrefs = ntohl(chwall_buf->chwall_max_ssidrefs); + chwall_buf->chwall_max_conflictsets = ntohl(chwall_buf->chwall_max_conflictsets); + chwall_buf->chwall_ssid_offset = ntohl(chwall_buf->chwall_ssid_offset); + chwall_buf->chwall_conflict_sets_offset = ntohl(chwall_buf->chwall_conflict_sets_offset); + chwall_buf->chwall_running_types_offset = ntohl(chwall_buf->chwall_running_types_offset); + chwall_buf->chwall_conflict_aggregate_offset = ntohl(chwall_buf->chwall_conflict_aggregate_offset); + + /* policy type and version checks */ + if ((chwall_buf->policy_code != ACM_CHINESE_WALL_POLICY) || + (chwall_buf->policy_version != ACM_CHWALL_VERSION)) + return -EINVAL; /* 1. allocate new buffers */ ssids = xmalloc_array(domaintype_t, chwall_buf->chwall_max_types*chwall_buf->chwall_max_ssidrefs); diff -r 9be7fe98a556 -r e173a853dc46 xen/acm/acm_core.c --- a/xen/acm/acm_core.c Tue Aug 2 10:47:41 2005 +++ b/xen/acm/acm_core.c Tue Aug 2 17:20:46 2005 @@ -120,7 +120,6 @@ if (ntohl(pol->magic) == ACM_MAGIC) { rc = acm_set_policy((void *)_policy_start, (u16)_policy_len, - ACM_USE_SECURITY_POLICY, 0); if (rc == ACM_OK) { printf("Policy len 0x%lx, start at %p.\n",_policy_len,_policy_start); diff -r 9be7fe98a556 -r e173a853dc46 xen/acm/acm_policy.c --- a/xen/acm/acm_policy.c Tue Aug 2 10:47:41 2005 +++ b/xen/acm/acm_policy.c Tue Aug 2 17:20:46 2005 @@ -6,9 +6,8 @@ * Author: * Reiner Sailer <sailer@xxxxxxxxxxxxxx> * - * Contributions: + * Contributors: * Stefan Berger <stefanb@xxxxxxxxxxxxxx> - * support for network-byte-order binary policies * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -27,29 +26,20 @@ #include <xen/lib.h> #include <xen/delay.h> #include <xen/sched.h> -#include <public/policy_ops.h> +#include <public/acm_ops.h> #include <acm/acm_core.h> #include <acm/acm_hooks.h> #include <acm/acm_endian.h> int -acm_set_policy(void *buf, u16 buf_size, u16 policy, int isuserbuffer) +acm_set_policy(void *buf, u16 buf_size, int isuserbuffer) { u8 *policy_buffer = NULL; struct acm_policy_buffer *pol; - if (policy != ACM_USE_SECURITY_POLICY) { - printk("%s: Loading incompatible policy (running: %s).\n", __func__, - ACM_POLICY_NAME(ACM_USE_SECURITY_POLICY)); - return -EFAULT; - } - /* now check correct buffer sizes for policy combinations */ - if (policy == ACM_NULL_POLICY) { - printkd("%s: NULL Policy, no policy needed.\n", __func__); - goto out; - } if (buf_size < sizeof(struct acm_policy_buffer)) return -EFAULT; + /* 1. copy buffer from domain */ if ((policy_buffer = xmalloc_array(u8, buf_size)) == NULL) goto error_free; @@ -58,17 +48,17 @@ printk("%s: Error copying!\n",__func__); goto error_free; } - } else { + } else memcpy(policy_buffer, buf, buf_size); - } + /* 2. some sanity checking */ pol = (struct acm_policy_buffer *)policy_buffer; if ((ntohl(pol->magic) != ACM_MAGIC) || - (ntohs(pol->primary_policy_code) != acm_bin_pol.primary_policy_code) || - (ntohs(pol->secondary_policy_code) != acm_bin_pol.secondary_policy_code) || - (ntohl(pol->policyversion) != POLICY_INTERFACE_VERSION)) { - printkd("%s: Wrong policy magics!\n", __func__); + (ntohl(pol->policy_version) != ACM_POLICY_VERSION) || + (ntohl(pol->primary_policy_code) != acm_bin_pol.primary_policy_code) || + (ntohl(pol->secondary_policy_code) != acm_bin_pol.secondary_policy_code)) { + printkd("%s: Wrong policy magics or versions!\n", __func__); goto error_free; } if (buf_size != ntohl(pol->len)) { @@ -79,21 +69,19 @@ /* get bin_policy lock and rewrite policy (release old one) */ write_lock(&acm_bin_pol_rwlock); - /* 3. now get/set primary policy data */ - if (acm_primary_ops->set_binary_policy(buf + ntohs(pol->primary_buffer_offset), - ntohs(pol->secondary_buffer_offset) - - ntohs(pol->primary_buffer_offset))) { + /* 3. set primary policy data */ + if (acm_primary_ops->set_binary_policy(buf + ntohl(pol->primary_buffer_offset), + ntohl(pol->secondary_buffer_offset) - + ntohl(pol->primary_buffer_offset))) { goto error_lock_free; } - /* 4. now get/set secondary policy data */ - if (acm_secondary_ops->set_binary_policy(buf + ntohs(pol->secondary_buffer_offset), + /* 4. set secondary policy data */ + if (acm_secondary_ops->set_binary_policy(buf + ntohl(pol->secondary_buffer_offset), ntohl(pol->len) - - ntohs(pol->secondary_buffer_offset))) { + ntohl(pol->secondary_buffer_offset))) { goto error_lock_free; } write_unlock(&acm_bin_pol_rwlock); - out: - printk("%s: Done .\n", __func__); if (policy_buffer != NULL) xfree(policy_buffer); return ACM_OK; @@ -121,26 +109,25 @@ /* future: read policy from file and set it */ bin_pol = (struct acm_policy_buffer *)policy_buffer; bin_pol->magic = htonl(ACM_MAGIC); - bin_pol->policyversion = htonl(POLICY_INTERFACE_VERSION); - bin_pol->primary_policy_code = htons(acm_bin_pol.primary_policy_code); - bin_pol->secondary_policy_code = htons(acm_bin_pol.secondary_policy_code); + bin_pol->primary_policy_code = htonl(acm_bin_pol.primary_policy_code); + bin_pol->secondary_policy_code = htonl(acm_bin_pol.secondary_policy_code); bin_pol->len = htonl(sizeof(struct acm_policy_buffer)); - bin_pol->primary_buffer_offset = htons(ntohl(bin_pol->len)); - bin_pol->secondary_buffer_offset = htons(ntohl(bin_pol->len)); + bin_pol->primary_buffer_offset = htonl(ntohl(bin_pol->len)); + bin_pol->secondary_buffer_offset = htonl(ntohl(bin_pol->len)); - ret = acm_primary_ops->dump_binary_policy (policy_buffer + ntohs(bin_pol->primary_buffer_offset), - buf_size - ntohs(bin_pol->primary_buffer_offset)); + ret = acm_primary_ops->dump_binary_policy (policy_buffer + ntohl(bin_pol->primary_buffer_offset), + buf_size - ntohl(bin_pol->primary_buffer_offset)); if (ret < 0) { printk("%s: ERROR creating chwallpolicy buffer.\n", __func__); read_unlock(&acm_bin_pol_rwlock); return -1; } bin_pol->len = htonl(ntohl(bin_pol->len) + ret); - bin_pol->secondary_buffer_offset = htons(ntohl(bin_pol->len)); + bin_pol->secondary_buffer_offset = htonl(ntohl(bin_pol->len)); - ret = acm_secondary_ops->dump_binary_policy(policy_buffer + ntohs(bin_pol->secondary_buffer_offset), - buf_size - ntohs(bin_pol->secondary_buffer_offset)); + ret = acm_secondary_ops->dump_binary_policy(policy_buffer + ntohl(bin_pol->secondary_buffer_offset), + buf_size - ntohl(bin_pol->secondary_buffer_offset)); if (ret < 0) { printk("%s: ERROR creating chwallpolicy buffer.\n", __func__); read_unlock(&acm_bin_pol_rwlock); @@ -178,11 +165,10 @@ goto error_lock_free; acm_stats.magic = htonl(ACM_MAGIC); - acm_stats.policyversion = htonl(POLICY_INTERFACE_VERSION); - acm_stats.primary_policy_code = htons(acm_bin_pol.primary_policy_code); - acm_stats.secondary_policy_code = htons(acm_bin_pol.secondary_policy_code); - acm_stats.primary_stats_offset = htons(sizeof(struct acm_stats_buffer)); - acm_stats.secondary_stats_offset = htons(sizeof(struct acm_stats_buffer) + len1); + acm_stats.primary_policy_code = htonl(acm_bin_pol.primary_policy_code); + acm_stats.secondary_policy_code = htonl(acm_bin_pol.secondary_policy_code); + acm_stats.primary_stats_offset = htonl(sizeof(struct acm_stats_buffer)); + acm_stats.secondary_stats_offset = htonl(sizeof(struct acm_stats_buffer) + len1); acm_stats.len = htonl(sizeof(struct acm_stats_buffer) + len1 + len2); memcpy(stats_buffer, &acm_stats, sizeof(struct acm_stats_buffer)); diff -r 9be7fe98a556 -r e173a853dc46 xen/acm/acm_simple_type_enforcement_hooks.c --- a/xen/acm/acm_simple_type_enforcement_hooks.c Tue Aug 2 10:47:41 2005 +++ b/xen/acm/acm_simple_type_enforcement_hooks.c Tue Aug 2 17:20:46 2005 @@ -140,15 +140,15 @@ struct acm_ste_policy_buffer *ste_buf = (struct acm_ste_policy_buffer *)buf; int ret = 0; - ste_buf->ste_max_types = htons(ste_bin_pol.max_types); - ste_buf->ste_max_ssidrefs = htons(ste_bin_pol.max_ssidrefs); - ste_buf->policy_code = htons(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY); - ste_buf->ste_ssid_offset = htons(sizeof(struct acm_ste_policy_buffer)); - ret = ntohs(ste_buf->ste_ssid_offset) + + ste_buf->ste_max_types = htonl(ste_bin_pol.max_types); + ste_buf->ste_max_ssidrefs = htonl(ste_bin_pol.max_ssidrefs); + ste_buf->policy_code = htonl(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY); + ste_buf->ste_ssid_offset = htonl(sizeof(struct acm_ste_policy_buffer)); + ret = ntohl(ste_buf->ste_ssid_offset) + sizeof(domaintype_t)*ste_bin_pol.max_ssidrefs*ste_bin_pol.max_types; /* now copy buffer over */ - arrcpy(buf + ntohs(ste_buf->ste_ssid_offset), + arrcpy(buf + ntohl(ste_buf->ste_ssid_offset), ste_bin_pol.ssidrefs, sizeof(domaintype_t), ste_bin_pol.max_ssidrefs*ste_bin_pol.max_types); @@ -276,10 +276,16 @@ int i; /* Convert endianess of policy */ - ste_buf->policy_code = ntohs(ste_buf->policy_code); - ste_buf->ste_max_types = ntohs(ste_buf->ste_max_types); - ste_buf->ste_max_ssidrefs = ntohs(ste_buf->ste_max_ssidrefs); - ste_buf->ste_ssid_offset = ntohs(ste_buf->ste_ssid_offset); + ste_buf->policy_code = ntohl(ste_buf->policy_code); + ste_buf->policy_version = ntohl(ste_buf->policy_version); + ste_buf->ste_max_types = ntohl(ste_buf->ste_max_types); + ste_buf->ste_max_ssidrefs = ntohl(ste_buf->ste_max_ssidrefs); + ste_buf->ste_ssid_offset = ntohl(ste_buf->ste_ssid_offset); + + /* policy type and version checks */ + if ((ste_buf->policy_code != ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY) || + (ste_buf->policy_version != ACM_STE_VERSION)) + return -EINVAL; /* 1. create and copy-in new ssidrefs buffer */ ssidrefsbuf = xmalloc_array(u8, sizeof(domaintype_t)*ste_buf->ste_max_types*ste_buf->ste_max_ssidrefs); diff -r 9be7fe98a556 -r e173a853dc46 xen/arch/x86/shadow_public.c --- a/xen/arch/x86/shadow_public.c Tue Aug 2 10:47:41 2005 +++ b/xen/arch/x86/shadow_public.c Tue Aug 2 17:20:46 2005 @@ -30,7 +30,7 @@ #include <xen/sched.h> #include <xen/trace.h> -#if CONFIG_PAGING_LEVELS >= 4 +#if CONFIG_PAGING_LEVELS >= 3 #include <asm/shadow_64.h> extern struct shadow_ops MODE_F_HANDLER; @@ -233,7 +233,20 @@ v->arch.monitor_vtable = 0; } +#elif CONFIG_PAGING_LEVELS == 3 + +static void alloc_monitor_pagetable(struct vcpu *v) +{ + BUG(); /* PAE not implemented yet */ +} + +void free_monitor_pagetable(struct vcpu *v) +{ + BUG(); /* PAE not implemented yet */ +} + #elif CONFIG_PAGING_LEVELS == 2 + static void alloc_monitor_pagetable(struct vcpu *v) { unsigned long mmfn; diff -r 9be7fe98a556 -r e173a853dc46 xen/arch/x86/x86_32/entry.S --- a/xen/arch/x86/x86_32/entry.S Tue Aug 2 10:47:41 2005 +++ b/xen/arch/x86/x86_32/entry.S Tue Aug 2 17:20:46 2005 @@ -751,7 +751,7 @@ .long do_boot_vcpu .long do_ni_hypercall /* 25 */ .long do_mmuext_op - .long do_policy_op /* 27 */ + .long do_acm_op /* 27 */ .rept NR_hypercalls-((.-hypercall_table)/4) .long do_ni_hypercall .endr diff -r 9be7fe98a556 -r e173a853dc46 xen/arch/x86/x86_64/entry.S --- a/xen/arch/x86/x86_64/entry.S Tue Aug 2 10:47:41 2005 +++ b/xen/arch/x86/x86_64/entry.S Tue Aug 2 17:20:46 2005 @@ -587,7 +587,7 @@ .quad do_boot_vcpu .quad do_set_segment_base /* 25 */ .quad do_mmuext_op - .quad do_policy_op + .quad do_acm_op .rept NR_hypercalls-((.-hypercall_table)/4) .quad do_ni_hypercall .endr diff -r 9be7fe98a556 -r e173a853dc46 xen/include/acm/acm_core.h --- a/xen/include/acm/acm_core.h Tue Aug 2 10:47:41 2005 +++ b/xen/include/acm/acm_core.h Tue Aug 2 17:20:46 2005 @@ -21,7 +21,7 @@ #include <xen/spinlock.h> #include <public/acm.h> #include <xen/acm_policy.h> -#include <public/policy_ops.h> +#include <public/acm_ops.h> /* Xen-internal representation of the binary policy */ struct acm_binary_policy { @@ -113,7 +113,7 @@ /* protos */ int acm_init_domain_ssid(domid_t id, ssidref_t ssidref); int acm_free_domain_ssid(struct acm_ssid_domain *ssid); -int acm_set_policy(void *buf, u16 buf_size, u16 policy, int isuserbuffer); +int acm_set_policy(void *buf, u16 buf_size, int isuserbuffer); int acm_get_policy(void *buf, u16 buf_size); int acm_dump_statistics(void *buf, u16 buf_size); diff -r 9be7fe98a556 -r e173a853dc46 xen/include/public/acm.h --- a/xen/include/public/acm.h Tue Aug 2 10:47:41 2005 +++ b/xen/include/public/acm.h Tue Aug 2 17:20:46 2005 @@ -71,6 +71,14 @@ (X == ACM_CHINESE_WALL_AND_SIMPLE_TYPE_ENFORCEMENT_POLICY) ? "CHINESE WALL AND SIMPLE TYPE ENFORCEMENT policy" : \ "UNDEFINED policy" +/* the following policy versions must be increased + * whenever the interpretation of the related + * policy's data structure changes + */ +#define ACM_POLICY_VERSION 1 +#define ACM_CHWALL_VERSION 1 +#define ACM_STE_VERSION 1 + /* defines a ssid reference used by xen */ typedef u32 ssidref_t; @@ -102,46 +110,53 @@ #define ACM_MAGIC 0x0001debc /* each offset in bytes from start of the struct they - * the are part of */ + * are part of */ + /* each buffer consists of all policy information for * the respective policy given in the policy code + * + * acm_policy_buffer, acm_chwall_policy_buffer, + * and acm_ste_policy_buffer need to stay 32-bit aligned + * because we create binary policies also with external + * tools that assume packed representations (e.g. the java tool) */ struct acm_policy_buffer { + u32 policy_version; /* ACM_POLICY_VERSION */ u32 magic; - u32 policyversion; u32 len; - u16 primary_policy_code; - u16 primary_buffer_offset; - u16 secondary_policy_code; - u16 secondary_buffer_offset; + u32 primary_policy_code; + u32 primary_buffer_offset; + u32 secondary_policy_code; + u32 secondary_buffer_offset; }; struct acm_chwall_policy_buffer { - u16 policy_code; - u16 chwall_max_types; - u16 chwall_max_ssidrefs; - u16 chwall_max_conflictsets; - u16 chwall_ssid_offset; - u16 chwall_conflict_sets_offset; - u16 chwall_running_types_offset; - u16 chwall_conflict_aggregate_offset; + u32 policy_version; /* ACM_CHWALL_VERSION */ + u32 policy_code; + u32 chwall_max_types; + u32 chwall_max_ssidrefs; + u32 chwall_max_conflictsets; + u32 chwall_ssid_offset; + u32 chwall_conflict_sets_offset; + u32 chwall_running_types_offset; + u32 chwall_conflict_aggregate_offset; }; struct acm_ste_policy_buffer { - u16 policy_code; - u16 ste_max_types; - u16 ste_max_ssidrefs; - u16 ste_ssid_offset; + u32 policy_version; /* ACM_STE_VERSION */ + u32 policy_code; + u32 ste_max_types; + u32 ste_max_ssidrefs; + u32 ste_ssid_offset; }; struct acm_stats_buffer { u32 magic; - u32 policyversion; u32 len; - u16 primary_policy_code; - u16 primary_stats_offset; - u16 secondary_policy_code; - u16 secondary_stats_offset; + u32 primary_policy_code; + u32 primary_stats_offset; + u32 secondary_policy_code; + u32 secondary_stats_offset; }; struct acm_ste_stats_buffer { diff -r 9be7fe98a556 -r e173a853dc46 xen/include/public/xen.h --- a/xen/include/public/xen.h Tue Aug 2 10:47:41 2005 +++ b/xen/include/public/xen.h Tue Aug 2 17:20:46 2005 @@ -58,7 +58,7 @@ #define __HYPERVISOR_boot_vcpu 24 #define __HYPERVISOR_set_segment_base 25 /* x86/64 only */ #define __HYPERVISOR_mmuext_op 26 -#define __HYPERVISOR_policy_op 27 +#define __HYPERVISOR_acm_op 27 /* * VIRTUAL INTERRUPTS diff -r 9be7fe98a556 -r e173a853dc46 tools/consoled/Makefile --- /dev/null Tue Aug 2 10:47:41 2005 +++ b/tools/consoled/Makefile Tue Aug 2 17:20:46 2005 @@ -0,0 +1,48 @@ +# Makefile for consoled +# based on xcs Makefile +# Anthony Liguori 2005 + +XEN_ROOT=../.. +include $(XEN_ROOT)/tools/Rules.mk + +CONSOLED_INSTALL_DIR = /usr/sbin +XC_CONSOLE_INSTALL_DIR = /usr/libexec/xen + +INSTALL = install +INSTALL_PROG = $(INSTALL) -m0755 +INSTALL_DIR = $(INSTALL) -d -m0755 + +CC = gcc +CFLAGS = -Wall -Werror -g3 + +CFLAGS += -I $(XEN_XCS) +CFLAGS += -I $(XEN_LIBXC) +CFLAGS += -I $(XEN_XENSTORE) + +SRCS := +SRCS += main.c utils.c io.c + +HDRS = $(wildcard *.h) +OBJS = $(patsubst %.c,%.o,$(SRCS)) +BIN = consoled xc_console + +all: $(BIN) + +clean: + $(RM) *.a *.so *.o *.rpm $(BIN) + +consoled: $(OBJS) + $(CC) $(CFLAGS) $^ -o $@ -L$(XEN_LIBXC) -L$(XEN_XENSTORE) \ + -lxc -lxenstore + +xc_console: xc_console.o + $(CC) $(CFLAGS) $^ -o $@ -L$(XEN_LIBXC) -L$(XEN_XENSTORE) \ + -lxc -lxenstore + +$(OBJS): $(HDRS) + +install: $(BIN) + $(INSTALL_DIR) -p $(DESTDIR)/$(CONSOLED_INSTALL_DIR) + $(INSTALL_PROG) consoled $(DESTDIR)/$(CONSOLED_INSTALL_DIR) + $(INSTALL_DIR) -p $(DESTDIR)/$(XC_CONSOLE_INSTALL_DIR) + $(INSTALL_PROG) xc_console $(DESTDIR)/$(XC_CONSOLE_INSTALL_DIR) diff -r 9be7fe98a556 -r e173a853dc46 tools/consoled/io.c --- /dev/null Tue Aug 2 10:47:41 2005 +++ b/tools/consoled/io.c Tue Aug 2 17:20:46 2005 @@ -0,0 +1,328 @@ +/*\ + * Copyright (C) International Business Machines Corp., 2005 + * Author(s): Anthony Liguori <aliguori@xxxxxxxxxx> + * + * Xen Console Daemon + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; under version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +\*/ + +#define _GNU_SOURCE + +#include "utils.h" +#include "io.h" + +#include "xc.h" +#include "xs.h" +#include "xen/io/domain_controller.h" +#include "xcs_proto.h" + +#include <malloc.h> +#include <stdlib.h> +#include <errno.h> +#include <string.h> +#include <sys/select.h> +#include <fcntl.h> +#include <unistd.h> +#include <termios.h> + +#define MAX(a, b) (((a) > (b)) ? (a) : (b)) +#define MIN(a, b) (((a) < (b)) ? (a) : (b)) + +struct buffer +{ + char *data; + size_t size; + size_t capacity; + size_t max_capacity; +}; + +void buffer_append(struct buffer *buffer, const void *data, size_t size) +{ + if ((buffer->capacity - buffer->size) < size) { + buffer->capacity += (size + 1024); + buffer->data = realloc(buffer->data, buffer->capacity); + if (buffer->data == NULL) { + dolog(LOG_ERR, "Memory allocation failed"); + exit(ENOMEM); + } + } + + memcpy(buffer->data + buffer->size, data, size); + buffer->size += size; + + if (buffer->max_capacity && + buffer->size > buffer->max_capacity) { + memmove(buffer->data + (buffer->size - buffer->max_capacity), + buffer->data, buffer->max_capacity); + buffer->data = realloc(buffer->data, buffer->max_capacity); + buffer->capacity = buffer->max_capacity; + } +} + +bool buffer_empty(struct buffer *buffer) +{ + return buffer->size == 0; +} + +void buffer_advance(struct buffer *buffer, size_t size) +{ + size = MIN(size, buffer->size); + memmove(buffer->data, buffer + size, buffer->size - size); + buffer->size -= size; +} + +struct domain +{ + int domid; + int tty_fd; + struct buffer buffer; + struct domain *next; +}; + +static struct domain *dom_head; + +bool domain_is_valid(int domid) +{ + bool ret; + xc_dominfo_t info; + + ret = (xc_domain_getinfo(xc, domid, 1, &info) == 1 && + info.domid == domid); + + return ret; +} + +int domain_create_tty(int domid) +{ + char path[1024]; + int master; + + if ((master = getpt()) == -1 || + grantpt(master) == -1 || unlockpt(master) == -1) { + dolog(LOG_ERR, "Failed to create tty for domain-%d", domid); + master = -1; + } else { + const char *slave = ptsname(master); + struct termios term; + + if (tcgetattr(master, &term) != -1) { + cfmakeraw(&term); + tcsetattr(master, TCSAFLUSH, &term); + } + + xs_mkdir(xs, "/console"); + snprintf(path, sizeof(path), "/console/%d", domid); + xs_mkdir(xs, path); + strcat(path, "/tty"); + + xs_write(xs, path, slave, strlen(slave), O_CREAT); + } + + return master; +} + +struct domain *create_domain(int domid) +{ + struct domain *dom; + char *data; + unsigned int len; + char path[1024]; + + dom = (struct domain *)malloc(sizeof(struct domain)); + if (dom == NULL) { + dolog(LOG_ERR, "Out of memory %s:%s():L%d", + __FILE__, __FUNCTION__, __LINE__); + exit(ENOMEM); + } + + dom->domid = domid; + dom->tty_fd = domain_create_tty(domid); + dom->buffer.data = 0; + dom->buffer.size = 0; + dom->buffer.capacity = 0; + dom->buffer.max_capacity = 0; + + snprintf(path, sizeof(path), "/console/%d/limit", domid); + data = xs_read(xs, path, &len); + if (data) { + dom->buffer.max_capacity = strtoul(data, 0, 0); + free(data); + } + + dolog(LOG_DEBUG, "New domain %d", domid); + + return dom; +} + +struct domain *lookup_domain(int domid) +{ + struct domain **pp; + + for (pp = &dom_head; *pp; pp = &(*pp)->next) { + struct domain *dom = *pp; + + if (dom->domid == domid) { + return dom; + } else if (dom->domid > domid) { + *pp = create_domain(domid); + (*pp)->next = dom; + return *pp; + } + } + + *pp = create_domain(domid); + return *pp; +} + +void remove_domain(struct domain *dom) +{ + struct domain **pp; + + dolog(LOG_DEBUG, "Removing domain-%d", dom->domid); + + for (pp = &dom_head; *pp; pp = &(*pp)->next) { + struct domain *d = *pp; + + if (dom->domid == d->domid) { + *pp = d->next; + free(d); + break; + } + } +} + +void handle_tty_read(struct domain *dom) +{ + ssize_t len; + xcs_msg_t msg; + + msg.type = XCS_REQUEST; + msg.u.control.remote_dom = dom->domid; + msg.u.control.msg.type = CMSG_CONSOLE; + msg.u.control.msg.subtype = CMSG_CONSOLE_DATA; + msg.u.control.msg.id = 1; + + len = read(dom->tty_fd, msg.u.control.msg.msg, 60); + if (len < 1) { + close(dom->tty_fd); + + if (domain_is_valid(dom->domid)) { + dom->tty_fd = domain_create_tty(dom->domid); + } else { + remove_domain(dom); + } + } else if (domain_is_valid(dom->domid)) { + msg.u.control.msg.length = len; + + if (!write_sync(xcs_data_fd, &msg, sizeof(msg))) { + dolog(LOG_ERR, "Write to xcs failed: %m"); + } + } else { + close(dom->tty_fd); + remove_domain(dom); + } +} + +void handle_tty_write(struct domain *dom) +{ + ssize_t len; + + len = write(dom->tty_fd, dom->buffer.data, dom->buffer.size); + if (len < 1) { + close(dom->tty_fd); + + if (domain_is_valid(dom->domid)) { + dom->tty_fd = domain_create_tty(dom->domid); + } else { + remove_domain(dom); + } + } else { + buffer_advance(&dom->buffer, len); + } +} + +void handle_xcs_msg(int fd) +{ + xcs_msg_t msg; + + if (!read_sync(fd, &msg, sizeof(msg))) { + dolog(LOG_ERR, "read from xcs failed! %m"); + } else if (msg.type == XCS_REQUEST) { + struct domain *dom; + + dom = lookup_domain(msg.u.control.remote_dom); + buffer_append(&dom->buffer, + msg.u.control.msg.msg, + msg.u.control.msg.length); + } +} + +static void enum_domains(void) +{ + int domid = 0; + xc_dominfo_t dominfo; + + while (xc_domain_getinfo(xc, domid, 1, &dominfo) == 1) { + lookup_domain(dominfo.domid); + domid = dominfo.domid + 1; + } +} + +void handle_io(void) +{ + fd_set readfds, writefds; + int ret; + int max_fd = -1; + + do { + struct domain *d; + struct timeval tv = { 1, 0 }; + + FD_ZERO(&readfds); + FD_ZERO(&writefds); + + FD_SET(xcs_data_fd, &readfds); + max_fd = MAX(xcs_data_fd, max_fd); + + for (d = dom_head; d; d = d->next) { + if (d->tty_fd != -1) { + FD_SET(d->tty_fd, &readfds); + } + + if (d->tty_fd != -1 && !buffer_empty(&d->buffer)) { + FD_SET(d->tty_fd, &writefds); + } + + max_fd = MAX(d->tty_fd, max_fd); + } + + ret = select(max_fd + 1, &readfds, &writefds, 0, &tv); + enum_domains(); + + if (FD_ISSET(xcs_data_fd, &readfds)) { + handle_xcs_msg(xcs_data_fd); + } + + for (d = dom_head; d; d = d->next) { + if (FD_ISSET(d->tty_fd, &readfds)) { + handle_tty_read(d); + } + + if (FD_ISSET(d->tty_fd, &writefds)) { + handle_tty_write(d); + } + } + } while (ret > -1); +} diff -r 9be7fe98a556 -r e173a853dc46 tools/consoled/io.h --- /dev/null Tue Aug 2 10:47:41 2005 +++ b/tools/consoled/io.h Tue Aug 2 17:20:46 2005 @@ -0,0 +1,26 @@ +/*\ + * Copyright (C) International Business Machines Corp., 2005 + * Author(s): Anthony Liguori <aliguori@xxxxxxxxxx> + * + * Xen Console Daemon + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; under version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +\*/ + +#ifndef CONSOLED_IO_H +#define CONSOLED_IO_H + +void handle_io(void); + +#endif diff -r 9be7fe98a556 -r e173a853dc46 tools/consoled/main.c --- /dev/null Tue Aug 2 10:47:41 2005 +++ b/tools/consoled/main.c Tue Aug 2 17:20:46 2005 @@ -0,0 +1,93 @@ +/*\ + * Copyright (C) International Business Machines Corp., 2005 + * Author(s): Anthony Liguori <aliguori@xxxxxxxxxx> + * + * Xen Console Daemon + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; under version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +\*/ + +#include <getopt.h> +#include <stdlib.h> +#include <stdio.h> +#include <errno.h> +#include <unistd.h> +#include <sys/types.h> + +#include "xc.h" +#include "xen/io/domain_controller.h" +#include "xcs_proto.h" + +#include "utils.h" +#include "io.h" + +int main(int argc, char **argv) +{ + const char *sopts = "hVvi"; + struct option lopts[] = { + { "help", 0, 0, 'h' }, + { "version", 0, 0, 'V' }, + { "verbose", 0, 0, 'v' }, + { "interactive", 0, 0, 'i' }, + { 0 }, + }; + bool is_interactive = false; + int ch; + int syslog_option = LOG_CONS; + int syslog_mask = LOG_WARNING; + int opt_ind = 0; + + while ((ch = getopt_long(argc, argv, sopts, lopts, &opt_ind)) != -1) { + switch (ch) { + case 'h': + //usage(argv[0]); + exit(0); + case 'V': + //version(argv[0]); + exit(0); + case 'v': + syslog_option |= LOG_PERROR; + syslog_mask = LOG_DEBUG; + break; + case 'i': + is_interactive = true; + break; + case '?': + fprintf(stderr, + "Try `%s --help' for more information\n", + argv[0]); + exit(EINVAL); + } + } + + if (geteuid() != 0) { + fprintf(stderr, "%s requires root to run.\n", argv[0]); + exit(EPERM); + } + + openlog("consoled", syslog_option, LOG_DAEMON); + setlogmask(syslog_mask); + + if (!is_interactive) { + daemonize("/var/run/consoled.pid"); + } + + xen_setup(); + + handle_io(); + + closelog(); + + return 0; +} diff -r 9be7fe98a556 -r e173a853dc46 tools/consoled/utils.c --- /dev/null Tue Aug 2 10:47:41 2005 +++ b/tools/consoled/utils.c Tue Aug 2 17:20:46 2005 @@ -0,0 +1,251 @@ +/*\ + * Copyright (C) International Business Machines Corp., 2005 + * Author(s): Anthony Liguori <aliguori@xxxxxxxxxx> + * + * Xen Console Daemon + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; under version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +\*/ + +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/wait.h> +#include <unistd.h> +#include <stdlib.h> +#include <fcntl.h> +#include <err.h> +#include <errno.h> +#include <stdio.h> +#include <getopt.h> +#include <stdbool.h> +#include <sys/socket.h> +#include <sys/un.h> +#include <string.h> + +#include "xc.h" +#include "xen/io/domain_controller.h" +#include "xcs_proto.h" + +#include "utils.h" + +struct xs_handle *xs; +int xc; + +int xcs_ctrl_fd = -1; +int xcs_data_fd = -1; + +bool _read_write_sync(int fd, void *data, size_t size, bool do_read) +{ + size_t offset = 0; + ssize_t len; + + while (offset < size) { + if (do_read) { + len = read(fd, data + offset, size - offset); + } else { + len = write(fd, data + offset, size - offset); + } + + if (len < 1) { + if (len == -1 && (errno == EAGAIN || errno == EINTR)) { + return false; + } + } else { + offset += len; + } + } + + return true; +} + +static int open_domain_socket(const char *path) +{ + struct sockaddr_un addr; + int sock; + size_t addr_len; + + if ((sock = socket(PF_UNIX, SOCK_STREAM, 0)) == -1) { + goto out; + } + + addr.sun_family = AF_UNIX; + strcpy(addr.sun_path, path); + addr_len = sizeof(addr.sun_family) + strlen(XCS_SUN_PATH) + 1; + + if (connect(sock, (struct sockaddr *)&addr, addr_len) == -1) { + goto out_close_sock; + } + + return sock; + + out_close_sock: + close(sock); + out: + return -1; +} + +static void child_exit(int sig) +{ + while (waitpid(-1, NULL, WNOHANG) > 0); +} + +void daemonize(const char *pidfile) +{ + pid_t pid; + int fd; + int len; + int i; + char buf[100]; + + if (getppid() == 1) { + return; + } + + if ((pid = fork()) > 0) { + exit(0); + } else if (pid == -1) { + err(errno, "fork() failed"); + } + + setsid(); + + /* redirect fd 0,1,2 to /dev/null */ + if ((fd = open("/dev/null",O_RDWR)) == -1) { + exit(1); + } + + for (i = 0; i <= 2; i++) { + close(i); + dup2(fd, i); + } + + close(fd); + + umask(027); + chdir("/"); + + fd = open(pidfile, O_RDWR | O_CREAT); + if (fd == -1) { + exit(1); + } + + if (lockf(fd, F_TLOCK, 0) == -1) { + exit(1); + } + + len = sprintf(buf, "%d\n", getpid()); + write(fd, buf, len); + + signal(SIGCHLD, child_exit); + signal(SIGTSTP, SIG_IGN); + signal(SIGTTOU, SIG_IGN); + signal(SIGTTIN, SIG_IGN); +} + +/* synchronized send/recv strictly for setting up xcs */ +/* always use asychronize callbacks any other time */ +static bool xcs_send_recv(int fd, xcs_msg_t *msg) +{ + bool ret = false; + + if (!write_sync(fd, msg, sizeof(*msg))) { + dolog(LOG_ERR, "Write failed at %s:%s():L%d? Possible bug.", + __FILE__, __FUNCTION__, __LINE__); + goto out; + } + + if (!read_sync(fd, msg, sizeof(*msg))) { + dolog(LOG_ERR, "Read failed at %s:%s():L%d? Possible bug.", + __FILE__, __FUNCTION__, __LINE__); + goto out; + } + + ret = true; + + out: + return ret; +} + +bool xen_setup(void) +{ + int sock; + xcs_msg_t msg; + + xs = xs_daemon_open(); + if (xs == NULL) { + dolog(LOG_ERR, + "Failed to contact xenstore (%m). Is it running?"); + goto out; + } + + xc = xc_interface_open(); + if (xc == -1) { + dolog(LOG_ERR, "Failed to contact hypervisor (%m)"); + goto out; + } + + sock = open_domain_socket(XCS_SUN_PATH); + if (sock == -1) { + dolog(LOG_ERR, "Failed to contact xcs (%m). Is it running?"); + goto out_close_store; + } + + xcs_ctrl_fd = sock; + + sock = open_domain_socket(XCS_SUN_PATH); + if (sock == -1) { + dolog(LOG_ERR, "Failed to contact xcs (%m). Is it running?"); + goto out_close_ctrl; + } + + xcs_data_fd = sock; + + memset(&msg, 0, sizeof(msg)); + msg.type = XCS_CONNECT_CTRL; + if (!xcs_send_recv(xcs_ctrl_fd, &msg) || msg.result != XCS_RSLT_OK) { + dolog(LOG_ERR, "xcs control connect failed. Possible bug."); + goto out_close_data; + } + + msg.type = XCS_CONNECT_DATA; + if (!xcs_send_recv(xcs_data_fd, &msg) || msg.result != XCS_RSLT_OK) { + dolog(LOG_ERR, "xcs data connect failed. Possible bug."); + goto out_close_data; + } + + /* Since the vast majority of control messages are console messages + it's just easier to ignore other messages that try to bind to + a specific type. */ + msg.type = XCS_MSG_BIND; + msg.u.bind.port = PORT_WILDCARD; + msg.u.bind.type = TYPE_WILDCARD; + if (!xcs_send_recv(xcs_ctrl_fd, &msg) || msg.result != XCS_RSLT_OK) { + dolog(LOG_ERR, "xcs vind failed. Possible bug."); + goto out_close_data; + } + + return true; + + out_close_data: + close(xcs_ctrl_fd); + xcs_data_fd = -1; + out_close_ctrl: + close(xcs_ctrl_fd); + xcs_ctrl_fd = -1; + out_close_store: + xs_daemon_close(xs); + out: + return false; +} + diff -r 9be7fe98a556 -r e173a853dc46 tools/consoled/utils.h --- /dev/null Tue Aug 2 10:47:41 2005 +++ b/tools/consoled/utils.h Tue Aug 2 17:20:46 2005 @@ -0,0 +1,47 @@ +/*\ + * Copyright (C) International Business Machines Corp., 2005 + * Author(s): Anthony Liguori <aliguori@xxxxxxxxxx> + * + * Xen Console Daemon + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; under version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +\*/ + +#ifndef CONSOLED_UTILS_H +#define CONSOLED_UTILS_H + +#include <stdbool.h> +#include <syslog.h> +#include <stdio.h> + +#include "xs.h" + +void daemonize(const char *pidfile); +bool xen_setup(void); +#define read_sync(fd, buffer, size) _read_write_sync(fd, buffer, size, true) +#define write_sync(fd, buffer, size) _read_write_sync(fd, buffer, size, false) +bool _read_write_sync(int fd, void *data, size_t size, bool do_read); + +extern int xcs_ctrl_fd; +extern int xcs_data_fd; +extern struct xs_handle *xs; +extern int xc; + +#if 1 +#define dolog(val, fmt, ...) syslog(val, fmt, ## __VA_ARGS__) +#else +#define dolog(val, fmt, ...) fprintf(stderr, fmt "\n", ## __VA_ARGS__) +#endif + +#endif diff -r 9be7fe98a556 -r e173a853dc46 tools/consoled/xc_console.c --- /dev/null Tue Aug 2 10:47:41 2005 +++ b/tools/consoled/xc_console.c Tue Aug 2 17:20:46 2005 @@ -0,0 +1,236 @@ +/*\ + * Copyright (C) International Business Machines Corp., 2005 + * Author(s): Anthony Liguori <aliguori@xxxxxxxxxx> + * + * Xen Console Daemon + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; under version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +\*/ + +#include <sys/types.h> +#include <sys/socket.h> +#include <sys/un.h> +#include <stdio.h> +#include <unistd.h> +#include <errno.h> +#include <stdlib.h> +#include <time.h> +#include <fcntl.h> +#include <sys/wait.h> +#include <termios.h> +#include <signal.h> +#include <getopt.h> +#include <sys/select.h> +#include <err.h> +#include <errno.h> +#include <pty.h> + +#include "xc.h" +#include "xs.h" + +#define ESCAPE_CHARACTER 0x1d + +static volatile sig_atomic_t received_signal = 0; + +static void sighandler(int signum) +{ + received_signal = 1; +} + +static bool write_sync(int fd, const void *data, size_t size) +{ + size_t offset = 0; + ssize_t len; + + while (offset < size) { + len = write(fd, data + offset, size - offset); + if (len < 1) { + return false; + } + offset += len; + } + + return true; +} + +static void usage(const char *program) { + printf("Usage: %s [OPTION] DOMID\n" + "Attaches to a virtual domain console\n" + "\n" + " -h, --help display this help and exit\n" + , program); +} + +/* don't worry too much if setting terminal attributes fail */ +static void init_term(int fd, struct termios *old) +{ + struct termios new_term; + + if (tcgetattr(fd, old) == -1) { + perror("tcgetattr() failed"); + return; + } + + new_term = *old; + cfmakeraw(&new_term); + + if (tcsetattr(fd, TCSAFLUSH, &new_term) == -1) { + perror("tcsetattr() failed"); + } +} + +static void restore_term(int fd, struct termios *old) +{ + if (tcsetattr(fd, TCSAFLUSH, old) == -1) { + perror("tcsetattr() failed"); + } +} + +static int console_loop(int xc_handle, domid_t domid, int fd) +{ + int ret; + + do { + fd_set fds; + + FD_ZERO(&fds); + FD_SET(STDIN_FILENO, &fds); + FD_SET(fd, &fds); + + ret = select(fd + 1, &fds, NULL, NULL, NULL); + if (ret == -1) { + if (errno == EINTR || errno == EAGAIN) { + continue; + } + perror("select() failed"); + return -1; + } + + if (FD_ISSET(STDIN_FILENO, &fds)) { + ssize_t len; + char msg[60]; + + len = read(STDIN_FILENO, msg, sizeof(msg)); + if (len == 1 && msg[0] == ESCAPE_CHARACTER) { + return 0; + } + + if (len == 0 && len == -1) { + if (len == -1 && + (errno == EINTR || errno == EAGAIN)) { + continue; + } + perror("select() failed"); + return -1; + } + + if (!write_sync(fd, msg, len)) { + perror("write() failed"); + return -1; + } + } + + if (FD_ISSET(fd, &fds)) { + ssize_t len; + char msg[512]; + + len = read(fd, msg, sizeof(msg)); + if (len == 0 || len == -1) { + if (len == -1 && + (errno == EINTR || errno == EAGAIN)) { + continue; + } + perror("select() failed"); + return -1; + } + + if (!write_sync(STDOUT_FILENO, msg, len)) { + perror("write() failed"); + return -1; + } + } + } while (received_signal == 0); + + return 0; +} + +int main(int argc, char **argv) +{ + struct termios attr; + int domid; + int xc_handle; + char *sopt = "hf:pc"; + int ch; + int opt_ind=0; + struct option lopt[] = { + { "help", 0, 0, 'h' }, + { "file", 1, 0, 'f' }, + { "pty", 0, 0, 'p' }, + { "ctty", 0, 0, 'c' }, + { 0 }, + + }; + char *str_pty; + char path[1024]; + int spty; + unsigned int len = 0; + struct xs_handle *xs; + + while((ch = getopt_long(argc, argv, sopt, lopt, &opt_ind)) != -1) { + switch(ch) { + case 'h': + usage(argv[0]); + exit(0); + break; + } + } + + if ((argc - optind) != 1) { + fprintf(stderr, "Invalid number of arguments\n"); + fprintf(stderr, "Try `%s --help' for more information.\n", + argv[0]); + exit(EINVAL); + } + + domid = atoi(argv[optind]); + + xs = xs_daemon_open(); + if (xs == NULL) { + err(errno, "Could not contact XenStore"); + } + + xc_handle = xc_interface_open(); + if (xc_handle == -1) { + err(errno, "xc_interface_open()"); + } + + signal(SIGTERM, sighandler); + + snprintf(path, sizeof(path), "/console/%d/tty", domid); + str_pty = xs_read(xs, path, &len); + if (str_pty == NULL) { + err(errno, "Could not read tty from store"); + } + spty = open(str_pty, O_RDWR | O_NOCTTY); + if (spty == -1) { + err(errno, "Could not open tty `%s'", str_pty); + } + free(str_pty); + + init_term(STDIN_FILENO, &attr); + console_loop(xc_handle, domid, spty); + restore_term(STDIN_FILENO, &attr); + + return 0; + } diff -r 9be7fe98a556 -r e173a853dc46 tools/libxc/xc_ia64_stubs.c --- /dev/null Tue Aug 2 10:47:41 2005 +++ b/tools/libxc/xc_ia64_stubs.c Tue Aug 2 17:20:46 2005 @@ -0,0 +1,39 @@ +#include "xc_private.h" + +int xc_linux_save(int xc_handle, int io_fd, u32 dom) +{ + PERROR("xc_linux_save not implemented\n"); + return -1; +} + +int xc_linux_restore(int xc_handle, int io_fd, u32 dom, unsigned long nr_pfns) +{ + PERROR("xc_linux_restore not implemented\n"); + return -1; +} + +int xc_vmx_build(int xc_handle, + u32 domid, + int memsize, + const char *image_name, + struct mem_map *mem_mapp, + const char *ramdisk_name, + const char *cmdline, + unsigned int control_evtchn, + unsigned long flags) +{ + PERROR("xc_vmx_build not implemented\n"); + return -1; +} + +int +xc_plan9_build(int xc_handle, + u32 domid, + const char *image_name, + const char *cmdline, + unsigned int control_evtchn, unsigned long flags) +{ + PERROR("xc_plan9_build not implemented\n"); + return -1; +} + diff -r 9be7fe98a556 -r e173a853dc46 tools/misc/policyprocessor/Makefile --- /dev/null Tue Aug 2 10:47:41 2005 +++ b/tools/misc/policyprocessor/Makefile Tue Aug 2 17:20:46 2005 @@ -0,0 +1,42 @@ +XEN_ROOT = ../../.. +include $(XEN_ROOT)/tools/Rules.mk + +CFLAGS += -static +CFLAGS += -Wall +CFLAGS += -Werror +CFLAGS += -O3 +CFLAGS += -fno-strict-aliasing +CFLAGS += -I. + +all: build + +build: mk-symlinks + $(MAKE) xml_to_bin + +default: all + +install: all + +xml_to_bin : make_include XmlToBin.java XmlToBinInterface.java SsidsEntry.java SecurityLabel.java myHandler.java + javac XmlToBin.java + +make_include : c2j_include + ./c2j_include + +c2j_include: c2j_include.c + $(CC) $(CPPFLAGS) $(CFLAGS) -o $@ $< + +clean: + rm -rf *.class xen c2j_include policy_version.java *.bin + + +LINUX_ROOT := $(XEN_ROOT)/linux-2.6-xen-sparse +mk-symlinks: + [ -e xen/linux ] || mkdir -p xen/linux + [ -e xen/io ] || mkdir -p xen/io + ( cd xen >/dev/null ; \ + ln -sf ../$(XEN_ROOT)/xen/include/public/*.h . ) + ( cd xen/io >/dev/null ; \ + ln -sf ../../$(XEN_ROOT)/xen/include/public/io/*.h . ) + ( cd xen/linux >/dev/null ; \ + ln -sf ../../$(LINUX_ROOT)/include/asm-xen/linux-public/*.h . ) diff -r 9be7fe98a556 -r e173a853dc46 tools/misc/policyprocessor/c2j_include.c --- /dev/null Tue Aug 2 10:47:41 2005 +++ b/tools/misc/policyprocessor/c2j_include.c Tue Aug 2 17:20:46 2005 @@ -0,0 +1,57 @@ +/**************************************************************** + * c2j_include.c + * + * Copyright (C) 2005 IBM Corporation + * + * Authors: + * Reiner Sailer <sailer@xxxxxxxxxxxxxx> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation, version 2 of the + * License. + * + * This tool makes some constants from acm.h available to the + * java policyprocessor for version checking. + */ +#include <stdio.h> +#include <errno.h> +#include <stdlib.h> +#include <stdint.h> + +typedef uint8_t u8; +typedef uint16_t u16; +typedef uint32_t u32; +typedef uint64_t u64; +typedef int8_t s8; +typedef int16_t s16; +typedef int32_t s32; +typedef int64_t s64; + +#include <xen/acm.h> + +char *filename = "policy_version.java"; + +int main(int argc, char **argv) +{ + + FILE *fd; + if ((fd = fopen(filename, "w")) <= 0) + { + printf("File %s not found.\n", filename); + exit(-ENOENT); + } + + fprintf(fd, "/*\n * This file was automatically generated\n"); + fprintf(fd, " * Do not change it manually!\n */\n"); + fprintf(fd, "public class policy_version {\n"); + fprintf(fd, " final int ACM_POLICY_VERSION = %x;\n", + ACM_POLICY_VERSION); + fprintf(fd, " final int ACM_CHWALL_VERSION = %x;\n", + ACM_CHWALL_VERSION); + fprintf(fd, " final int ACM_STE_VERSION = %x;\n", + ACM_STE_VERSION); + fprintf(fd, "}\n"); + fclose(fd); + return 0; +} diff -r 9be7fe98a556 -r e173a853dc46 tools/security/Makefile --- /dev/null Tue Aug 2 10:47:41 2005 +++ b/tools/security/Makefile Tue Aug 2 17:20:46 2005 @@ -0,0 +1,36 @@ +XEN_ROOT = ../.. +include $(XEN_ROOT)/tools/Rules.mk + +SRCS = secpol_tool.c +CFLAGS += -static +CFLAGS += -Wall +CFLAGS += -Werror +CFLAGS += -O3 +CFLAGS += -fno-strict-aliasing +CFLAGS += -I. + +all: build +build: mk-symlinks + $(MAKE) secpol_tool + +default: all + +install: all + +secpol_tool : secpol_tool.c + $(CC) $(CPPFLAGS) $(CFLAGS) -o $@ $< + +clean: + rm -rf secpol_tool xen + + +LINUX_ROOT := $(XEN_ROOT)/linux-2.6-xen-sparse +mk-symlinks: + [ -e xen/linux ] || mkdir -p xen/linux + [ -e xen/io ] || mkdir -p xen/io + ( cd xen >/dev/null ; \ + ln -sf ../$(XEN_ROOT)/xen/include/public/*.h . ) + ( cd xen/io >/dev/null ; \ + ln -sf ../../$(XEN_ROOT)/xen/include/public/io/*.h . ) + ( cd xen/linux >/dev/null ; \ + ln -sf ../../$(LINUX_ROOT)/include/asm-xen/linux-public/*.h . ) diff -r 9be7fe98a556 -r e173a853dc46 tools/security/secpol_tool.c --- /dev/null Tue Aug 2 10:47:41 2005 +++ b/tools/security/secpol_tool.c Tue Aug 2 17:20:46 2005 @@ -0,0 +1,648 @@ +/**************************************************************** + * secpol_tool.c + * + * Copyright (C) 2005 IBM Corporation + * + * Authors: + * Reiner Sailer <sailer@xxxxxxxxxxxxxx> + * Stefan Berger <stefanb@xxxxxxxxxxxxxx> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation, version 2 of the + * License. + * + * sHype policy management tool. This code runs in a domain and + * manages the Xen security policy by interacting with the + * Xen access control module via a /proc/xen/privcmd proc-ioctl, + * which is translated into a acm_op hypercall into Xen. + * + * indent -i4 -kr -nut + */ + + +#include <unistd.h> +#include <stdio.h> +#include <errno.h> +#include <fcntl.h> +#include <sys/mman.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <stdlib.h> +#include <sys/ioctl.h> +#include <string.h> +#include <stdint.h> +#include <netinet/in.h> + +typedef uint8_t u8; +typedef uint16_t u16; +typedef uint32_t u32; +typedef uint64_t u64; +typedef int8_t s8; +typedef int16_t s16; +typedef int32_t s32; +typedef int64_t s64; + +#include <xen/acm.h> +#include <xen/acm_ops.h> +#include <xen/linux/privcmd.h> + +#define PERROR(_m, _a...) \ +fprintf(stderr, "ERROR: " _m " (%d = %s)\n" , ## _a , \ + errno, strerror(errno)) + +static inline int do_policycmd(int xc_handle, unsigned int cmd, + unsigned long data) +{ + return ioctl(xc_handle, cmd, data); +} + +static inline int do_xen_hypercall(int xc_handle, + privcmd_hypercall_t * hypercall) +{ + return do_policycmd(xc_handle, + IOCTL_PRIVCMD_HYPERCALL, + (unsigned long) hypercall); +} + +static inline int do_acm_op(int xc_handle, acm_op_t * op) +{ + int ret = -1; + privcmd_hypercall_t hypercall; + + op->interface_version = ACM_INTERFACE_VERSION; + + hypercall.op = __HYPERVISOR_acm_op; + hypercall.arg[0] = (unsigned long) op; + + if (mlock(op, sizeof(*op)) != 0) + { + PERROR("Could not lock memory for Xen policy hypercall"); + goto out1; + } + + if ((ret = do_xen_hypercall(xc_handle, &hypercall)) < 0) + { + if (errno == EACCES) + fprintf(stderr, "ACM operation failed -- need to" + " rebuild the user-space tool set?\n"); + goto out2; + } + + out2:(void) munlock(op, sizeof(*op)); + out1:return ret; +} + +/*************************** DUMPS *******************************/ + +void acm_dump_chinesewall_buffer(void *buf, int buflen) +{ + + struct acm_chwall_policy_buffer *cwbuf = + (struct acm_chwall_policy_buffer *) buf; + domaintype_t *ssids, *conflicts, *running_types, *conflict_aggregate; + int i, j; + + + if (htonl(cwbuf->policy_code) != ACM_CHINESE_WALL_POLICY) + { + printf("CHINESE WALL POLICY CODE not found ERROR!!\n"); + return; + } + printf("\n\nChinese Wall policy:\n"); + printf("====================\n"); + printf("Policy version= %x.\n", ntohl(cwbuf->policy_version)); + printf("Max Types = %x.\n", ntohl(cwbuf->chwall_max_types)); + printf("Max Ssidrefs = %x.\n", ntohl(cwbuf->chwall_max_ssidrefs)); + printf("Max ConfSets = %x.\n", ntohl(cwbuf->chwall_max_conflictsets)); + printf("Ssidrefs Off = %x.\n", ntohl(cwbuf->chwall_ssid_offset)); + printf("Conflicts Off = %x.\n", + ntohl(cwbuf->chwall_conflict_sets_offset)); + printf("Runing T. Off = %x.\n", + ntohl(cwbuf->chwall_running_types_offset)); + printf("C. Agg. Off = %x.\n", + ntohl(cwbuf->chwall_conflict_aggregate_offset)); + printf("\nSSID To CHWALL-Type matrix:\n"); + + ssids = (domaintype_t *) (buf + ntohl(cwbuf->chwall_ssid_offset)); + for (i = 0; i < ntohl(cwbuf->chwall_max_ssidrefs); i++) + { + printf("\n ssidref%2x: ", i); + for (j = 0; j < ntohl(cwbuf->chwall_max_types); j++) + printf("%02x ", + ntohs(ssids[i * ntohl(cwbuf->chwall_max_types) + j])); + } + printf("\n\nConfict Sets:\n"); + conflicts = + (domaintype_t *) (buf + ntohl(cwbuf->chwall_conflict_sets_offset)); + for (i = 0; i < ntohl(cwbuf->chwall_max_conflictsets); i++) + { + printf("\n c-set%2x: ", i); + for (j = 0; j < ntohl(cwbuf->chwall_max_types); j++) + printf("%02x ", + ntohs(conflicts + [i * ntohl(cwbuf->chwall_max_types) + j])); + } + printf("\n"); + + printf("\nRunning\nTypes: "); + if (ntohl(cwbuf->chwall_running_types_offset)) + { + running_types = + (domaintype_t *) (buf + + ntohl(cwbuf->chwall_running_types_offset)); + for (i = 0; i < ntohl(cwbuf->chwall_max_types); i++) + { + printf("%02x ", ntohs(running_types[i])); + } + printf("\n"); + } else { + printf("Not Reported!\n"); + } + printf("\nConflict\nAggregate Set: "); + if (ntohl(cwbuf->chwall_conflict_aggregate_offset)) + { + conflict_aggregate = + (domaintype_t *) (buf + + ntohl(cwbuf->chwall_conflict_aggregate_offset)); + for (i = 0; i < ntohl(cwbuf->chwall_max_types); i++) + { + printf("%02x ", ntohs(conflict_aggregate[i])); + } + printf("\n\n"); + } else { + printf("Not Reported!\n"); + } +} + +void acm_dump_ste_buffer(void *buf, int buflen) +{ + + struct acm_ste_policy_buffer *stebuf = + (struct acm_ste_policy_buffer *) buf; + domaintype_t *ssids; + int i, j; + + + if (ntohl(stebuf->policy_code) != ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY) { + printf("SIMPLE TYPE ENFORCEMENT POLICY CODE not found ERROR!!\n"); + return; + } + printf("\nSimple Type Enforcement policy:\n"); + printf("===============================\n"); + printf("Policy version= %x.\n", ntohl(stebuf->policy_version)); + printf("Max Types = %x.\n", ntohl(stebuf->ste_max_types)); + printf("Max Ssidrefs = %x.\n", ntohl(stebuf->ste_max_ssidrefs)); + printf("Ssidrefs Off = %x.\n", ntohl(stebuf->ste_ssid_offset)); + printf("\nSSID To STE-Type matrix:\n"); + + ssids = (domaintype_t *) (buf + ntohl(stebuf->ste_ssid_offset)); + for (i = 0; i < ntohl(stebuf->ste_max_ssidrefs); i++) + { + printf("\n ssidref%2x: ", i); + for (j = 0; j < ntohl(stebuf->ste_max_types); j++) + printf("%02x ", ntohs(ssids[i * ntohl(stebuf->ste_max_types) + j])); + } + printf("\n\n"); +} + +void acm_dump_policy_buffer(void *buf, int buflen) +{ + struct acm_policy_buffer *pol = (struct acm_policy_buffer *) buf; + + printf("\nPolicy dump:\n"); + printf("============\n"); + printf("PolicyVer = %x.\n", ntohl(pol->policy_version)); + printf("Magic = %x.\n", ntohl(pol->magic)); + printf("Len = %x.\n", ntohl(pol->len)); + printf("Primary = %s (c=%x, off=%x).\n", + ACM_POLICY_NAME(ntohl(pol->primary_policy_code)), + ntohl(pol->primary_policy_code), + ntohl(pol->primary_buffer_offset)); + printf("Secondary = %s (c=%x, off=%x).\n", + ACM_POLICY_NAME(ntohl(pol->secondary_policy_code)), + ntohl(pol->secondary_policy_code), + ntohl(pol->secondary_buffer_offset)); + switch (ntohl(pol->primary_policy_code)) + { + case ACM_CHINESE_WALL_POLICY: + acm_dump_chinesewall_buffer(buf + + ntohl(pol->primary_buffer_offset), + ntohl(pol->len) - + ntohl(pol->primary_buffer_offset)); + break; + + case ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY: + acm_dump_ste_buffer(buf + ntohl(pol->primary_buffer_offset), + ntohl(pol->len) - + ntohl(pol->primary_buffer_offset)); + break; + + case ACM_NULL_POLICY: + printf("Primary policy is NULL Policy (n/a).\n"); + break; + + default: + printf("UNKNOWN POLICY!\n"); + } + + switch (ntohl(pol->secondary_policy_code)) + { + case ACM_CHINESE_WALL_POLICY: + acm_dump_chinesewall_buffer(buf + + ntohl(pol->secondary_buffer_offset), + ntohl(pol->len) - + ntohl(pol->secondary_buffer_offset)); + break; + + case ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY: + acm_dump_ste_buffer(buf + ntohl(pol->secondary_buffer_offset), + ntohl(pol->len) - + ntohl(pol->secondary_buffer_offset)); + break; + + case ACM_NULL_POLICY: + printf("Secondary policy is NULL Policy (n/a).\n"); + break; + + default: + printf("UNKNOWN POLICY!\n"); + } +} + +/*************************** set policy ****************************/ + +int acm_domain_set_chwallpolicy(void *bufstart, int buflen) +{ +#define CWALL_MAX_SSIDREFS 6 +#define CWALL_MAX_TYPES 10 +#define CWALL_MAX_CONFLICTSETS 2 + + struct acm_chwall_policy_buffer *chwall_bin_pol = + (struct acm_chwall_policy_buffer *) bufstart; + domaintype_t *ssidrefs, *conflicts; + int ret = 0; + int j; + + chwall_bin_pol->chwall_max_types = htonl(CWALL_MAX_TYPES); + chwall_bin_pol->chwall_max_ssidrefs = htonl(CWALL_MAX_SSIDREFS); + chwall_bin_pol->policy_code = htonl(ACM_CHINESE_WALL_POLICY); + chwall_bin_pol->policy_version = htonl(ACM_CHWALL_VERSION); + chwall_bin_pol->chwall_ssid_offset = + htonl(sizeof(struct acm_chwall_policy_buffer)); + chwall_bin_pol->chwall_max_conflictsets = + htonl(CWALL_MAX_CONFLICTSETS); + chwall_bin_pol->chwall_conflict_sets_offset = + htonl(ntohl(chwall_bin_pol->chwall_ssid_offset) + + sizeof(domaintype_t) * CWALL_MAX_SSIDREFS * CWALL_MAX_TYPES); + chwall_bin_pol->chwall_running_types_offset = 0; /* not set */ + chwall_bin_pol->chwall_conflict_aggregate_offset = 0; /* not set */ + ret += sizeof(struct acm_chwall_policy_buffer); + /* now push example ssids into the buffer (max_ssidrefs x max_types entries) */ + /* check buffer size */ + if ((buflen - ret) < + (CWALL_MAX_TYPES * CWALL_MAX_SSIDREFS * sizeof(domaintype_t))) + return -1; /* not enough space */ + + ssidrefs = (domaintype_t *) (bufstart + + ntohl(chwall_bin_pol->chwall_ssid_offset)); + memset(ssidrefs, 0, + CWALL_MAX_TYPES * CWALL_MAX_SSIDREFS * sizeof(domaintype_t)); + + /* now set type j-1 for ssidref i+1 */ + for (j = 0; j <= CWALL_MAX_SSIDREFS; j++) + if ((0 < j) && (j <= CWALL_MAX_TYPES)) + ssidrefs[j * CWALL_MAX_TYPES + j - 1] = htons(1); + + ret += CWALL_MAX_TYPES * CWALL_MAX_SSIDREFS * sizeof(domaintype_t); + if ((buflen - ret) < + (CWALL_MAX_CONFLICTSETS * CWALL_MAX_TYPES * sizeof(domaintype_t))) + return -1; /* not enough space */ + + /* now the chinese wall policy conflict sets */ + conflicts = (domaintype_t *) (bufstart + + ntohl(chwall_bin_pol-> + chwall_conflict_sets_offset)); + memset((void *) conflicts, 0, + CWALL_MAX_CONFLICTSETS * CWALL_MAX_TYPES * + sizeof(domaintype_t)); + /* just 1 conflict set [0]={2,3}, [1]={1,5,6} */ + if (CWALL_MAX_TYPES > 3) + { + conflicts[2] = htons(1); + conflicts[3] = htons(1); /* {2,3} */ + conflicts[CWALL_MAX_TYPES + 1] = htons(1); + conflicts[CWALL_MAX_TYPES + 5] = htons(1); + conflicts[CWALL_MAX_TYPES + 6] = htons(1); /* {0,5,6} */ + } + ret += sizeof(domaintype_t) * CWALL_MAX_CONFLICTSETS * CWALL_MAX_TYPES; + return ret; +} + +int acm_domain_set_stepolicy(void *bufstart, int buflen) +{ +#define STE_MAX_SSIDREFS 6 +#define STE_MAX_TYPES 5 + + struct acm_ste_policy_buffer *ste_bin_pol = + (struct acm_ste_policy_buffer *) bufstart; + domaintype_t *ssidrefs; + int j, ret = 0; + + ste_bin_pol->ste_max_types = htonl(STE_MAX_TYPES); + ste_bin_pol->ste_max_ssidrefs = htonl(STE_MAX_SSIDREFS); + ste_bin_pol->policy_code = htonl(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY); + ste_bin_pol->policy_version = htonl(ACM_STE_VERSION); + ste_bin_pol->ste_ssid_offset = + htonl(sizeof(struct acm_ste_policy_buffer)); + ret += sizeof(struct acm_ste_policy_buffer); + /* check buffer size */ + if ((buflen - ret) < + (STE_MAX_TYPES * STE_MAX_SSIDREFS * sizeof(domaintype_t))) + return -1; /* not enough space */ + + ssidrefs = + (domaintype_t *) (bufstart + ntohl(ste_bin_pol->ste_ssid_offset)); + memset(ssidrefs, 0, + STE_MAX_TYPES * STE_MAX_SSIDREFS * sizeof(domaintype_t)); + /* all types 1 for ssidref 1 */ + for (j = 0; j < STE_MAX_TYPES; j++) + ssidrefs[1 * STE_MAX_TYPES + j] = htons(1); + /* now set type j-1 for ssidref j */ + for (j = 0; j < STE_MAX_SSIDREFS; j++) + if ((0 < j) && (j <= STE_MAX_TYPES)) + ssidrefs[j * STE_MAX_TYPES + j - 1] = htons(1); + ret += STE_MAX_TYPES * STE_MAX_SSIDREFS * sizeof(domaintype_t); + return ret; +} + +#define MAX_PUSH_BUFFER 16384 +u8 push_buffer[MAX_PUSH_BUFFER]; + +int acm_domain_setpolicy(int xc_handle) +{ + int ret; + struct acm_policy_buffer *bin_pol; + acm_op_t op; + + /* future: read policy from file and set it */ + bin_pol = (struct acm_policy_buffer *) push_buffer; + bin_pol->policy_version = htonl(ACM_POLICY_VERSION); + bin_pol->magic = htonl(ACM_MAGIC); + bin_pol->primary_policy_code = htonl(ACM_CHINESE_WALL_POLICY); + bin_pol->secondary_policy_code = + htonl(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY); + + bin_pol->len = htonl(sizeof(struct acm_policy_buffer)); + bin_pol->primary_buffer_offset = htonl(ntohl(bin_pol->len)); + ret = + acm_domain_set_chwallpolicy(push_buffer + + ntohl(bin_pol->primary_buffer_offset), + MAX_PUSH_BUFFER - + ntohl(bin_pol->primary_buffer_offset)); + if (ret < 0) + { + printf("ERROR creating chwallpolicy buffer.\n"); + return -1; + } + bin_pol->len = htonl(ntohl(bin_pol->len) + ret); + bin_pol->secondary_buffer_offset = htonl(ntohl(bin_pol->len)); + ret = acm_domain_set_stepolicy(push_buffer + + ntohl(bin_pol->secondary_buffer_offset), + MAX_PUSH_BUFFER - + ntohl(bin_pol->secondary_buffer_offset)); + if (ret < 0) + { + printf("ERROR creating chwallpolicy buffer.\n"); + return -1; + } + bin_pol->len = htonl(ntohl(bin_pol->len) + ret); + + /* dump it and then push it down into xen/acm */ + acm_dump_policy_buffer(push_buffer, ntohl(bin_pol->len)); + + op.cmd = ACM_SETPOLICY; + op.interface_version = ACM_INTERFACE_VERSION; + op.u.setpolicy.pushcache = (void *) push_buffer; + op.u.setpolicy.pushcache_size = ntohl(bin_pol->len); + ret = do_acm_op(xc_handle, &op); + + if (ret) + printf("ERROR setting policy. Use 'xm dmesg' to see details.\n"); + else + printf("Successfully changed policy.\n"); + + return ret; +} + +/******************************* get policy ******************************/ + +#define PULL_CACHE_SIZE 8192 +u8 pull_buffer[PULL_CACHE_SIZE]; +int acm_domain_getpolicy(int xc_handle) +{ + acm_op_t op; + int ret; + + memset(pull_buffer, 0x00, sizeof(pull_buffer)); + op.cmd = ACM_GETPOLICY; + op.interface_version = ACM_INTERFACE_VERSION; + op.u.getpolicy.pullcache = (void *) pull_buffer; + op.u.getpolicy.pullcache_size = sizeof(pull_buffer); + ret = do_acm_op(xc_handle, &op); + /* dump policy */ + acm_dump_policy_buffer(pull_buffer, sizeof(pull_buffer)); + return ret; +} + +/************************ load binary policy ******************************/ + +int acm_domain_loadpolicy(int xc_handle, const char *filename) +{ + struct stat mystat; + int ret, fd; + off_t len; + u8 *buffer; + + if ((ret = stat(filename, &mystat))) + { + printf("File %s not found.\n", filename); + goto out; + } + + len = mystat.st_size; + if ((buffer = malloc(len)) == NULL) + { + ret = -ENOMEM; + goto out; + } + if ((fd = open(filename, O_RDONLY)) <= 0) + { + ret = -ENOENT; + printf("File %s not found.\n", filename); + goto free_out; + } + if (len == read(fd, buffer, len)) + { + acm_op_t op; + /* dump it and then push it down into xen/acm */ + acm_dump_policy_buffer(buffer, len); + op.cmd = ACM_SETPOLICY; + op.interface_version = ACM_INTERFACE_VERSION; + op.u.setpolicy.pushcache = (void *) buffer; + op.u.setpolicy.pushcache_size = len; + ret = do_acm_op(xc_handle, &op); + + if (ret) + printf + ("ERROR setting policy. Use 'xm dmesg' to see details.\n"); + else + printf("Successfully changed policy.\n"); + + } else { + ret = -1; + } + close(fd); + free_out: + free(buffer); + out: + return ret; +} + +/************************ dump hook statistics ******************************/ +void dump_ste_stats(struct acm_ste_stats_buffer *ste_stats) +{ + printf("STE-Policy Security Hook Statistics:\n"); + printf("ste: event_channel eval_count = %d\n", + ntohl(ste_stats->ec_eval_count)); + printf("ste: event_channel denied_count = %d\n", + ntohl(ste_stats->ec_denied_count)); + printf("ste: event_channel cache_hit_count = %d\n", + ntohl(ste_stats->ec_cachehit_count)); + printf("ste:\n"); + printf("ste: grant_table eval_count = %d\n", + ntohl(ste_stats->gt_eval_count)); + printf("ste: grant_table denied_count = %d\n", + ntohl(ste_stats->gt_denied_count)); + printf("ste: grant_table cache_hit_count = %d\n", + ntohl(ste_stats->gt_cachehit_count)); +} + +#define PULL_STATS_SIZE 8192 +int acm_domain_dumpstats(int xc_handle) +{ + u8 stats_buffer[PULL_STATS_SIZE]; + acm_op_t op; + int ret; + struct acm_stats_buffer *stats; + + memset(stats_buffer, 0x00, sizeof(stats_buffer)); + op.cmd = ACM_DUMPSTATS; + op.interface_version = ACM_INTERFACE_VERSION; + op.u.dumpstats.pullcache = (void *) stats_buffer; + op.u.dumpstats.pullcache_size = sizeof(stats_buffer); + ret = do_acm_op(xc_handle, &op); + + if (ret < 0) + { + printf("ERROR dumping policy stats. Use 'xm dmesg' to see details.\n"); + return ret; + } + stats = (struct acm_stats_buffer *) stats_buffer; + + printf("\nPolicy dump:\n"); + printf("============\n"); + printf("Magic = %x.\n", ntohl(stats->magic)); + printf("Len = %x.\n", ntohl(stats->len)); + + switch (ntohl(stats->primary_policy_code)) + { + case ACM_NULL_POLICY: + printf("NULL Policy: No statistics apply.\n"); + break; + + case ACM_CHINESE_WALL_POLICY: + printf("Chinese Wall Policy: No statistics apply.\n"); + break; + + case ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY: + dump_ste_stats((struct acm_ste_stats_buffer *) (stats_buffer + + ntohl(stats-> + primary_stats_offset))); + break; + + default: + printf("UNKNOWN PRIMARY POLICY ERROR!\n"); + } + + switch (ntohl(stats->secondary_policy_code)) + { + case ACM_NULL_POLICY: + printf("NULL Policy: No statistics apply.\n"); + break; + + case ACM_CHINESE_WALL_POLICY: + printf("Chinese Wall Policy: No statistics apply.\n"); + break; + + case ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY: + dump_ste_stats((struct acm_ste_stats_buffer *) (stats_buffer + + ntohl(stats-> + secondary_stats_offset))); + break; + + default: + printf("UNKNOWN SECONDARY POLICY ERROR!\n"); + } + return ret; +} + +/***************************** main **************************************/ + +void usage(char *progname) +{ + printf("Use: %s \n" + "\t setpolicy\n" + "\t getpolicy\n" + "\t dumpstats\n" + "\t loadpolicy <binary policy file>\n", progname); + exit(-1); +} + +int main(int argc, char **argv) +{ + + int acm_cmd_fd, ret; + + if (argc < 2) + usage(argv[0]); + + if ((acm_cmd_fd = open("/proc/xen/privcmd", O_RDONLY)) <= 0) + { + printf("ERROR: Could not open xen privcmd device!\n"); + exit(-1); + } + + if (!strcmp(argv[1], "setpolicy")) + { + if (argc != 2) + usage(argv[0]); + ret = acm_domain_setpolicy(acm_cmd_fd); + } else if (!strcmp(argv[1], "getpolicy")) { + if (argc != 2) + usage(argv[0]); + ret = acm_domain_getpolicy(acm_cmd_fd); + } else if (!strcmp(argv[1], "loadpolicy")) { + if (argc != 3) + usage(argv[0]); + ret = acm_domain_loadpolicy(acm_cmd_fd, argv[2]); + } else if (!strcmp(argv[1], "dumpstats")) { + if (argc != 2) + usage(argv[0]); + ret = acm_domain_dumpstats(acm_cmd_fd); + } else + usage(argv[0]); + + close(acm_cmd_fd); + return ret; +} diff -r 9be7fe98a556 -r e173a853dc46 xen/common/acm_ops.c --- /dev/null Tue Aug 2 10:47:41 2005 +++ b/xen/common/acm_ops.c Tue Aug 2 17:20:46 2005 @@ -0,0 +1,127 @@ +/****************************************************************************** + * acm_ops.c + * + * Copyright (C) 2005 IBM Corporation + * + * Author: + * Reiner Sailer <sailer@xxxxxxxxxxxxxx> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation, version 2 of the + * License. + * + * Process acm command requests from guest OS. + * + */ + +#include <xen/config.h> +#include <xen/types.h> +#include <xen/lib.h> +#include <xen/mm.h> +#include <public/acm_ops.h> +#include <xen/sched.h> +#include <xen/event.h> +#include <xen/trace.h> +#include <xen/console.h> +#include <asm/shadow.h> +#include <public/sched_ctl.h> +#include <acm/acm_hooks.h> + +#if (ACM_USE_SECURITY_POLICY == ACM_NULL_POLICY) + +long do_acm_op(acm_op_t * u_acm_op) +{ + return -ENOSYS; +} + +#else + +typedef enum acm_operation { + POLICY, /* access to policy interface (early drop) */ + GETPOLICY, /* dump policy cache */ + SETPOLICY, /* set policy cache (controls security) */ + DUMPSTATS /* dump policy statistics */ +} acm_operation_t; + +int acm_authorize_acm_ops(struct domain *d, acm_operation_t pops) +{ + /* all policy management functions are restricted to privileged domains, + * soon we will introduce finer-grained privileges for policy operations + */ + if (!IS_PRIV(d)) + { + printk("%s: ACM management authorization denied ERROR!\n", __func__); + return ACM_ACCESS_DENIED; + } + return ACM_ACCESS_PERMITTED; +} + +long do_acm_op(acm_op_t * u_acm_op) +{ + long ret = 0; + acm_op_t curop, *op = &curop; + + /* check here policy decision for policy commands */ + /* for now allow DOM0 only, later indepedently */ + if (acm_authorize_acm_ops(current->domain, POLICY)) + return -EACCES; + + if (copy_from_user(op, u_acm_op, sizeof(*op))) + return -EFAULT; + + if (op->interface_version != ACM_INTERFACE_VERSION) + return -EACCES; + + switch (op->cmd) + { + case ACM_SETPOLICY: + { + if (acm_authorize_acm_ops(current->domain, SETPOLICY)) + return -EACCES; + printkd("%s: setting policy.\n", __func__); + ret = acm_set_policy(op->u.setpolicy.pushcache, + op->u.setpolicy.pushcache_size, 1); + if (ret == ACM_OK) + ret = 0; + else + ret = -ESRCH; + } + break; + + case ACM_GETPOLICY: + { + if (acm_authorize_acm_ops(current->domain, GETPOLICY)) + return -EACCES; + printkd("%s: getting policy.\n", __func__); + ret = acm_get_policy(op->u.getpolicy.pullcache, + op->u.getpolicy.pullcache_size); + if (ret == ACM_OK) + ret = 0; + else + ret = -ESRCH; + } + break; + + case ACM_DUMPSTATS: + { + if (acm_authorize_acm_ops(current->domain, DUMPSTATS)) + return -EACCES; + printkd("%s: dumping statistics.\n", __func__); + ret = acm_dump_statistics(op->u.dumpstats.pullcache, + op->u.dumpstats.pullcache_size); + if (ret == ACM_OK) + ret = 0; + else + ret = -ESRCH; + } + break; + + default: + ret = -ESRCH; + + } + return ret; +} + +#endif diff -r 9be7fe98a556 -r e173a853dc46 xen/include/public/acm_ops.h --- /dev/null Tue Aug 2 10:47:41 2005 +++ b/xen/include/public/acm_ops.h Tue Aug 2 17:20:46 2005 @@ -0,0 +1,66 @@ +/****************************************************************************** + * acm_ops.h + * + * Copyright (C) 2005 IBM Corporation + * + * Author: + * Reiner Sailer <sailer@xxxxxxxxxxxxxx> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation, version 2 of the + * License. + * + * Process acm policy command requests from guest OS. + * access checked by policy; not restricted to DOM0 + * + */ + +#ifndef __XEN_PUBLIC_ACM_OPS_H__ +#define __XEN_PUBLIC_ACM_OPS_H__ + +#include "xen.h" +#include "sched_ctl.h" + +/* + * Make sure you increment the interface version whenever you modify this file! + * This makes sure that old versions of acm tools will stop working in a + * well-defined way (rather than crashing the machine, for instance). + */ +#define ACM_INTERFACE_VERSION 0xAAAA0003 + +/************************************************************************/ + +#define ACM_SETPOLICY 4 +typedef struct acm_setpolicy { + /* OUT variables */ + void *pushcache; + u16 pushcache_size; +} acm_setpolicy_t; + + +#define ACM_GETPOLICY 5 +typedef struct acm_getpolicy { + /* OUT variables */ + void *pullcache; + u16 pullcache_size; +} acm_getpolicy_t; + +#define ACM_DUMPSTATS 6 +typedef struct acm_dumpstats { + void *pullcache; + u16 pullcache_size; +} acm_dumpstats_t; + + +typedef struct acm_op { + u32 cmd; + u32 interface_version; /* ACM_INTERFACE_VERSION */ + union { + acm_setpolicy_t setpolicy; + acm_getpolicy_t getpolicy; + acm_dumpstats_t dumpstats; + } u; +} acm_op_t; + +#endif /* __XEN_PUBLIC_ACM_OPS_H__ */ diff -r 9be7fe98a556 -r e173a853dc46 linux-2.6-xen-sparse/kernel/ptrace.c --- a/linux-2.6-xen-sparse/kernel/ptrace.c Tue Aug 2 10:47:41 2005 +++ /dev/null Tue Aug 2 17:20:46 2005 @@ -1,391 +0,0 @@ -/* - * linux/kernel/ptrace.c - * - * (C) Copyright 1999 Linus Torvalds - * - * Common interfaces for "ptrace()" which we do not want - * to continually duplicate across every architecture. - */ - -#include <linux/module.h> -#include <linux/sched.h> -#include <linux/errno.h> -#include <linux/mm.h> -#include <linux/highmem.h> -#include <linux/pagemap.h> -#include <linux/smp_lock.h> -#include <linux/ptrace.h> -#include <linux/security.h> -#include <linux/signal.h> - -#include <asm/pgtable.h> -#include <asm/uaccess.h> - -/* - * ptrace a task: make the debugger its new parent and - * move it to the ptrace list. - * - * Must be called with the tasklist lock write-held. - */ -void __ptrace_link(task_t *child, task_t *new_parent) -{ - if (!list_empty(&child->ptrace_list)) - BUG(); - if (child->parent == new_parent) - return; - list_add(&child->ptrace_list, &child->parent->ptrace_children); - REMOVE_LINKS(child); - child->parent = new_parent; - SET_LINKS(child); -} - -/* - * Turn a tracing stop into a normal stop now, since with no tracer there - * would be no way to wake it up with SIGCONT or SIGKILL. If there was a - * signal sent that would resume the child, but didn't because it was in - * TASK_TRACED, resume it now. - * Requires that irqs be disabled. - */ -void ptrace_untrace(task_t *child) -{ - spin_lock(&child->sighand->siglock); - if (child->state == TASK_TRACED) { - if (child->signal->flags & SIGNAL_STOP_STOPPED) { - child->state = TASK_STOPPED; - } else { - signal_wake_up(child, 1); - } - } - spin_unlock(&child->sighand->siglock); -} - -/* - * unptrace a task: move it back to its original parent and - * remove it from the ptrace list. - * - * Must be called with the tasklist lock write-held. - */ -void __ptrace_unlink(task_t *child) -{ - if (!child->ptrace) - BUG(); - child->ptrace = 0; - if (!list_empty(&child->ptrace_list)) { - list_del_init(&child->ptrace_list); - REMOVE_LINKS(child); - child->parent = child->real_parent; - SET_LINKS(child); - } - - if (child->state == TASK_TRACED) - ptrace_untrace(child); -} - -/* - * Check that we have indeed attached to the thing.. - */ -int ptrace_check_attach(struct task_struct *child, int kill) -{ - int ret = -ESRCH; - - /* - * We take the read lock around doing both checks to close a - * possible race where someone else was tracing our child and - * detached between these two checks. After this locked check, - * we are sure that this is our traced child and that can only - * be changed by us so it's not changing right after this. - */ - read_lock(&tasklist_lock); - if ((child->ptrace & PT_PTRACED) && child->parent == current && - (!(child->ptrace & PT_ATTACHED) || child->real_parent != current) - && child->signal != NULL) { - ret = 0; - spin_lock_irq(&child->sighand->siglock); - if (child->state == TASK_STOPPED) { - child->state = TASK_TRACED; - } else if (child->state != TASK_TRACED && !kill) { - ret = -ESRCH; - } - spin_unlock_irq(&child->sighand->siglock); - } - read_unlock(&tasklist_lock); - - if (!ret && !kill) { - wait_task_inactive(child); - } - - /* All systems go.. */ - return ret; -} - -int ptrace_attach(struct task_struct *task) -{ - int retval; - task_lock(task); - retval = -EPERM; - if (task->pid <= 1) - goto bad; - if (task == current) - goto bad; - if (!task->mm) - goto bad; - if(((current->uid != task->euid) || - (current->uid != task->suid) || - (current->uid != task->uid) || - (current->gid != task->egid) || - (current->gid != task->sgid) || - (current->gid != task->gid)) && !capable(CAP_SYS_PTRACE)) - goto bad; - smp_rmb(); - if (!task->mm->dumpable && !capable(CAP_SYS_PTRACE)) - goto bad; - /* the same process cannot be attached many times */ - if (task->ptrace & PT_PTRACED) - goto bad; - retval = security_ptrace(current, task); - if (retval) - goto bad; - - /* Go */ - task->ptrace |= PT_PTRACED | ((task->real_parent != current) - ? PT_ATTACHED : 0); - if (capable(CAP_SYS_PTRACE)) - task->ptrace |= PT_PTRACE_CAP; - task_unlock(task); - - write_lock_irq(&tasklist_lock); - __ptrace_link(task, current); - write_unlock_irq(&tasklist_lock); - - force_sig_specific(SIGSTOP, task); - return 0; - -bad: - task_unlock(task); - return retval; -} - -int ptrace_detach(struct task_struct *child, unsigned int data) -{ - if (!valid_signal(data)) - return -EIO; - - /* Architecture-specific hardware disable .. */ - ptrace_disable(child); - - /* .. re-parent .. */ - child->exit_code = data; - - write_lock_irq(&tasklist_lock); - __ptrace_unlink(child); - /* .. and wake it up. */ - if (child->exit_state != EXIT_ZOMBIE) - wake_up_process(child); - write_unlock_irq(&tasklist_lock); - - return 0; -} - -/* - * Access another process' address space. - * Source/target buffer must be kernel space, - * Do not walk the page table directly, use get_user_pages - */ - -int access_process_vm(struct task_struct *tsk, unsigned long addr, void *buf, int len, int write) -{ - struct mm_struct *mm; - struct vm_area_struct *vma; - struct page *page; - void *old_buf = buf; - - mm = get_task_mm(tsk); - if (!mm) - return 0; - - down_read(&mm->mmap_sem); - /* ignore errors, just check how much was sucessfully transfered */ - while (len) { - int bytes, ret, offset; - void *maddr; - - ret = get_user_pages(tsk, mm, addr, 1, - write, 1, &page, &vma); - if (ret <= 0) - break; - - bytes = len; - offset = addr & (PAGE_SIZE-1); - if (bytes > PAGE_SIZE-offset) - bytes = PAGE_SIZE-offset; - - maddr = kmap(page); - if (write) { - copy_to_user_page(vma, page, addr, - maddr + offset, buf, bytes); - set_page_dirty_lock(page); - } else { - copy_from_user_page(vma, page, addr, - buf, maddr + offset, bytes); - } - kunmap(page); - page_cache_release(page); - len -= bytes; - buf += bytes; - addr += bytes; - } - up_read(&mm->mmap_sem); - mmput(mm); - - return buf - old_buf; -} -EXPORT_SYMBOL(access_process_vm); - -int ptrace_readdata(struct task_struct *tsk, unsigned long src, char __user *dst, int len) -{ - int copied = 0; - - while (len > 0) { - char buf[128]; - int this_len, retval; - - this_len = (len > sizeof(buf)) ? sizeof(buf) : len; - retval = access_process_vm(tsk, src, buf, this_len, 0); - if (!retval) { - if (copied) - break; - return -EIO; - } - if (copy_to_user(dst, buf, retval)) - return -EFAULT; - copied += retval; - src += retval; - dst += retval; - len -= retval; - } - return copied; -} - -int ptrace_writedata(struct task_struct *tsk, char __user *src, unsigned long dst, int len) -{ - int copied = 0; - - while (len > 0) { - char buf[128]; - int this_len, retval; - - this_len = (len > sizeof(buf)) ? sizeof(buf) : len; - if (copy_from_user(buf, src, this_len)) - return -EFAULT; - retval = access_process_vm(tsk, dst, buf, this_len, 1); - if (!retval) { - if (copied) - break; - return -EIO; - } - copied += retval; - src += retval; - dst += retval; - len -= retval; - } - return copied; -} - -static int ptrace_setoptions(struct task_struct *child, long data) -{ - child->ptrace &= ~PT_TRACE_MASK; - - if (data & PTRACE_O_TRACESYSGOOD) - child->ptrace |= PT_TRACESYSGOOD; - - if (data & PTRACE_O_TRACEFORK) - child->ptrace |= PT_TRACE_FORK; - - if (data & PTRACE_O_TRACEVFORK) - child->ptrace |= PT_TRACE_VFORK; - - if (data & PTRACE_O_TRACECLONE) - child->ptrace |= PT_TRACE_CLONE; - - if (data & PTRACE_O_TRACEEXEC) - child->ptrace |= PT_TRACE_EXEC; - - if (data & PTRACE_O_TRACEVFORKDONE) - child->ptrace |= PT_TRACE_VFORK_DONE; - - if (data & PTRACE_O_TRACEEXIT) - child->ptrace |= PT_TRACE_EXIT; - - return (data & ~PTRACE_O_MASK) ? -EINVAL : 0; -} - -static int ptrace_getsiginfo(struct task_struct *child, siginfo_t __user * data) -{ - siginfo_t lastinfo; - int error = -ESRCH; - - read_lock(&tasklist_lock); - if (likely(child->sighand != NULL)) { - error = -EINVAL; - spin_lock_irq(&child->sighand->siglock); - if (likely(child->last_siginfo != NULL)) { - lastinfo = *child->last_siginfo; - error = 0; - } - spin_unlock_irq(&child->sighand->siglock); - } - read_unlock(&tasklist_lock); - if (!error) - return copy_siginfo_to_user(data, &lastinfo); - return error; -} - -static int ptrace_setsiginfo(struct task_struct *child, siginfo_t __user * data) -{ - siginfo_t newinfo; - int error = -ESRCH; - - if (copy_from_user(&newinfo, data, sizeof (siginfo_t))) - return -EFAULT; - - read_lock(&tasklist_lock); - if (likely(child->sighand != NULL)) { - error = -EINVAL; - spin_lock_irq(&child->sighand->siglock); - if (likely(child->last_siginfo != NULL)) { - *child->last_siginfo = newinfo; - error = 0; - } - spin_unlock_irq(&child->sighand->siglock); - } - read_unlock(&tasklist_lock); - return error; -} - -int ptrace_request(struct task_struct *child, long request, - long addr, long data) -{ - int ret = -EIO; - - switch (request) { -#ifdef PTRACE_OLDSETOPTIONS - case PTRACE_OLDSETOPTIONS: -#endif - case PTRACE_SETOPTIONS: - ret = ptrace_setoptions(child, data); - break; - case PTRACE_GETEVENTMSG: - ret = put_user(child->ptrace_message, (unsigned long __user *) data); - break; - case PTRACE_GETSIGINFO: - ret = ptrace_getsiginfo(child, (siginfo_t __user *) data); - break; - case PTRACE_SETSIGINFO: - ret = ptrace_setsiginfo(child, (siginfo_t __user *) data); - break; - default: - break; - } - - return ret; -} diff -r 9be7fe98a556 -r e173a853dc46 tools/policy/Makefile --- a/tools/policy/Makefile Tue Aug 2 10:47:41 2005 +++ /dev/null Tue Aug 2 17:20:46 2005 @@ -1,36 +0,0 @@ -XEN_ROOT = ../.. -include $(XEN_ROOT)/tools/Rules.mk - -SRCS = policy_tool.c -CFLAGS += -static -CFLAGS += -Wall -CFLAGS += -Werror -CFLAGS += -O3 -CFLAGS += -fno-strict-aliasing -CFLAGS += -I. - -all: build -build: mk-symlinks - $(MAKE) policy_tool - -default: all - -install: all - -policy_tool : policy_tool.c - $(CC) $(CPPFLAGS) $(CFLAGS) -o $@ $< - -clean: - rm -rf policy_tool xen - - -LINUX_ROOT := $(XEN_ROOT)/linux-2.6-xen-sparse -mk-symlinks: - [ -e xen/linux ] || mkdir -p xen/linux - [ -e xen/io ] || mkdir -p xen/io - ( cd xen >/dev/null ; \ - ln -sf ../$(XEN_ROOT)/xen/include/public/*.h . ) - ( cd xen/io >/dev/null ; \ - ln -sf ../../$(XEN_ROOT)/xen/include/public/io/*.h . ) - ( cd xen/linux >/dev/null ; \ - ln -sf ../../$(LINUX_ROOT)/include/asm-xen/linux-public/*.h . ) diff -r 9be7fe98a556 -r e173a853dc46 tools/policy/policy_tool.c --- a/tools/policy/policy_tool.c Tue Aug 2 10:47:41 2005 +++ /dev/null Tue Aug 2 17:20:46 2005 @@ -1,552 +0,0 @@ -/**************************************************************** - * policy_tool.c - * - * Copyright (C) 2005 IBM Corporation - * - * Authors: - * Reiner Sailer <sailer@xxxxxxxxxxxxxx> - * Stefan Berger <stefanb@xxxxxxxxxxxxxx> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation, version 2 of the - * License. - * - * sHype policy management tool. This code runs in a domain and - * manages the Xen security policy by interacting with the - * Xen access control module via a /proc/xen/privcmd proc-ioctl, - * which is translated into a policy_op hypercall into Xen. - * - * todo: implement setpolicy to dynamically set a policy cache. - */ -#include <unistd.h> -#include <stdio.h> -#include <errno.h> -#include <fcntl.h> -#include <sys/mman.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <stdlib.h> -#include <sys/ioctl.h> -#include <string.h> -#include <stdint.h> -#include <netinet/in.h> - -typedef uint8_t u8; -typedef uint16_t u16; -typedef uint32_t u32; -typedef uint64_t u64; -typedef int8_t s8; -typedef int16_t s16; -typedef int32_t s32; -typedef int64_t s64; - -#include <xen/acm.h> - -#include <xen/policy_ops.h> - -#include <xen/linux/privcmd.h> - -#define ERROR(_m, _a...) \ - fprintf(stderr, "ERROR: " _m "\n" , ## _a ) - -#define PERROR(_m, _a...) \ - fprintf(stderr, "ERROR: " _m " (%d = %s)\n" , ## _a , \ - errno, strerror(errno)) - -static inline int do_policycmd(int xc_handle, - unsigned int cmd, - unsigned long data) -{ - return ioctl(xc_handle, cmd, data); -} - -static inline int do_xen_hypercall(int xc_handle, - privcmd_hypercall_t *hypercall) -{ - return do_policycmd(xc_handle, - IOCTL_PRIVCMD_HYPERCALL, - (unsigned long)hypercall); -} - -static inline int do_policy_op(int xc_handle, policy_op_t *op) -{ - int ret = -1; - privcmd_hypercall_t hypercall; - - op->interface_version = POLICY_INTERFACE_VERSION; - - hypercall.op = __HYPERVISOR_policy_op; - hypercall.arg[0] = (unsigned long)op; - - if ( mlock(op, sizeof(*op)) != 0 ) - { - PERROR("Could not lock memory for Xen policy hypercall"); - goto out1; - } - - if ( (ret = do_xen_hypercall(xc_handle, &hypercall)) < 0 ) - { - if ( errno == EACCES ) - fprintf(stderr, "POLICY operation failed -- need to" - " rebuild the user-space tool set?\n"); - goto out2; - } - - out2: (void)munlock(op, sizeof(*op)); - out1: return ret; -} - -/*************************** DUMPS *******************************/ - -void acm_dump_chinesewall_buffer(void *buf, int buflen) { - - struct acm_chwall_policy_buffer *cwbuf = (struct acm_chwall_policy_buffer *)buf; - domaintype_t *ssids, *conflicts, *running_types, *conflict_aggregate; - int i,j; - - - if (htons(cwbuf->policy_code) != ACM_CHINESE_WALL_POLICY) { - printf("CHINESE WALL POLICY CODE not found ERROR!!\n"); - return; - } - printf("\n\nChinese Wall policy:\n"); - printf("====================\n"); - printf("Max Types = %x.\n", ntohs(cwbuf->chwall_max_types)); - printf("Max Ssidrefs = %x.\n", ntohs(cwbuf->chwall_max_ssidrefs)); - printf("Max ConfSets = %x.\n", ntohs(cwbuf->chwall_max_conflictsets)); - printf("Ssidrefs Off = %x.\n", ntohs(cwbuf->chwall_ssid_offset)); - printf("Conflicts Off = %x.\n", ntohs(cwbuf->chwall_conflict_sets_offset)); - printf("Runing T. Off = %x.\n", ntohs(cwbuf->chwall_running_types_offset)); - printf("C. Agg. Off = %x.\n", ntohs(cwbuf->chwall_conflict_aggregate_offset)); - printf("\nSSID To CHWALL-Type matrix:\n"); - - ssids = (domaintype_t *)(buf + ntohs(cwbuf->chwall_ssid_offset)); - for(i=0; i< ntohs(cwbuf->chwall_max_ssidrefs); i++) { - printf("\n ssidref%2x: ", i); - for(j=0; j< ntohs(cwbuf->chwall_max_types); j++) - printf("%02x ", ntohs(ssids[i*ntohs(cwbuf->chwall_max_types) + j])); - } - printf("\n\nConfict Sets:\n"); - conflicts = (domaintype_t *)(buf + ntohs(cwbuf->chwall_conflict_sets_offset)); - for(i=0; i< ntohs(cwbuf->chwall_max_conflictsets); i++) { - printf("\n c-set%2x: ", i); - for(j=0; j< ntohs(cwbuf->chwall_max_types); j++) - printf("%02x ", ntohs(conflicts[i*ntohs(cwbuf->chwall_max_types) +j])); - } - printf("\n"); - - printf("\nRunning\nTypes: "); - if (ntohs(cwbuf->chwall_running_types_offset)) { - running_types = (domaintype_t *)(buf + ntohs(cwbuf->chwall_running_types_offset)); - for(i=0; i< ntohs(cwbuf->chwall_max_types); i++) { - printf("%02x ", ntohs(running_types[i])); - } - printf("\n"); - } else { - printf("Not Reported!\n"); - } - printf("\nConflict\nAggregate Set: "); - if (ntohs(cwbuf->chwall_conflict_aggregate_offset)) { - conflict_aggregate = (domaintype_t *)(buf + ntohs(cwbuf->chwall_conflict_aggregate_offset)); - for(i=0; i< ntohs(cwbuf->chwall_max_types); i++) { - printf("%02x ", ntohs(conflict_aggregate[i])); - } - printf("\n\n"); - } else { - printf("Not Reported!\n"); - } -} - -void acm_dump_ste_buffer(void *buf, int buflen) { - - struct acm_ste_policy_buffer *stebuf = (struct acm_ste_policy_buffer *)buf; - domaintype_t *ssids; - int i,j; - - - if (ntohs(stebuf->policy_code) != ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY) { - printf("SIMPLE TYPE ENFORCEMENT POLICY CODE not found ERROR!!\n"); - return; - } - printf("\nSimple Type Enforcement policy:\n"); - printf("===============================\n"); - printf("Max Types = %x.\n", ntohs(stebuf->ste_max_types)); - printf("Max Ssidrefs = %x.\n", ntohs(stebuf->ste_max_ssidrefs)); - printf("Ssidrefs Off = %x.\n", ntohs(stebuf->ste_ssid_offset)); - printf("\nSSID To STE-Type matrix:\n"); - - ssids = (domaintype_t *)(buf + ntohs(stebuf->ste_ssid_offset)); - for(i=0; i< ntohs(stebuf->ste_max_ssidrefs); i++) { - printf("\n ssidref%2x: ", i); - for(j=0; j< ntohs(stebuf->ste_max_types); j++) - printf("%02x ", ntohs(ssids[i*ntohs(stebuf->ste_max_types) +j])); - } - printf("\n\n"); -} - -void acm_dump_policy_buffer(void *buf, int buflen) { - struct acm_policy_buffer *pol = (struct acm_policy_buffer *)buf; - - printf("\nPolicy dump:\n"); - printf("============\n"); - printf("Magic = %x.\n", ntohl(pol->magic)); - printf("PolVer = %x.\n", ntohl(pol->policyversion)); - printf("Len = %x.\n", ntohl(pol->len)); - printf("Primary = %s (c=%x, off=%x).\n", - ACM_POLICY_NAME(ntohs(pol->primary_policy_code)), - ntohs(pol->primary_policy_code), ntohs(pol->primary_buffer_offset)); - printf("Secondary = %s (c=%x, off=%x).\n", - ACM_POLICY_NAME(ntohs(pol->secondary_policy_code)), - ntohs(pol->secondary_policy_code), ntohs(pol->secondary_buffer_offset)); - switch (ntohs(pol->primary_policy_code)) { - case ACM_CHINESE_WALL_POLICY: - acm_dump_chinesewall_buffer(buf+ntohs(pol->primary_buffer_offset), - ntohl(pol->len) - ntohs(pol->primary_buffer_offset)); - break; - case ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY: - acm_dump_ste_buffer(buf+ntohs(pol->primary_buffer_offset), - ntohl(pol->len) - ntohs(pol->primary_buffer_offset)); - break; - case ACM_NULL_POLICY: - printf("Primary policy is NULL Policy (n/a).\n"); - break; - default: - printf("UNKNOWN POLICY!\n"); - } - switch (ntohs(pol->secondary_policy_code)) { - case ACM_CHINESE_WALL_POLICY: - acm_dump_chinesewall_buffer(buf+ntohs(pol->secondary_buffer_offset), - ntohl(pol->len) - ntohs(pol->secondary_buffer_offset)); - break; - case ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY: - acm_dump_ste_buffer(buf+ntohs(pol->secondary_buffer_offset), - ntohl(pol->len) - ntohs(pol->secondary_buffer_offset)); - break; - case ACM_NULL_POLICY: - printf("Secondary policy is NULL Policy (n/a).\n"); - break; - default: - printf("UNKNOWN POLICY!\n"); - } -} - -/*************************** set policy ****************************/ - -int acm_domain_set_chwallpolicy(void *bufstart, int buflen) { -#define CWALL_MAX_SSIDREFS 6 -#define CWALL_MAX_TYPES 10 -#define CWALL_MAX_CONFLICTSETS 2 - - struct acm_chwall_policy_buffer *chwall_bin_pol = (struct acm_chwall_policy_buffer *)bufstart; - domaintype_t *ssidrefs, *conflicts; - int ret = 0; - int j; - - chwall_bin_pol->chwall_max_types = htons(CWALL_MAX_TYPES); - chwall_bin_pol->chwall_max_ssidrefs = htons(CWALL_MAX_SSIDREFS); - chwall_bin_pol->policy_code = htons(ACM_CHINESE_WALL_POLICY); - chwall_bin_pol->chwall_ssid_offset = htons(sizeof(struct acm_chwall_policy_buffer)); - chwall_bin_pol->chwall_max_conflictsets = htons(CWALL_MAX_CONFLICTSETS); - chwall_bin_pol->chwall_conflict_sets_offset = - htons( - ntohs(chwall_bin_pol->chwall_ssid_offset) + - sizeof(domaintype_t)*CWALL_MAX_SSIDREFS*CWALL_MAX_TYPES); - chwall_bin_pol->chwall_running_types_offset = 0; /* not set */ - chwall_bin_pol->chwall_conflict_aggregate_offset = 0; /* not set */ - ret += sizeof(struct acm_chwall_policy_buffer); - /* now push example ssids into the buffer (max_ssidrefs x max_types entries) */ - /* check buffer size */ - if ((buflen - ret) < (CWALL_MAX_TYPES*CWALL_MAX_SSIDREFS*sizeof(domaintype_t))) - return -1; /* not enough space */ - - ssidrefs = (domaintype_t *)(bufstart+ntohs(chwall_bin_pol->chwall_ssid_offset)); - memset(ssidrefs, 0, CWALL_MAX_TYPES*CWALL_MAX_SSIDREFS*sizeof(domaintype_t)); - - /* now set type j-1 for ssidref i+1 */ - for(j=0; j<= CWALL_MAX_SSIDREFS; j++) - if ((0 < j) &&( j <= CWALL_MAX_TYPES)) - ssidrefs[j*CWALL_MAX_TYPES + j - 1] = htons(1); - - ret += CWALL_MAX_TYPES*CWALL_MAX_SSIDREFS*sizeof(domaintype_t); - if ((buflen - ret) < (CWALL_MAX_CONFLICTSETS*CWALL_MAX_TYPES*sizeof(domaintype_t))) - return -1; /* not enough space */ - - /* now the chinese wall policy conflict sets*/ - conflicts = (domaintype_t *)(bufstart + - ntohs(chwall_bin_pol->chwall_conflict_sets_offset)); - memset((void *)conflicts, 0, CWALL_MAX_CONFLICTSETS*CWALL_MAX_TYPES*sizeof(domaintype_t)); - /* just 1 conflict set [0]={2,3}, [1]={1,5,6} */ - if (CWALL_MAX_TYPES > 3) { - conflicts[2] = htons(1); conflicts[3] = htons(1); /* {2,3} */ - conflicts[CWALL_MAX_TYPES+1] = htons(1); conflicts[CWALL_MAX_TYPES+5] = htons(1); - conflicts[CWALL_MAX_TYPES+6] = htons(1);/* {0,5,6} */ - } - ret += sizeof(domaintype_t)*CWALL_MAX_CONFLICTSETS*CWALL_MAX_TYPES; - return ret; -} - -int acm_domain_set_stepolicy(void *bufstart, int buflen) { -#define STE_MAX_SSIDREFS 6 -#define STE_MAX_TYPES 5 - - struct acm_ste_policy_buffer *ste_bin_pol = (struct acm_ste_policy_buffer *)bufstart; - domaintype_t *ssidrefs; - int j, ret = 0; - - ste_bin_pol->ste_max_types = htons(STE_MAX_TYPES); - ste_bin_pol->ste_max_ssidrefs = htons(STE_MAX_SSIDREFS); - ste_bin_pol->policy_code = htons(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY); - ste_bin_pol->ste_ssid_offset = htons(sizeof(struct acm_ste_policy_buffer)); - ret += sizeof(struct acm_ste_policy_buffer); - /* check buffer size */ - if ((buflen - ret) < (STE_MAX_TYPES*STE_MAX_SSIDREFS*sizeof(domaintype_t))) - return -1; /* not enough space */ - - ssidrefs = (domaintype_t *)(bufstart+ntohs(ste_bin_pol->ste_ssid_offset)); - memset(ssidrefs, 0, STE_MAX_TYPES*STE_MAX_SSIDREFS*sizeof(domaintype_t)); - /* all types 1 for ssidref 1 */ - for(j=0; j< STE_MAX_TYPES; j++) - ssidrefs[1*STE_MAX_TYPES +j] = htons(1); - /* now set type j-1 for ssidref j */ - for(j=0; j< STE_MAX_SSIDREFS; j++) - if ((0 < j) &&( j <= STE_MAX_TYPES)) - ssidrefs[j*STE_MAX_TYPES + j - 1] = htons(1); - ret += STE_MAX_TYPES*STE_MAX_SSIDREFS*sizeof(domaintype_t); - return ret; -} - -#define MAX_PUSH_BUFFER 16384 -u8 push_buffer[MAX_PUSH_BUFFER]; - -int acm_domain_setpolicy(int xc_handle) -{ - int ret; - struct acm_policy_buffer *bin_pol; - policy_op_t op; - - /* future: read policy from file and set it */ - bin_pol = (struct acm_policy_buffer *)push_buffer; - bin_pol->magic = htonl(ACM_MAGIC); - bin_pol->policyversion = htonl(POLICY_INTERFACE_VERSION); - bin_pol->primary_policy_code = htons(ACM_CHINESE_WALL_POLICY); - bin_pol->secondary_policy_code = htons(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY); - - bin_pol->len = htonl(sizeof(struct acm_policy_buffer)); - bin_pol->primary_buffer_offset = htons(ntohl(bin_pol->len)); - ret = acm_domain_set_chwallpolicy(push_buffer + ntohs(bin_pol->primary_buffer_offset), - MAX_PUSH_BUFFER - ntohs(bin_pol->primary_buffer_offset)); - if (ret < 0) { - printf("ERROR creating chwallpolicy buffer.\n"); - return -1; - } - bin_pol->len = htonl(ntohl(bin_pol->len) + ret); - bin_pol->secondary_buffer_offset = htons(ntohl(bin_pol->len)); - ret = acm_domain_set_stepolicy(push_buffer + ntohs(bin_pol->secondary_buffer_offset), - MAX_PUSH_BUFFER - ntohs(bin_pol->secondary_buffer_offset)); - if (ret < 0) { - printf("ERROR creating chwallpolicy buffer.\n"); - return -1; - } - bin_pol->len = htonl(ntohl(bin_pol->len) + ret); - - /* dump it and then push it down into xen/acm */ - acm_dump_policy_buffer(push_buffer, ntohl(bin_pol->len)); - op.cmd = POLICY_SETPOLICY; - op.u.setpolicy.pushcache = (void *)push_buffer; - op.u.setpolicy.pushcache_size = ntohl(bin_pol->len); - op.u.setpolicy.policy_type = ACM_CHINESE_WALL_AND_SIMPLE_TYPE_ENFORCEMENT_POLICY; - ret = do_policy_op(xc_handle, &op); - - if (ret) - printf("ERROR setting policy. Use 'xm dmesg' to see details.\n"); - else - printf("Successfully changed policy.\n"); - return ret; -} - -/******************************* get policy ******************************/ - -#define PULL_CACHE_SIZE 8192 -u8 pull_buffer[PULL_CACHE_SIZE]; -int acm_domain_getpolicy(int xc_handle) -{ - policy_op_t op; - int ret; - - memset(pull_buffer, 0x00, sizeof(pull_buffer)); - op.cmd = POLICY_GETPOLICY; - op.u.getpolicy.pullcache = (void *)pull_buffer; - op.u.getpolicy.pullcache_size = sizeof(pull_buffer); - ret = do_policy_op(xc_handle, &op); - /* dump policy */ - acm_dump_policy_buffer(pull_buffer, sizeof(pull_buffer)); - return ret; -} - -/************************ load binary policy ******************************/ - -int acm_domain_loadpolicy(int xc_handle, - const char *filename) -{ - struct stat mystat; - int ret, fd; - off_t len; - u8 *buffer; - - if ((ret = stat(filename, &mystat))) { - printf("File %s not found.\n",filename); - goto out; - } - - len = mystat.st_size; - if ((buffer = malloc(len)) == NULL) { - ret = -ENOMEM; - goto out; - } - if ((fd = open(filename, O_RDONLY)) <= 0) { - ret = -ENOENT; - printf("File %s not found.\n",filename); - goto free_out; - } - if (len == read(fd, buffer, len)) { - policy_op_t op; - /* dump it and then push it down into xen/acm */ - acm_dump_policy_buffer(buffer, len); - op.cmd = POLICY_SETPOLICY; - op.u.setpolicy.pushcache = (void *)buffer; - op.u.setpolicy.pushcache_size = len; - op.u.setpolicy.policy_type = ACM_CHINESE_WALL_AND_SIMPLE_TYPE_ENFORCEMENT_POLICY; - ret = do_policy_op(xc_handle, &op); - - if (ret) - printf("ERROR setting policy. Use 'xm dmesg' to see details.\n"); - else - printf("Successfully changed policy.\n"); - - } else { - ret = -1; - } - close(fd); - free_out: - free(buffer); - out: - return ret; -} - -/************************ dump hook statistics ******************************/ -void -dump_ste_stats(struct acm_ste_stats_buffer *ste_stats) -{ - printf("STE-Policy Security Hook Statistics:\n"); - printf("ste: event_channel eval_count = %d\n", ntohl(ste_stats->ec_eval_count)); - printf("ste: event_channel denied_count = %d\n", ntohl(ste_stats->ec_denied_count)); - printf("ste: event_channel cache_hit_count = %d\n", ntohl(ste_stats->ec_cachehit_count)); - printf("ste:\n"); - printf("ste: grant_table eval_count = %d\n", ntohl(ste_stats->gt_eval_count)); - printf("ste: grant_table denied_count = %d\n", ntohl(ste_stats->gt_denied_count)); - printf("ste: grant_table cache_hit_count = %d\n", ntohl(ste_stats->gt_cachehit_count)); -} - -#define PULL_STATS_SIZE 8192 -int acm_domain_dumpstats(int xc_handle) -{ - u8 stats_buffer[PULL_STATS_SIZE]; - policy_op_t op; - int ret; - struct acm_stats_buffer *stats; - - memset(stats_buffer, 0x00, sizeof(stats_buffer)); - op.cmd = POLICY_DUMPSTATS; - op.u.dumpstats.pullcache = (void *)stats_buffer; - op.u.dumpstats.pullcache_size = sizeof(stats_buffer); - ret = do_policy_op(xc_handle, &op); - - if (ret < 0) { - printf("ERROR dumping policy stats. Use 'xm dmesg' to see details.\n"); - return ret; - } - stats = (struct acm_stats_buffer *)stats_buffer; - - printf("\nPolicy dump:\n"); - printf("============\n"); - printf("Magic = %x.\n", ntohl(stats->magic)); - printf("PolVer = %x.\n", ntohl(stats->policyversion)); - printf("Len = %x.\n", ntohl(stats->len)); - - switch(ntohs(stats->primary_policy_code)) { - case ACM_NULL_POLICY: - printf("NULL Policy: No statistics apply.\n"); - break; - case ACM_CHINESE_WALL_POLICY: - printf("Chinese Wall Policy: No statistics apply.\n"); - break; - case ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY: - dump_ste_stats((struct acm_ste_stats_buffer *)(stats_buffer + ntohs(stats->primary_stats_offset))); - break; - default: - printf("UNKNOWN PRIMARY POLICY ERROR!\n"); - } - switch(ntohs(stats->secondary_policy_code)) { - case ACM_NULL_POLICY: - printf("NULL Policy: No statistics apply.\n"); - break; - case ACM_CHINESE_WALL_POLICY: - printf("Chinese Wall Policy: No statistics apply.\n"); - break; - case ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY: - dump_ste_stats((struct acm_ste_stats_buffer *)(stats_buffer + ntohs(stats->secondary_stats_offset))); - break; - default: - printf("UNKNOWN SECONDARY POLICY ERROR!\n"); - } - return ret; -} - -/***************************** main **************************************/ - -void -usage(char *progname){ - printf("Use: %s \n" - "\t setpolicy\n" - "\t getpolicy\n" - "\t dumpstats\n" - "\t loadpolicy <binary policy file>\n", progname); - exit(-1); -} - -int -main(int argc, char **argv) { - - int policycmd_fd, ret; - - if (argc < 2) - usage(argv[0]); - - if ((policycmd_fd = open("/proc/xen/privcmd", O_RDONLY)) <= 0) { - printf("ERROR: Could not open xen privcmd device!\n"); - exit(-1); - } - - if (!strcmp(argv[1], "setpolicy")) { - if (argc != 2) - usage(argv[0]); - ret = acm_domain_setpolicy(policycmd_fd); - } else if (!strcmp(argv[1], "getpolicy")) { - if (argc != 2) - usage(argv[0]); - ret = acm_domain_getpolicy(policycmd_fd); - } else if (!strcmp(argv[1], "loadpolicy")) { - if (argc != 3) - usage(argv[0]); - ret = acm_domain_loadpolicy(policycmd_fd, argv[2]); - } else if (!strcmp(argv[1], "dumpstats")) { - if (argc != 2) - usage(argv[0]); - ret = acm_domain_dumpstats(policycmd_fd); - } else - usage(argv[0]); - - close(policycmd_fd); - return ret; -} diff -r 9be7fe98a556 -r e173a853dc46 xen/common/policy_ops.c --- a/xen/common/policy_ops.c Tue Aug 2 10:47:41 2005 +++ /dev/null Tue Aug 2 17:20:46 2005 @@ -1,133 +0,0 @@ -/****************************************************************************** - * policy_ops.c - * - * Copyright (C) 2005 IBM Corporation - * - * Author: - * Reiner Sailer <sailer@xxxxxxxxxxxxxx> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation, version 2 of the - * License. - * - * Process policy command requests from guest OS. - * - */ - -#include <xen/config.h> -#include <xen/types.h> -#include <xen/lib.h> -#include <xen/mm.h> -#include <public/policy_ops.h> -#include <xen/sched.h> -#include <xen/event.h> -#include <xen/trace.h> -#include <xen/console.h> -#include <asm/shadow.h> -#include <public/sched_ctl.h> -#include <acm/acm_hooks.h> - -#if (ACM_USE_SECURITY_POLICY == ACM_NULL_POLICY) - -long do_policy_op(policy_op_t *u_policy_op) -{ - return -ENOSYS; -} - -#else - -typedef enum policyoperation { - POLICY, /* access to policy interface (early drop) */ - GETPOLICY, /* dump policy cache */ - SETPOLICY, /* set policy cache (controls security) */ - DUMPSTATS /* dump policy statistics */ -} policyoperation_t; - -int -acm_authorize_policyops(struct domain *d, policyoperation_t pops) -{ - /* all policy management functions are restricted to privileged domains, - * soon we will introduce finer-grained privileges for policy operations - */ - if (!IS_PRIV(d)) { - printk("%s: Policy management authorization denied ERROR!\n", - __func__); - return ACM_ACCESS_DENIED; - } - return ACM_ACCESS_PERMITTED; -} - -long do_policy_op(policy_op_t *u_policy_op) -{ - long ret = 0; - policy_op_t curop, *op = &curop; - - /* check here policy decision for policy commands */ - /* for now allow DOM0 only, later indepedently */ - if (acm_authorize_policyops(current->domain, POLICY)) - return -EACCES; - - if ( copy_from_user(op, u_policy_op, sizeof(*op)) ) - return -EFAULT; - - if ( op->interface_version != POLICY_INTERFACE_VERSION ) - return -EACCES; - - switch ( op->cmd ) - { - case POLICY_SETPOLICY: - { - if (acm_authorize_policyops(current->domain, SETPOLICY)) - return -EACCES; - printkd("%s: setting policy.\n", __func__); - ret = acm_set_policy( - op->u.setpolicy.pushcache, - op->u.setpolicy.pushcache_size, - op->u.setpolicy.policy_type, - 1); - if (ret == ACM_OK) - ret = 0; - else - ret = -ESRCH; - } - break; - - case POLICY_GETPOLICY: - { - if (acm_authorize_policyops(current->domain, GETPOLICY)) - return -EACCES; - printkd("%s: getting policy.\n", __func__); - ret = acm_get_policy( - op->u.getpolicy.pullcache, - op->u.getpolicy.pullcache_size); - if (ret == ACM_OK) - ret = 0; - else - ret = -ESRCH; - } - break; - - case POLICY_DUMPSTATS: - { - if (acm_authorize_policyops(current->domain, DUMPSTATS)) - return -EACCES; - printkd("%s: dumping statistics.\n", __func__); - ret = acm_dump_statistics( - op->u.dumpstats.pullcache, - op->u.dumpstats.pullcache_size); - if (ret == ACM_OK) - ret = 0; - else - ret = -ESRCH; - } - break; - - default: - ret = -ESRCH; - - } - return ret; -} - -#endif diff -r 9be7fe98a556 -r e173a853dc46 xen/include/public/policy_ops.h --- a/xen/include/public/policy_ops.h Tue Aug 2 10:47:41 2005 +++ /dev/null Tue Aug 2 17:20:46 2005 @@ -1,70 +0,0 @@ -/****************************************************************************** - * policy_ops.h - * - * Copyright (C) 2005 IBM Corporation - * - * Author: - * Reiner Sailer <sailer@xxxxxxxxxxxxxx> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation, version 2 of the - * License. - * - * Process policy command requests from guest OS. - * access checked by policy; not restricted to DOM0 - * - */ - -#ifndef __XEN_PUBLIC_POLICY_OPS_H__ -#define __XEN_PUBLIC_POLICY_OPS_H__ - -#include "xen.h" -#include "sched_ctl.h" - -/* - * Make sure you increment the interface version whenever you modify this file! - * This makes sure that old versions of policy tools will stop working in a - * well-defined way (rather than crashing the machine, for instance). - */ -#define POLICY_INTERFACE_VERSION 0xAAAA0003 - -/************************************************************************/ - -#define POLICY_SETPOLICY 4 -typedef struct policy_setpolicy { - /* IN variables. */ - u16 policy_type; - /* OUT variables */ - void *pushcache; - u16 pushcache_size; -} policy_setpolicy_t; - - -#define POLICY_GETPOLICY 5 -typedef struct policy_getpolicy { - /* IN variables. */ - u16 policy_type; - /* OUT variables */ - void *pullcache; - u16 pullcache_size; -} policy_getpolicy_t; - -#define POLICY_DUMPSTATS 6 -typedef struct policy_dumpstats { - void *pullcache; - u16 pullcache_size; -} policy_dumpstats_t; - - -typedef struct policy_op { - u32 cmd; - u32 interface_version; /* POLICY_INTERFACE_VERSION */ - union { - policy_setpolicy_t setpolicy; - policy_getpolicy_t getpolicy; - policy_dumpstats_t dumpstats; - } u; -} policy_op_t; - -#endif /* __XEN_PUBLIC_POLICY_OPS_H__ */ _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |