[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] Merged.
# HG changeset patch # User emellor@xxxxxxxxxxxxxxxxxxxxxx # Node ID f31494465fb07d9f790716683d7b92eab4ac8835 # Parent 19af31a595377b48400441d8235ebbaff670e18a # Parent c3a0f492644cf3288e4144d85d73efc831d7333f Merged. diff -r 19af31a59537 -r f31494465fb0 tools/ioemu/exec-all.h --- a/tools/ioemu/exec-all.h Fri Oct 21 11:06:17 2005 +++ b/tools/ioemu/exec-all.h Fri Oct 21 11:07:14 2005 @@ -573,7 +573,7 @@ } #endif -#define DEBUG_UNUSED_IOPORT -#define DEBUG_IOPORT +//#define DEBUG_UNUSED_IOPORT +//#define DEBUG_IOPORT #define TARGET_VMX diff -r 19af31a59537 -r f31494465fb0 tools/ioemu/hw/cirrus_vga_rop2.h --- a/tools/ioemu/hw/cirrus_vga_rop2.h Fri Oct 21 11:06:17 2005 +++ b/tools/ioemu/hw/cirrus_vga_rop2.h Fri Oct 21 11:07:14 2005 @@ -47,6 +47,11 @@ int x, y, pattern_y, pattern_pitch, pattern_x; unsigned int col; const uint8_t *src1; +#if DEPTH == 24 + int skipleft = s->gr[0x2f] & 0x1f; +#else + int skipleft = (s->gr[0x2f] & 0x07) * (DEPTH / 8); +#endif #if DEPTH == 8 pattern_pitch = 8; @@ -56,11 +61,11 @@ pattern_pitch = 32; #endif pattern_y = s->cirrus_blt_srcaddr & 7; - pattern_x = 0; - for(y = 0; y < bltheight; y++) { - d = dst; + for(y = 0; y < bltheight; y++) { + pattern_x = skipleft; + d = dst + skipleft; src1 = src + pattern_y * pattern_pitch; - for (x = 0; x < bltwidth; x += (DEPTH / 8)) { + for (x = skipleft; x < bltwidth; x += (DEPTH / 8)) { #if DEPTH == 8 col = src1[pattern_x]; pattern_x = (pattern_x + 1) & 7; @@ -99,7 +104,13 @@ unsigned int col; unsigned bitmask; unsigned index; - int srcskipleft = 0; +#if DEPTH == 24 + int dstskipleft = s->gr[0x2f] & 0x1f; + int srcskipleft = dstskipleft / 3; +#else + int srcskipleft = s->gr[0x2f] & 0x07; + int dstskipleft = srcskipleft * (DEPTH / 8); +#endif if (s->cirrus_blt_modeext & CIRRUS_BLTMODEEXT_COLOREXPINV) { bits_xor = 0xff; @@ -112,8 +123,8 @@ for(y = 0; y < bltheight; y++) { bitmask = 0x80 >> srcskipleft; bits = *src++ ^ bits_xor; - d = dst; - for (x = 0; x < bltwidth; x += (DEPTH / 8)) { + d = dst + dstskipleft; + for (x = dstskipleft; x < bltwidth; x += (DEPTH / 8)) { if ((bitmask & 0xff) == 0) { bitmask = 0x80; bits = *src++ ^ bits_xor; @@ -142,15 +153,16 @@ unsigned bits; unsigned int col; unsigned bitmask; - int srcskipleft = 0; + int srcskipleft = s->gr[0x2f] & 0x07; + int dstskipleft = srcskipleft * (DEPTH / 8); colors[0] = s->cirrus_blt_bgcol; colors[1] = s->cirrus_blt_fgcol; for(y = 0; y < bltheight; y++) { bitmask = 0x80 >> srcskipleft; bits = *src++; - d = dst; - for (x = 0; x < bltwidth; x += (DEPTH / 8)) { + d = dst + dstskipleft; + for (x = dstskipleft; x < bltwidth; x += (DEPTH / 8)) { if ((bitmask & 0xff) == 0) { bitmask = 0x80; bits = *src++; @@ -175,6 +187,13 @@ int x, y, bitpos, pattern_y; unsigned int bits, bits_xor; unsigned int col; +#if DEPTH == 24 + int dstskipleft = s->gr[0x2f] & 0x1f; + int srcskipleft = dstskipleft / 3; +#else + int srcskipleft = s->gr[0x2f] & 0x07; + int dstskipleft = srcskipleft * (DEPTH / 8); +#endif if (s->cirrus_blt_modeext & CIRRUS_BLTMODEEXT_COLOREXPINV) { bits_xor = 0xff; @@ -187,9 +206,9 @@ for(y = 0; y < bltheight; y++) { bits = src[pattern_y] ^ bits_xor; - bitpos = 7; - d = dst; - for (x = 0; x < bltwidth; x += (DEPTH / 8)) { + bitpos = 7 - srcskipleft; + d = dst + dstskipleft; + for (x = dstskipleft; x < bltwidth; x += (DEPTH / 8)) { if ((bits >> bitpos) & 1) { PUTPIXEL(); } @@ -213,6 +232,8 @@ int x, y, bitpos, pattern_y; unsigned int bits; unsigned int col; + int srcskipleft = s->gr[0x2f] & 0x07; + int dstskipleft = srcskipleft * (DEPTH / 8); colors[0] = s->cirrus_blt_bgcol; colors[1] = s->cirrus_blt_fgcol; @@ -220,9 +241,9 @@ for(y = 0; y < bltheight; y++) { bits = src[pattern_y]; - bitpos = 7; - d = dst; - for (x = 0; x < bltwidth; x += (DEPTH / 8)) { + bitpos = 7 - srcskipleft; + d = dst + dstskipleft; + for (x = dstskipleft; x < bltwidth; x += (DEPTH / 8)) { col = colors[(bits >> bitpos) & 1]; PUTPIXEL(); d += (DEPTH / 8); diff -r 19af31a59537 -r f31494465fb0 tools/ioemu/hw/i8259.c --- a/tools/ioemu/hw/i8259.c Fri Oct 21 11:06:17 2005 +++ b/tools/ioemu/hw/i8259.c Fri Oct 21 11:07:14 2005 @@ -29,7 +29,7 @@ //#define DEBUG_PIC //#define DEBUG_IRQ_LATENCY -#define DEBUG_IRQ_COUNT +//#define DEBUG_IRQ_COUNT extern void pit_reset_vmx_vectors(); diff -r 19af31a59537 -r f31494465fb0 tools/ioemu/monitor.c --- a/tools/ioemu/monitor.c Fri Oct 21 11:06:17 2005 +++ b/tools/ioemu/monitor.c Fri Oct 21 11:07:14 2005 @@ -232,6 +232,161 @@ exit(0); } +typedef struct { + int keycode; + const char *name; +} KeyDef; + +static const KeyDef key_defs[] = { + { 0x2a, "shift" }, + { 0x36, "shift_r" }, + + { 0x38, "alt" }, + { 0xb8, "alt_r" }, + { 0x1d, "ctrl" }, + { 0x9d, "ctrl_r" }, + + { 0xdd, "menu" }, + + { 0x01, "esc" }, + + { 0x02, "1" }, + { 0x03, "2" }, + { 0x04, "3" }, + { 0x05, "4" }, + { 0x06, "5" }, + { 0x07, "6" }, + { 0x08, "7" }, + { 0x09, "8" }, + { 0x0a, "9" }, + { 0x0b, "0" }, + { 0x0e, "backspace" }, + + { 0x0f, "tab" }, + { 0x10, "q" }, + { 0x11, "w" }, + { 0x12, "e" }, + { 0x13, "r" }, + { 0x14, "t" }, + { 0x15, "y" }, + { 0x16, "u" }, + { 0x17, "i" }, + { 0x18, "o" }, + { 0x19, "p" }, + + { 0x1c, "ret" }, + + { 0x1e, "a" }, + { 0x1f, "s" }, + { 0x20, "d" }, + { 0x21, "f" }, + { 0x22, "g" }, + { 0x23, "h" }, + { 0x24, "j" }, + { 0x25, "k" }, + { 0x26, "l" }, + + { 0x2c, "z" }, + { 0x2d, "x" }, + { 0x2e, "c" }, + { 0x2f, "v" }, + { 0x30, "b" }, + { 0x31, "n" }, + { 0x32, "m" }, + + { 0x39, "spc" }, + { 0x3a, "caps_lock" }, + { 0x3b, "f1" }, + { 0x3c, "f2" }, + { 0x3d, "f3" }, + { 0x3e, "f4" }, + { 0x3f, "f5" }, + { 0x40, "f6" }, + { 0x41, "f7" }, + { 0x42, "f8" }, + { 0x43, "f9" }, + { 0x44, "f10" }, + { 0x45, "num_lock" }, + { 0x46, "scroll_lock" }, + + { 0x56, "<" }, + + { 0x57, "f11" }, + { 0x58, "f12" }, + + { 0xb7, "print" }, + + { 0xc7, "home" }, + { 0xc9, "pgup" }, + { 0xd1, "pgdn" }, + { 0xcf, "end" }, + + { 0xcb, "left" }, + { 0xc8, "up" }, + { 0xd0, "down" }, + { 0xcd, "right" }, + + { 0xd2, "insert" }, + { 0xd3, "delete" }, + { 0, NULL }, +}; + +static int get_keycode(const char *key) +{ + const KeyDef *p; + + for(p = key_defs; p->name != NULL; p++) { + if (!strcmp(key, p->name)) + return p->keycode; + } + return -1; +} + +static void do_send_key(const char *string) +{ + char keybuf[16], *q; + uint8_t keycodes[16]; + const char *p; + int nb_keycodes, keycode, i; + + nb_keycodes = 0; + p = string; + while (*p != '\0') { + q = keybuf; + while (*p != '\0' && *p != '-') { + if ((q - keybuf) < sizeof(keybuf) - 1) { + *q++ = *p; + } + p++; + } + *q = '\0'; + keycode = get_keycode(keybuf); + if (keycode < 0) { + term_printf("unknown key: '%s'\n", keybuf); + return; + } + keycodes[nb_keycodes++] = keycode; + if (*p == '\0') + break; + p++; + } + /* key down events */ + for(i = 0; i < nb_keycodes; i++) { + keycode = keycodes[i]; + if (keycode & 0x80) + kbd_put_keycode(0xe0); + kbd_put_keycode(keycode & 0x7f); + } + /* key up events */ + for(i = nb_keycodes - 1; i >= 0; i--) { + keycode = keycodes[i]; + if (keycode & 0x80) + kbd_put_keycode(0xe0); + kbd_put_keycode(keycode | 0x80); + } +} + + static int eject_device(BlockDriverState *bs, int force) { if (bdrv_is_inserted(bs)) { @@ -331,6 +486,8 @@ "item1[,...]", "activate logging of the specified items to '/tmp/qemu.log'" }, { "q|quit", "", do_quit, "", "quit the emulator" }, + { "sendkey", "s", do_send_key, + "keys", "send keys to the VM (e.g. 'sendkey ctrl-alt-f1')" }, { NULL, NULL, }, }; diff -r 19af31a59537 -r f31494465fb0 tools/python/xen/xend/image.py --- a/tools/python/xen/xend/image.py Fri Oct 21 11:06:17 2005 +++ b/tools/python/xen/xend/image.py Fri Oct 21 11:07:14 2005 @@ -311,7 +311,8 @@ "-m", "%s" % (self.vm.getMemoryTarget() / 1024)]) args = args + self.dmargs env = dict(os.environ) - env['DISPLAY'] = self.display + if self.display: + env['DISPLAY'] = self.display log.info("spawning device models: %s %s", self.device_model, args) self.pid = os.spawnve(os.P_NOWAIT, self.device_model, args, env) log.info("device model pid: %d", self.pid) diff -r 19af31a59537 -r f31494465fb0 tools/security/Makefile --- a/tools/security/Makefile Fri Oct 21 11:06:17 2005 +++ b/tools/security/Makefile Fri Oct 21 11:07:14 2005 @@ -43,6 +43,7 @@ build: mk-symlinks $(MAKE) secpol_tool $(MAKE) secpol_xml2bin + $(MAKE) get_decision chmod 700 ./setlabel.sh chmod 700 ./updategrub.sh chmod 700 ./getlabel.sh diff -r 19af31a59537 -r f31494465fb0 tools/security/secpol_tool.c --- a/tools/security/secpol_tool.c Fri Oct 21 11:06:17 2005 +++ b/tools/security/secpol_tool.c Fri Oct 21 11:07:14 2005 @@ -67,7 +67,7 @@ (unsigned long) hypercall); } -static inline int do_acm_op(int xc_handle, acm_op_t * op) +static inline int do_acm_op(int xc_handle, struct acm_op * op) { int ret = -1; privcmd_hypercall_t hypercall; @@ -275,10 +275,10 @@ /******************************* get policy ******************************/ #define PULL_CACHE_SIZE 8192 -u8 pull_buffer[PULL_CACHE_SIZE]; +uint8_t pull_buffer[PULL_CACHE_SIZE]; int acm_domain_getpolicy(int xc_handle) { - acm_op_t op; + struct acm_op op; int ret; memset(pull_buffer, 0x00, sizeof(pull_buffer)); @@ -299,7 +299,7 @@ struct stat mystat; int ret, fd; off_t len; - u8 *buffer; + uint8_t *buffer; if ((ret = stat(filename, &mystat))) { @@ -321,7 +321,7 @@ } if (len == read(fd, buffer, len)) { - acm_op_t op; + struct acm_op op; /* dump it and then push it down into xen/acm */ acm_dump_policy_buffer(buffer, len); op.cmd = ACM_SETPOLICY; @@ -368,8 +368,8 @@ #define PULL_STATS_SIZE 8192 int acm_domain_dumpstats(int xc_handle) { - u8 stats_buffer[PULL_STATS_SIZE]; - acm_op_t op; + uint8_t stats_buffer[PULL_STATS_SIZE]; + struct acm_op op; int ret; struct acm_stats_buffer *stats; @@ -442,7 +442,7 @@ /* this includes header and a set of types */ #define MAX_SSIDBUFFER 2000 int ret, i; - acm_op_t op; + struct acm_op op; struct acm_ssid_buffer *hdr; unsigned char *buf; int nice_print = 1; diff -r 19af31a59537 -r f31494465fb0 xen/acm/acm_chinesewall_hooks.c --- a/xen/acm/acm_chinesewall_hooks.c Fri Oct 21 11:06:17 2005 +++ b/xen/acm/acm_chinesewall_hooks.c Fri Oct 21 11:07:14 2005 @@ -26,7 +26,10 @@ * in which case all types of a new domain must be conflict-free * with all types of already running domains. * + * indent -i4 -kr -nut + * */ + #include <xen/config.h> #include <xen/errno.h> #include <xen/types.h> @@ -48,270 +51,333 @@ */ int acm_init_chwall_policy(void) { - /* minimal startup policy; policy write-locked already */ - chwall_bin_pol.max_types = 1; - chwall_bin_pol.max_ssidrefs = 2; - chwall_bin_pol.max_conflictsets = 1; - chwall_bin_pol.ssidrefs = (domaintype_t *)xmalloc_array(domaintype_t, chwall_bin_pol.max_ssidrefs*chwall_bin_pol.max_types); - chwall_bin_pol.conflict_sets = (domaintype_t *)xmalloc_array(domaintype_t, chwall_bin_pol.max_conflictsets*chwall_bin_pol.max_types); - chwall_bin_pol.running_types = (domaintype_t *)xmalloc_array(domaintype_t, chwall_bin_pol.max_types); - chwall_bin_pol.conflict_aggregate_set = (domaintype_t *)xmalloc_array(domaintype_t, chwall_bin_pol.max_types); - - if ((chwall_bin_pol.conflict_sets == NULL) || (chwall_bin_pol.running_types == NULL) || - (chwall_bin_pol.ssidrefs == NULL) || (chwall_bin_pol.conflict_aggregate_set == NULL)) - return ACM_INIT_SSID_ERROR; - - /* initialize state */ - memset((void *)chwall_bin_pol.ssidrefs, 0, chwall_bin_pol.max_ssidrefs*chwall_bin_pol.max_types*sizeof(domaintype_t)); - memset((void *)chwall_bin_pol.conflict_sets, 0, chwall_bin_pol.max_conflictsets*chwall_bin_pol.max_types*sizeof(domaintype_t)); - memset((void *)chwall_bin_pol.running_types, 0, chwall_bin_pol.max_types*sizeof(domaintype_t)); - memset((void *)chwall_bin_pol.conflict_aggregate_set, 0, chwall_bin_pol.max_types*sizeof(domaintype_t)); - return ACM_OK; -} - -static int -chwall_init_domain_ssid(void **chwall_ssid, ssidref_t ssidref) -{ - struct chwall_ssid *chwall_ssidp = xmalloc(struct chwall_ssid); - traceprintk("%s.\n", __func__); - if (chwall_ssidp == NULL) - return ACM_INIT_SSID_ERROR; - /* - * depending on wheter chwall is primary or secondary, get the respective - * part of the global ssidref (same way we'll get the partial ssid pointer) - */ - chwall_ssidp->chwall_ssidref = GET_SSIDREF(ACM_CHINESE_WALL_POLICY, ssidref); - if ((chwall_ssidp->chwall_ssidref >= chwall_bin_pol.max_ssidrefs) || - (chwall_ssidp->chwall_ssidref == ACM_DEFAULT_LOCAL_SSID)) { - printkd("%s: ERROR chwall_ssidref(%x) undefined (>max) or unset (0).\n", - __func__, chwall_ssidp->chwall_ssidref); - xfree(chwall_ssidp); - return ACM_INIT_SSID_ERROR; - } - (*chwall_ssid) = chwall_ssidp; - printkd("%s: determined chwall_ssidref to %x.\n", - __func__, chwall_ssidp->chwall_ssidref); - return ACM_OK; -} - -static void -chwall_free_domain_ssid(void *chwall_ssid) -{ - traceprintk("%s.\n", __func__); - if (chwall_ssid != NULL) - xfree(chwall_ssid); - return; + /* minimal startup policy; policy write-locked already */ + chwall_bin_pol.max_types = 1; + chwall_bin_pol.max_ssidrefs = 2; + chwall_bin_pol.max_conflictsets = 1; + chwall_bin_pol.ssidrefs = + (domaintype_t *) xmalloc_array(domaintype_t, + chwall_bin_pol.max_ssidrefs * + chwall_bin_pol.max_types); + chwall_bin_pol.conflict_sets = + (domaintype_t *) xmalloc_array(domaintype_t, + chwall_bin_pol.max_conflictsets * + chwall_bin_pol.max_types); + chwall_bin_pol.running_types = + (domaintype_t *) xmalloc_array(domaintype_t, + chwall_bin_pol.max_types); + chwall_bin_pol.conflict_aggregate_set = + (domaintype_t *) xmalloc_array(domaintype_t, + chwall_bin_pol.max_types); + + if ((chwall_bin_pol.conflict_sets == NULL) + || (chwall_bin_pol.running_types == NULL) + || (chwall_bin_pol.ssidrefs == NULL) + || (chwall_bin_pol.conflict_aggregate_set == NULL)) + return ACM_INIT_SSID_ERROR; + + /* initialize state */ + memset((void *) chwall_bin_pol.ssidrefs, 0, + chwall_bin_pol.max_ssidrefs * chwall_bin_pol.max_types * + sizeof(domaintype_t)); + memset((void *) chwall_bin_pol.conflict_sets, 0, + chwall_bin_pol.max_conflictsets * chwall_bin_pol.max_types * + sizeof(domaintype_t)); + memset((void *) chwall_bin_pol.running_types, 0, + chwall_bin_pol.max_types * sizeof(domaintype_t)); + memset((void *) chwall_bin_pol.conflict_aggregate_set, 0, + chwall_bin_pol.max_types * sizeof(domaintype_t)); + return ACM_OK; +} + +static int chwall_init_domain_ssid(void **chwall_ssid, ssidref_t ssidref) +{ + struct chwall_ssid *chwall_ssidp = xmalloc(struct chwall_ssid); + traceprintk("%s.\n", __func__); + if (chwall_ssidp == NULL) + return ACM_INIT_SSID_ERROR; + + chwall_ssidp->chwall_ssidref = + GET_SSIDREF(ACM_CHINESE_WALL_POLICY, ssidref); + + if ((chwall_ssidp->chwall_ssidref >= chwall_bin_pol.max_ssidrefs) + || (chwall_ssidp->chwall_ssidref == ACM_DEFAULT_LOCAL_SSID)) + { + printkd("%s: ERROR chwall_ssidref(%x) undefined (>max) or unset (0).\n", + __func__, chwall_ssidp->chwall_ssidref); + xfree(chwall_ssidp); + return ACM_INIT_SSID_ERROR; + } + (*chwall_ssid) = chwall_ssidp; + printkd("%s: determined chwall_ssidref to %x.\n", + __func__, chwall_ssidp->chwall_ssidref); + return ACM_OK; +} + +static void chwall_free_domain_ssid(void *chwall_ssid) +{ + traceprintk("%s.\n", __func__); + if (chwall_ssid != NULL) + xfree(chwall_ssid); + return; } /* dump chinese wall cache; policy read-locked already */ -static int -chwall_dump_policy(u8 *buf, u16 buf_size) { - struct acm_chwall_policy_buffer *chwall_buf = (struct acm_chwall_policy_buffer *)buf; - int ret = 0; - - 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 = - 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 = - 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 = - htonl( - ntohl(chwall_buf->chwall_running_types_offset) + - sizeof(domaintype_t) * chwall_bin_pol.max_types); - - ret = ntohl(chwall_buf->chwall_conflict_aggregate_offset) + - sizeof(domaintype_t) * chwall_bin_pol.max_types; - - /* now copy buffers over */ - 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 + 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 + ntohl(chwall_buf->chwall_running_types_offset)), - chwall_bin_pol.running_types, - chwall_bin_pol.max_types); - - arrcpy16((u16 *)(buf + ntohl(chwall_buf->chwall_conflict_aggregate_offset)), - chwall_bin_pol.conflict_aggregate_set, - chwall_bin_pol.max_types); - return ret; +static int chwall_dump_policy(u8 * buf, u32 buf_size) +{ + struct acm_chwall_policy_buffer *chwall_buf = + (struct acm_chwall_policy_buffer *) buf; + int ret = 0; + + if (buf_size < sizeof(struct acm_chwall_policy_buffer)) + return -EINVAL; + + 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 = + 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 = + 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 = + htonl(ntohl(chwall_buf->chwall_running_types_offset) + + sizeof(domaintype_t) * chwall_bin_pol.max_types); + + ret = ntohl(chwall_buf->chwall_conflict_aggregate_offset) + + sizeof(domaintype_t) * chwall_bin_pol.max_types; + + if (buf_size < ret) + return -EINVAL; + + /* now copy buffers over */ + 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 + + 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 + + ntohl(chwall_buf->chwall_running_types_offset)), + chwall_bin_pol.running_types, chwall_bin_pol.max_types); + + arrcpy16((u16 *) (buf + + ntohl(chwall_buf->chwall_conflict_aggregate_offset)), + chwall_bin_pol.conflict_aggregate_set, + chwall_bin_pol.max_types); + return ret; } /* adapt security state (running_types and conflict_aggregate_set) to all running * domains; chwall_init_state is called when a policy is changed to bring the security * information into a consistent state and to detect violations (return != 0). * from a security point of view, we simulate that all running domains are re-started - */ + */ static int -chwall_init_state(struct acm_chwall_policy_buffer *chwall_buf, domaintype_t *ssidrefs, domaintype_t *conflict_sets, - domaintype_t *running_types, domaintype_t *conflict_aggregate_set) -{ - int violation = 0, i, j; - struct chwall_ssid *chwall_ssid; - ssidref_t chwall_ssidref; - struct domain **pd; - - write_lock(&domlist_lock); - /* go through all domains and adjust policy as if this domain was started now */ - pd = &domain_list; - for ( pd = &domain_list; *pd != NULL; pd = &(*pd)->next_in_list ) { - chwall_ssid = GET_SSIDP(ACM_CHINESE_WALL_POLICY, (struct acm_ssid_domain *)(*pd)->ssid); - chwall_ssidref = chwall_ssid->chwall_ssidref; - traceprintk("%s: validating policy for domain %x (chwall-REF=%x).\n", - __func__, (*pd)->domain_id, chwall_ssidref); - /* a) adjust types ref-count for running domains */ - for (i=0; i< chwall_buf->chwall_max_types; i++) - running_types[i] += - ssidrefs[chwall_ssidref*chwall_buf->chwall_max_types + i]; - - /* b) check for conflict */ - for (i=0; i< chwall_buf->chwall_max_types; i++) - if (conflict_aggregate_set[i] && - ssidrefs[chwall_ssidref*chwall_buf->chwall_max_types + i]) { - printk("%s: CHINESE WALL CONFLICT in type %02x.\n", __func__, i); - violation = 1; - goto out; - } - /* set violation and break out of the loop */ - /* c) adapt conflict aggregate set for this domain (notice conflicts) */ - for (i=0; i<chwall_buf->chwall_max_conflictsets; i++) { - int common = 0; - /* check if conflict_set_i and ssidref have common types */ - for (j=0; j<chwall_buf->chwall_max_types; j++) - if (conflict_sets[i*chwall_buf->chwall_max_types + j] && - ssidrefs[chwall_ssidref*chwall_buf->chwall_max_types + j]) { - common = 1; - break; - } - if (common == 0) - continue; /* try next conflict set */ - /* now add types of the conflict set to conflict_aggregate_set (except types in chwall_ssidref) */ - for (j=0; j<chwall_buf->chwall_max_types; j++) - if (conflict_sets[i*chwall_buf->chwall_max_types + j] && - !ssidrefs[chwall_ssidref*chwall_buf->chwall_max_types + j]) - conflict_aggregate_set[j]++; - } - } +chwall_init_state(struct acm_chwall_policy_buffer *chwall_buf, + domaintype_t * ssidrefs, domaintype_t * conflict_sets, + domaintype_t * running_types, + domaintype_t * conflict_aggregate_set) +{ + int violation = 0, i, j; + struct chwall_ssid *chwall_ssid; + ssidref_t chwall_ssidref; + struct domain **pd; + + write_lock(&domlist_lock); + /* go through all domains and adjust policy as if this domain was started now */ + pd = &domain_list; + for (pd = &domain_list; *pd != NULL; pd = &(*pd)->next_in_list) + { + chwall_ssid = + GET_SSIDP(ACM_CHINESE_WALL_POLICY, + (struct acm_ssid_domain *) (*pd)->ssid); + chwall_ssidref = chwall_ssid->chwall_ssidref; + traceprintk("%s: validating policy for domain %x (chwall-REF=%x).\n", + __func__, (*pd)->domain_id, chwall_ssidref); + /* a) adjust types ref-count for running domains */ + for (i = 0; i < chwall_buf->chwall_max_types; i++) + running_types[i] += + ssidrefs[chwall_ssidref * chwall_buf->chwall_max_types + i]; + + /* b) check for conflict */ + for (i = 0; i < chwall_buf->chwall_max_types; i++) + if (conflict_aggregate_set[i] && + ssidrefs[chwall_ssidref * chwall_buf->chwall_max_types + i]) + { + printk("%s: CHINESE WALL CONFLICT in type %02x.\n", + __func__, i); + violation = 1; + goto out; + } + /* set violation and break out of the loop */ + /* c) adapt conflict aggregate set for this domain (notice conflicts) */ + for (i = 0; i < chwall_buf->chwall_max_conflictsets; i++) + { + int common = 0; + /* check if conflict_set_i and ssidref have common types */ + for (j = 0; j < chwall_buf->chwall_max_types; j++) + if (conflict_sets[i * chwall_buf->chwall_max_types + j] && + ssidrefs[chwall_ssidref * + chwall_buf->chwall_max_types + j]) + { + common = 1; + break; + } + if (common == 0) + continue; /* try next conflict set */ + /* now add types of the conflict set to conflict_aggregate_set (except types in chwall_ssidref) */ + for (j = 0; j < chwall_buf->chwall_max_types; j++) + if (conflict_sets[i * chwall_buf->chwall_max_types + j] && + !ssidrefs[chwall_ssidref * + chwall_buf->chwall_max_types + j]) + conflict_aggregate_set[j]++; + } + } out: - write_unlock(&domlist_lock); - return violation; - /* returning "violation != 0" means that the currently running set of domains would - * not be possible if the new policy had been enforced before starting them; for chinese - * wall, this means that the new policy includes at least one conflict set of which - * more than one type is currently running */ -} - -static int -chwall_set_policy(u8 *buf, u16 buf_size) -{ - /* policy write-locked already */ - struct acm_chwall_policy_buffer *chwall_buf = (struct acm_chwall_policy_buffer *)buf; - void *ssids = NULL, *conflict_sets = NULL, *running_types = NULL, *conflict_aggregate_set = NULL; - - /* rewrite the policy due to endianess */ - 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); - conflict_sets = xmalloc_array(domaintype_t, chwall_buf->chwall_max_conflictsets*chwall_buf->chwall_max_types); - running_types = xmalloc_array(domaintype_t,chwall_buf->chwall_max_types); - conflict_aggregate_set = xmalloc_array(domaintype_t, chwall_buf->chwall_max_types); - - if ((ssids == NULL)||(conflict_sets == NULL)||(running_types == NULL)||(conflict_aggregate_set == NULL)) - goto error_free; - - /* 2. set new policy */ - if (chwall_buf->chwall_ssid_offset + sizeof(domaintype_t) * - chwall_buf->chwall_max_types * chwall_buf->chwall_max_ssidrefs > buf_size) - goto error_free; - arrcpy(ssids, buf + chwall_buf->chwall_ssid_offset, - sizeof(domaintype_t), - chwall_buf->chwall_max_types * chwall_buf->chwall_max_ssidrefs); - - if (chwall_buf->chwall_conflict_sets_offset + sizeof(domaintype_t) * - chwall_buf->chwall_max_types * chwall_buf->chwall_max_conflictsets > buf_size) - goto error_free; - - arrcpy(conflict_sets, buf + chwall_buf->chwall_conflict_sets_offset, - sizeof(domaintype_t), - chwall_buf->chwall_max_types * chwall_buf->chwall_max_conflictsets); - - /* we also use new state buffers since max_types can change */ - memset(running_types, 0, sizeof(domaintype_t)*chwall_buf->chwall_max_types); - memset(conflict_aggregate_set, 0, sizeof(domaintype_t)*chwall_buf->chwall_max_types); - - /* 3. now re-calculate the state for the new policy based on running domains; - * this can fail if new policy is conflicting with running domains */ - if (chwall_init_state(chwall_buf, ssids, conflict_sets, running_types, conflict_aggregate_set)) { - printk("%s: New policy conflicts with running domains. Policy load aborted.\n", __func__); - goto error_free; /* new policy conflicts with running domains */ - } - /* 4. free old policy buffers, replace with new ones */ - chwall_bin_pol.max_types = chwall_buf->chwall_max_types; - chwall_bin_pol.max_ssidrefs = chwall_buf->chwall_max_ssidrefs; - chwall_bin_pol.max_conflictsets = chwall_buf->chwall_max_conflictsets; - if (chwall_bin_pol.ssidrefs != NULL) - xfree(chwall_bin_pol.ssidrefs); - if (chwall_bin_pol.conflict_aggregate_set != NULL) - xfree(chwall_bin_pol.conflict_aggregate_set); - if (chwall_bin_pol.running_types != NULL) - xfree(chwall_bin_pol.running_types); - if (chwall_bin_pol.conflict_sets != NULL) - xfree(chwall_bin_pol.conflict_sets); - chwall_bin_pol.ssidrefs = ssids; - chwall_bin_pol.conflict_aggregate_set = conflict_aggregate_set; - chwall_bin_pol.running_types = running_types; - chwall_bin_pol.conflict_sets = conflict_sets; - return ACM_OK; - -error_free: - printk("%s: ERROR setting policy.\n", __func__); - if (ssids != NULL) xfree(ssids); - if (conflict_sets != NULL) xfree(conflict_sets); - if (running_types != NULL) xfree(running_types); - if (conflict_aggregate_set != NULL) xfree(conflict_aggregate_set); - return -EFAULT; -} - -static int -chwall_dump_stats(u8 *buf, u16 len) -{ - /* no stats for Chinese Wall Policy */ - return 0; -} - -static int -chwall_dump_ssid_types(ssidref_t ssidref, u8 *buf, u16 len) + write_unlock(&domlist_lock); + return violation; + /* returning "violation != 0" means that the currently running set of domains would + * not be possible if the new policy had been enforced before starting them; for chinese + * wall, this means that the new policy includes at least one conflict set of which + * more than one type is currently running */ +} + +static int chwall_set_policy(u8 * buf, u32 buf_size) +{ + /* policy write-locked already */ + struct acm_chwall_policy_buffer *chwall_buf = + (struct acm_chwall_policy_buffer *) buf; + void *ssids = NULL, *conflict_sets = NULL, *running_types = + NULL, *conflict_aggregate_set = NULL; + + if (buf_size < sizeof(struct acm_chwall_policy_buffer)) + return -EINVAL; + + /* rewrite the policy due to endianess */ + 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); + conflict_sets = + xmalloc_array(domaintype_t, + chwall_buf->chwall_max_conflictsets * + chwall_buf->chwall_max_types); + running_types = + xmalloc_array(domaintype_t, chwall_buf->chwall_max_types); + conflict_aggregate_set = + xmalloc_array(domaintype_t, chwall_buf->chwall_max_types); + + if ((ssids == NULL) || (conflict_sets == NULL) + || (running_types == NULL) || (conflict_aggregate_set == NULL)) + goto error_free; + + /* 2. set new policy */ + if (chwall_buf->chwall_ssid_offset + sizeof(domaintype_t) * + chwall_buf->chwall_max_types * chwall_buf->chwall_max_ssidrefs > + buf_size) + goto error_free; + + arrcpy(ssids, buf + chwall_buf->chwall_ssid_offset, + sizeof(domaintype_t), + chwall_buf->chwall_max_types * chwall_buf->chwall_max_ssidrefs); + + if (chwall_buf->chwall_conflict_sets_offset + sizeof(domaintype_t) * + chwall_buf->chwall_max_types * + chwall_buf->chwall_max_conflictsets > buf_size) + goto error_free; + + arrcpy(conflict_sets, buf + chwall_buf->chwall_conflict_sets_offset, + sizeof(domaintype_t), + chwall_buf->chwall_max_types * + chwall_buf->chwall_max_conflictsets); + + /* we also use new state buffers since max_types can change */ + memset(running_types, 0, + sizeof(domaintype_t) * chwall_buf->chwall_max_types); + memset(conflict_aggregate_set, 0, + sizeof(domaintype_t) * chwall_buf->chwall_max_types); + + /* 3. now re-calculate the state for the new policy based on running domains; + * this can fail if new policy is conflicting with running domains */ + if (chwall_init_state(chwall_buf, ssids, + conflict_sets, running_types, + conflict_aggregate_set)) + { + printk("%s: New policy conflicts with running domains. Policy load aborted.\n", + __func__); + goto error_free; /* new policy conflicts with running domains */ + } + /* 4. free old policy buffers, replace with new ones */ + chwall_bin_pol.max_types = chwall_buf->chwall_max_types; + chwall_bin_pol.max_ssidrefs = chwall_buf->chwall_max_ssidrefs; + chwall_bin_pol.max_conflictsets = chwall_buf->chwall_max_conflictsets; + if (chwall_bin_pol.ssidrefs != NULL) + xfree(chwall_bin_pol.ssidrefs); + if (chwall_bin_pol.conflict_aggregate_set != NULL) + xfree(chwall_bin_pol.conflict_aggregate_set); + if (chwall_bin_pol.running_types != NULL) + xfree(chwall_bin_pol.running_types); + if (chwall_bin_pol.conflict_sets != NULL) + xfree(chwall_bin_pol.conflict_sets); + chwall_bin_pol.ssidrefs = ssids; + chwall_bin_pol.conflict_aggregate_set = conflict_aggregate_set; + chwall_bin_pol.running_types = running_types; + chwall_bin_pol.conflict_sets = conflict_sets; + return ACM_OK; + + error_free: + printk("%s: ERROR setting policy.\n", __func__); + if (ssids != NULL) + xfree(ssids); + if (conflict_sets != NULL) + xfree(conflict_sets); + if (running_types != NULL) + xfree(running_types); + if (conflict_aggregate_set != NULL) + xfree(conflict_aggregate_set); + return -EFAULT; +} + +static int chwall_dump_stats(u8 * buf, u16 len) +{ + /* no stats for Chinese Wall Policy */ + return 0; +} + +static int chwall_dump_ssid_types(ssidref_t ssidref, u8 * buf, u16 len) { int i; @@ -319,12 +385,14 @@ if (chwall_bin_pol.max_types > len) return -EFAULT; - if (ssidref >= chwall_bin_pol.max_ssidrefs) - return -EFAULT; + if (ssidref >= chwall_bin_pol.max_ssidrefs) + return -EFAULT; /* read types for chwall ssidref */ - for(i=0; i< chwall_bin_pol.max_types; i++) { - if (chwall_bin_pol.ssidrefs[ssidref * chwall_bin_pol.max_types + i]) + for (i = 0; i < chwall_bin_pol.max_types; i++) + { + if (chwall_bin_pol. + ssidrefs[ssidref * chwall_bin_pol.max_types + i]) buf[i] = 1; else buf[i] = 0; @@ -336,198 +404,239 @@ * Authorization functions ***************************/ - /* -------- DOMAIN OPERATION HOOKS -----------*/ -static int -chwall_pre_domain_create(void *subject_ssid, ssidref_t ssidref) -{ - ssidref_t chwall_ssidref; - int i,j; - traceprintk("%s.\n", __func__); - - read_lock(&acm_bin_pol_rwlock); - chwall_ssidref = GET_SSIDREF(ACM_CHINESE_WALL_POLICY, ssidref); - if (chwall_ssidref == ACM_DEFAULT_LOCAL_SSID) { - printk("%s: ERROR CHWALL SSID is NOT SET but policy enforced.\n", __func__); - read_unlock(&acm_bin_pol_rwlock); - return ACM_ACCESS_DENIED; /* catching and indicating config error */ - } - if (chwall_ssidref >= chwall_bin_pol.max_ssidrefs) { - printk("%s: ERROR chwall_ssidref > max(%x).\n", - __func__, chwall_bin_pol.max_ssidrefs-1); - read_unlock(&acm_bin_pol_rwlock); - return ACM_ACCESS_DENIED; - } - /* A: chinese wall check for conflicts */ - for (i=0; i< chwall_bin_pol.max_types; i++) - if (chwall_bin_pol.conflict_aggregate_set[i] && - chwall_bin_pol.ssidrefs[chwall_ssidref*chwall_bin_pol.max_types + i]) { - printk("%s: CHINESE WALL CONFLICT in type %02x.\n", __func__, i); - read_unlock(&acm_bin_pol_rwlock); - return ACM_ACCESS_DENIED; - } - - /* B: chinese wall conflict set adjustment (so that other - * other domains simultaneously created are evaluated against this new set)*/ - for (i=0; i<chwall_bin_pol.max_conflictsets; i++) { - int common = 0; - /* check if conflict_set_i and ssidref have common types */ - for (j=0; j<chwall_bin_pol.max_types; j++) - if (chwall_bin_pol.conflict_sets[i*chwall_bin_pol.max_types + j] && - chwall_bin_pol.ssidrefs[chwall_ssidref*chwall_bin_pol.max_types + j]) { - common = 1; - break; - } - if (common == 0) - continue; /* try next conflict set */ - /* now add types of the conflict set to conflict_aggregate_set (except types in chwall_ssidref) */ - for (j=0; j<chwall_bin_pol.max_types; j++) - if (chwall_bin_pol.conflict_sets[i*chwall_bin_pol.max_types + j] && - !chwall_bin_pol.ssidrefs[chwall_ssidref*chwall_bin_pol.max_types + j]) - chwall_bin_pol.conflict_aggregate_set[j]++; - } - read_unlock(&acm_bin_pol_rwlock); - return ACM_ACCESS_PERMITTED; -} - -static void -chwall_post_domain_create(domid_t domid, ssidref_t ssidref) -{ - int i,j; - ssidref_t chwall_ssidref; - traceprintk("%s.\n", __func__); - - read_lock(&acm_bin_pol_rwlock); - chwall_ssidref = GET_SSIDREF(ACM_CHINESE_WALL_POLICY, ssidref); - /* adjust types ref-count for running domains */ - for (i=0; i< chwall_bin_pol.max_types; i++) - chwall_bin_pol.running_types[i] += - chwall_bin_pol.ssidrefs[chwall_ssidref*chwall_bin_pol.max_types + i]; - if (domid) { - read_unlock(&acm_bin_pol_rwlock); - return; - } - /* Xen does not call pre-create hook for DOM0; - * to consider type conflicts of any domain with DOM0, we need - * to adjust the conflict_aggregate for DOM0 here the same way it - * is done for non-DOM0 domains in the pre-hook */ - printkd("%s: adjusting security state for DOM0 (ssidref=%x, chwall_ssidref=%x).\n", - __func__, ssidref, chwall_ssidref); - - /* chinese wall conflict set adjustment (so that other - * other domains simultaneously created are evaluated against this new set)*/ - for (i=0; i<chwall_bin_pol.max_conflictsets; i++) { - int common = 0; - /* check if conflict_set_i and ssidref have common types */ - for (j=0; j<chwall_bin_pol.max_types; j++) - if (chwall_bin_pol.conflict_sets[i*chwall_bin_pol.max_types + j] && - chwall_bin_pol.ssidrefs[chwall_ssidref*chwall_bin_pol.max_types + j]) { - common = 1; - break; - } - if (common == 0) - continue; /* try next conflict set */ - /* now add types of the conflict set to conflict_aggregate_set (except types in chwall_ssidref) */ - for (j=0; j<chwall_bin_pol.max_types; j++) - if (chwall_bin_pol.conflict_sets[i*chwall_bin_pol.max_types + j] && - !chwall_bin_pol.ssidrefs[chwall_ssidref*chwall_bin_pol.max_types + j]) - chwall_bin_pol.conflict_aggregate_set[j]++; - } - read_unlock(&acm_bin_pol_rwlock); - return; +static int chwall_pre_domain_create(void *subject_ssid, ssidref_t ssidref) +{ + ssidref_t chwall_ssidref; + int i, j; + traceprintk("%s.\n", __func__); + + read_lock(&acm_bin_pol_rwlock); + chwall_ssidref = GET_SSIDREF(ACM_CHINESE_WALL_POLICY, ssidref); + if (chwall_ssidref == ACM_DEFAULT_LOCAL_SSID) + { + printk("%s: ERROR CHWALL SSID is NOT SET but policy enforced.\n", + __func__); + read_unlock(&acm_bin_pol_rwlock); + return ACM_ACCESS_DENIED; /* catching and indicating config error */ + } + if (chwall_ssidref >= chwall_bin_pol.max_ssidrefs) + { + printk("%s: ERROR chwall_ssidref > max(%x).\n", + __func__, chwall_bin_pol.max_ssidrefs - 1); + read_unlock(&acm_bin_pol_rwlock); + return ACM_ACCESS_DENIED; + } + /* A: chinese wall check for conflicts */ + for (i = 0; i < chwall_bin_pol.max_types; i++) + if (chwall_bin_pol.conflict_aggregate_set[i] && + chwall_bin_pol.ssidrefs[chwall_ssidref * + chwall_bin_pol.max_types + i]) + { + printk("%s: CHINESE WALL CONFLICT in type %02x.\n", __func__, i); + read_unlock(&acm_bin_pol_rwlock); + return ACM_ACCESS_DENIED; + } + + /* B: chinese wall conflict set adjustment (so that other + * other domains simultaneously created are evaluated against this new set)*/ + for (i = 0; i < chwall_bin_pol.max_conflictsets; i++) + { + int common = 0; + /* check if conflict_set_i and ssidref have common types */ + for (j = 0; j < chwall_bin_pol.max_types; j++) + if (chwall_bin_pol. + conflict_sets[i * chwall_bin_pol.max_types + j] + && chwall_bin_pol.ssidrefs[chwall_ssidref * + chwall_bin_pol.max_types + j]) + { + common = 1; + break; + } + if (common == 0) + continue; /* try next conflict set */ + /* now add types of the conflict set to conflict_aggregate_set (except types in chwall_ssidref) */ + for (j = 0; j < chwall_bin_pol.max_types; j++) + if (chwall_bin_pol. + conflict_sets[i * chwall_bin_pol.max_types + j] + && !chwall_bin_pol.ssidrefs[chwall_ssidref * + chwall_bin_pol.max_types + j]) + chwall_bin_pol.conflict_aggregate_set[j]++; + } + read_unlock(&acm_bin_pol_rwlock); + return ACM_ACCESS_PERMITTED; +} + +static void chwall_post_domain_create(domid_t domid, ssidref_t ssidref) +{ + int i, j; + ssidref_t chwall_ssidref; + traceprintk("%s.\n", __func__); + + read_lock(&acm_bin_pol_rwlock); + chwall_ssidref = GET_SSIDREF(ACM_CHINESE_WALL_POLICY, ssidref); + /* adjust types ref-count for running domains */ + for (i = 0; i < chwall_bin_pol.max_types; i++) + chwall_bin_pol.running_types[i] += + chwall_bin_pol.ssidrefs[chwall_ssidref * + chwall_bin_pol.max_types + i]; + if (domid) + { + read_unlock(&acm_bin_pol_rwlock); + return; + } + /* Xen does not call pre-create hook for DOM0; + * to consider type conflicts of any domain with DOM0, we need + * to adjust the conflict_aggregate for DOM0 here the same way it + * is done for non-DOM0 domains in the pre-hook */ + printkd("%s: adjusting security state for DOM0 (ssidref=%x, chwall_ssidref=%x).\n", + __func__, ssidref, chwall_ssidref); + + /* chinese wall conflict set adjustment (so that other + * other domains simultaneously created are evaluated against this new set)*/ + for (i = 0; i < chwall_bin_pol.max_conflictsets; i++) + { + int common = 0; + /* check if conflict_set_i and ssidref have common types */ + for (j = 0; j < chwall_bin_pol.max_types; j++) + if (chwall_bin_pol. + conflict_sets[i * chwall_bin_pol.max_types + j] + && chwall_bin_pol.ssidrefs[chwall_ssidref * + chwall_bin_pol.max_types + j]) + { + common = 1; + break; + } + if (common == 0) + continue; /* try next conflict set */ + /* now add types of the conflict set to conflict_aggregate_set (except types in chwall_ssidref) */ + for (j = 0; j < chwall_bin_pol.max_types; j++) + if (chwall_bin_pol. + conflict_sets[i * chwall_bin_pol.max_types + j] + && !chwall_bin_pol.ssidrefs[chwall_ssidref * + chwall_bin_pol.max_types + j]) + chwall_bin_pol.conflict_aggregate_set[j]++; + } + read_unlock(&acm_bin_pol_rwlock); + return; } static void chwall_fail_domain_create(void *subject_ssid, ssidref_t ssidref) { - int i, j; - ssidref_t chwall_ssidref; - traceprintk("%s.\n", __func__); - - read_lock(&acm_bin_pol_rwlock); - chwall_ssidref = GET_SSIDREF(ACM_CHINESE_WALL_POLICY, ssidref); - /* roll-back: re-adjust conflicting types aggregate */ - for (i=0; i<chwall_bin_pol.max_conflictsets; i++) { - int common = 0; - /* check if conflict_set_i and ssidref have common types */ - for (j=0; j<chwall_bin_pol.max_types; j++) - if (chwall_bin_pol.conflict_sets[i*chwall_bin_pol.max_types + j] && - chwall_bin_pol.ssidrefs[chwall_ssidref*chwall_bin_pol.max_types + j]) { - common = 1; - break; - } - if (common == 0) - continue; /* try next conflict set, this one does not include any type of chwall_ssidref */ - /* now add types of the conflict set to conflict_aggregate_set (except types in chwall_ssidref) */ - for (j=0; j<chwall_bin_pol.max_types; j++) - if (chwall_bin_pol.conflict_sets[i*chwall_bin_pol.max_types + j] && - !chwall_bin_pol.ssidrefs[chwall_ssidref*chwall_bin_pol.max_types + j]) - chwall_bin_pol.conflict_aggregate_set[j]--; - } - read_unlock(&acm_bin_pol_rwlock); -} - - -static void -chwall_post_domain_destroy(void *object_ssid, domid_t id) -{ - int i,j; - struct chwall_ssid *chwall_ssidp = - GET_SSIDP(ACM_CHINESE_WALL_POLICY, (struct acm_ssid_domain *)object_ssid); - ssidref_t chwall_ssidref = chwall_ssidp->chwall_ssidref; - - traceprintk("%s.\n", __func__); - - read_lock(&acm_bin_pol_rwlock); - /* adjust running types set */ - for (i=0; i< chwall_bin_pol.max_types; i++) - chwall_bin_pol.running_types[i] -= - chwall_bin_pol.ssidrefs[chwall_ssidref*chwall_bin_pol.max_types + i]; - - /* roll-back: re-adjust conflicting types aggregate */ - for (i=0; i<chwall_bin_pol.max_conflictsets; i++) { - int common = 0; - /* check if conflict_set_i and ssidref have common types */ - for (j=0; j<chwall_bin_pol.max_types; j++) - if (chwall_bin_pol.conflict_sets[i*chwall_bin_pol.max_types + j] && - chwall_bin_pol.ssidrefs[chwall_ssidref*chwall_bin_pol.max_types + j]) { - common = 1; - break; - } - if (common == 0) - continue; /* try next conflict set, this one does not include any type of chwall_ssidref */ - /* now add types of the conflict set to conflict_aggregate_set (except types in chwall_ssidref) */ - for (j=0; j<chwall_bin_pol.max_types; j++) - if (chwall_bin_pol.conflict_sets[i*chwall_bin_pol.max_types + j] && - !chwall_bin_pol.ssidrefs[chwall_ssidref*chwall_bin_pol.max_types + j]) - chwall_bin_pol.conflict_aggregate_set[j]--; - } - read_unlock(&acm_bin_pol_rwlock); - return; + int i, j; + ssidref_t chwall_ssidref; + traceprintk("%s.\n", __func__); + + read_lock(&acm_bin_pol_rwlock); + chwall_ssidref = GET_SSIDREF(ACM_CHINESE_WALL_POLICY, ssidref); + /* roll-back: re-adjust conflicting types aggregate */ + for (i = 0; i < chwall_bin_pol.max_conflictsets; i++) + { + int common = 0; + /* check if conflict_set_i and ssidref have common types */ + for (j = 0; j < chwall_bin_pol.max_types; j++) + if (chwall_bin_pol. + conflict_sets[i * chwall_bin_pol.max_types + j] + && chwall_bin_pol.ssidrefs[chwall_ssidref * + chwall_bin_pol.max_types + j]) + { + common = 1; + break; + } + if (common == 0) + continue; /* try next conflict set, this one does not include any type of chwall_ssidref */ + /* now add types of the conflict set to conflict_aggregate_set (except types in chwall_ssidref) */ + for (j = 0; j < chwall_bin_pol.max_types; j++) + if (chwall_bin_pol. + conflict_sets[i * chwall_bin_pol.max_types + j] + && !chwall_bin_pol.ssidrefs[chwall_ssidref * + chwall_bin_pol.max_types + j]) + chwall_bin_pol.conflict_aggregate_set[j]--; + } + read_unlock(&acm_bin_pol_rwlock); +} + + +static void chwall_post_domain_destroy(void *object_ssid, domid_t id) +{ + int i, j; + struct chwall_ssid *chwall_ssidp = GET_SSIDP(ACM_CHINESE_WALL_POLICY, + (struct acm_ssid_domain *) + object_ssid); + ssidref_t chwall_ssidref = chwall_ssidp->chwall_ssidref; + + traceprintk("%s.\n", __func__); + + read_lock(&acm_bin_pol_rwlock); + /* adjust running types set */ + for (i = 0; i < chwall_bin_pol.max_types; i++) + chwall_bin_pol.running_types[i] -= + chwall_bin_pol.ssidrefs[chwall_ssidref * + chwall_bin_pol.max_types + i]; + + /* roll-back: re-adjust conflicting types aggregate */ + for (i = 0; i < chwall_bin_pol.max_conflictsets; i++) + { + int common = 0; + /* check if conflict_set_i and ssidref have common types */ + for (j = 0; j < chwall_bin_pol.max_types; j++) + if (chwall_bin_pol. + conflict_sets[i * chwall_bin_pol.max_types + j] + && chwall_bin_pol.ssidrefs[chwall_ssidref * + chwall_bin_pol.max_types + j]) + { + common = 1; + break; + } + if (common == 0) + continue; /* try next conflict set, this one does not include any type of chwall_ssidref */ + /* now add types of the conflict set to conflict_aggregate_set (except types in chwall_ssidref) */ + for (j = 0; j < chwall_bin_pol.max_types; j++) + if (chwall_bin_pol. + conflict_sets[i * chwall_bin_pol.max_types + j] + && !chwall_bin_pol.ssidrefs[chwall_ssidref * + chwall_bin_pol.max_types + j]) + chwall_bin_pol.conflict_aggregate_set[j]--; + } + read_unlock(&acm_bin_pol_rwlock); + return; } struct acm_operations acm_chinesewall_ops = { - /* policy management services */ - .init_domain_ssid = chwall_init_domain_ssid, - .free_domain_ssid = chwall_free_domain_ssid, - .dump_binary_policy = chwall_dump_policy, - .set_binary_policy = chwall_set_policy, - .dump_statistics = chwall_dump_stats, - .dump_ssid_types = chwall_dump_ssid_types, - /* domain management control hooks */ - .pre_domain_create = chwall_pre_domain_create, - .post_domain_create = chwall_post_domain_create, - .fail_domain_create = chwall_fail_domain_create, - .post_domain_destroy = chwall_post_domain_destroy, - /* event channel control hooks */ - .pre_eventchannel_unbound = NULL, - .fail_eventchannel_unbound = NULL, - .pre_eventchannel_interdomain = NULL, - .fail_eventchannel_interdomain = NULL, - /* grant table control hooks */ - .pre_grant_map_ref = NULL, - .fail_grant_map_ref = NULL, - .pre_grant_setup = NULL, - .fail_grant_setup = NULL, + /* policy management services */ + .init_domain_ssid = chwall_init_domain_ssid, + .free_domain_ssid = chwall_free_domain_ssid, + .dump_binary_policy = chwall_dump_policy, + .set_binary_policy = chwall_set_policy, + .dump_statistics = chwall_dump_stats, + .dump_ssid_types = chwall_dump_ssid_types, + /* domain management control hooks */ + .pre_domain_create = chwall_pre_domain_create, + .post_domain_create = chwall_post_domain_create, + .fail_domain_create = chwall_fail_domain_create, + .post_domain_destroy = chwall_post_domain_destroy, + /* event channel control hooks */ + .pre_eventchannel_unbound = NULL, + .fail_eventchannel_unbound = NULL, + .pre_eventchannel_interdomain = NULL, + .fail_eventchannel_interdomain = NULL, + /* grant table control hooks */ + .pre_grant_map_ref = NULL, + .fail_grant_map_ref = NULL, + .pre_grant_setup = NULL, + .fail_grant_setup = NULL, + /* generic domain-requested decision hooks */ + .sharing = NULL, }; + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff -r 19af31a59537 -r f31494465fb0 xen/acm/acm_core.c --- a/xen/acm/acm_core.c Fri Oct 21 11:06:17 2005 +++ b/xen/acm/acm_core.c Fri Oct 21 11:07:14 2005 @@ -47,7 +47,7 @@ void acm_init_ste_policy(void); extern struct acm_operations acm_chinesewall_ops, - acm_simple_type_enforcement_ops, acm_null_ops; + acm_simple_type_enforcement_ops, acm_null_ops; /* global ops structs called by the hooks */ struct acm_operations *acm_primary_ops = NULL; @@ -66,7 +66,7 @@ u32 test = 1; if (*((u8 *)&test) == 1) { - printk("ACM module running in LITTLE ENDIAN.\n"); + printk("ACM module running in LITTLE ENDIAN.\n"); little_endian = 1; } else @@ -80,10 +80,10 @@ static void acm_init_binary_policy(void *primary, void *secondary) { - acm_bin_pol.primary_policy_code = 0; - acm_bin_pol.secondary_policy_code = 0; - acm_bin_pol.primary_binary_policy = primary; - acm_bin_pol.secondary_binary_policy = secondary; + acm_bin_pol.primary_policy_code = 0; + acm_bin_pol.secondary_policy_code = 0; + acm_bin_pol.primary_binary_policy = primary; + acm_bin_pol.secondary_binary_policy = secondary; } static int @@ -96,7 +96,7 @@ int rc = ACM_OK; if (mbi->mods_count > 1) - *initrdidx = 1; + *initrdidx = 1; /* * Try all modules and see whichever could be the binary policy. @@ -115,14 +115,14 @@ #error Architecture unsupported by sHype #endif _policy_len = mod[i].mod_end - mod[i].mod_start; - if (_policy_len < sizeof(struct acm_policy_buffer)) - continue; /* not a policy */ + if (_policy_len < sizeof(struct acm_policy_buffer)) + continue; /* not a policy */ pol = (struct acm_policy_buffer *)_policy_start; if (ntohl(pol->magic) == ACM_MAGIC) { rc = acm_set_policy((void *)_policy_start, - (u16)_policy_len, + (u32)_policy_len, 0); if (rc == ACM_OK) { @@ -145,7 +145,7 @@ } else { - printk("Invalid policy. %d.th module line.\n", i+1); + printk("Invalid policy. %d.th module line.\n", i+1); } } /* end if a binary policy definition, i.e., (ntohl(pol->magic) == ACM_MAGIC ) */ } @@ -158,10 +158,10 @@ const multiboot_info_t *mbi, unsigned long initial_images_start) { - int ret = ACM_OK; + int ret = ACM_OK; acm_set_endian(); - write_lock(&acm_bin_pol_rwlock); + write_lock(&acm_bin_pol_rwlock); acm_init_binary_policy(NULL, NULL); /* set primary policy component */ @@ -170,14 +170,14 @@ case ACM_CHINESE_WALL_POLICY: acm_init_chwall_policy(); - acm_bin_pol.primary_policy_code = ACM_CHINESE_WALL_POLICY; - acm_primary_ops = &acm_chinesewall_ops; + acm_bin_pol.primary_policy_code = ACM_CHINESE_WALL_POLICY; + acm_primary_ops = &acm_chinesewall_ops; break; case ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY: acm_init_ste_policy(); - acm_bin_pol.primary_policy_code = ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY; - acm_primary_ops = &acm_simple_type_enforcement_ops; + acm_bin_pol.primary_policy_code = ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY; + acm_primary_ops = &acm_simple_type_enforcement_ops; break; default: @@ -190,9 +190,9 @@ /* secondary policy component part */ switch ((ACM_USE_SECURITY_POLICY) >> 4) { case ACM_NULL_POLICY: - acm_bin_pol.secondary_policy_code = ACM_NULL_POLICY; - acm_secondary_ops = &acm_null_ops; - break; + acm_bin_pol.secondary_policy_code = ACM_NULL_POLICY; + acm_secondary_ops = &acm_null_ops; + break; case ACM_CHINESE_WALL_POLICY: if (acm_bin_pol.primary_policy_code == ACM_CHINESE_WALL_POLICY) @@ -200,9 +200,9 @@ ret = -EINVAL; goto out; } - acm_init_chwall_policy(); + acm_init_chwall_policy(); acm_bin_pol.secondary_policy_code = ACM_CHINESE_WALL_POLICY; - acm_secondary_ops = &acm_chinesewall_ops; + acm_secondary_ops = &acm_chinesewall_ops; break; case ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY: @@ -211,9 +211,9 @@ ret = -EINVAL; goto out; } - acm_init_ste_policy(); - acm_bin_pol.secondary_policy_code = ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY; - acm_secondary_ops = &acm_simple_type_enforcement_ops; + acm_init_ste_policy(); + acm_bin_pol.secondary_policy_code = ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY; + acm_secondary_ops = &acm_simple_type_enforcement_ops; break; default: @@ -222,96 +222,103 @@ } out: - write_unlock(&acm_bin_pol_rwlock); - - if (ret != ACM_OK) - { - printk("%s: Error setting policies.\n", __func__); + write_unlock(&acm_bin_pol_rwlock); + + if (ret != ACM_OK) + { + printk("%s: Error initializing policies.\n", __func__); /* here one could imagine a clean panic */ - return -EINVAL; - } - acm_setup(initrdidx, mbi, initial_images_start); - printk("%s: Enforcing Primary %s, Secondary %s.\n", __func__, - ACM_POLICY_NAME(acm_bin_pol.primary_policy_code), + return -EINVAL; + } + if (acm_setup(initrdidx, mbi, initial_images_start) != ACM_OK) + { + printk("%s: Error loading policy at boot time.\n", __func__); + /* ignore, just continue with the minimal hardcoded startup policy */ + } + printk("%s: Enforcing Primary %s, Secondary %s.\n", __func__, + ACM_POLICY_NAME(acm_bin_pol.primary_policy_code), ACM_POLICY_NAME(acm_bin_pol.secondary_policy_code)); - return ret; + return ret; } int acm_init_domain_ssid(domid_t id, ssidref_t ssidref) { - struct acm_ssid_domain *ssid; - struct domain *subj = find_domain_by_id(id); - int ret1, ret2; - - if (subj == NULL) - { - printk("%s: ACM_NULL_POINTER ERROR (id=%x).\n", __func__, id); - return ACM_NULL_POINTER_ERROR; - } - if ((ssid = xmalloc(struct acm_ssid_domain)) == NULL) - return ACM_INIT_SSID_ERROR; - - ssid->datatype = DOMAIN; - ssid->subject = subj; - ssid->domainid = subj->domain_id; - ssid->primary_ssid = NULL; - ssid->secondary_ssid = NULL; - - if (ACM_USE_SECURITY_POLICY != ACM_NULL_POLICY) - ssid->ssidref = ssidref; - else - ssid->ssidref = ACM_DEFAULT_SSID; - - subj->ssid = ssid; - /* now fill in primary and secondary parts; we only get here through hooks */ - if (acm_primary_ops->init_domain_ssid != NULL) - ret1 = acm_primary_ops->init_domain_ssid(&(ssid->primary_ssid), ssidref); - else - ret1 = ACM_OK; - - if (acm_secondary_ops->init_domain_ssid != NULL) - ret2 = acm_secondary_ops->init_domain_ssid(&(ssid->secondary_ssid), ssidref); - else - ret2 = ACM_OK; - - if ((ret1 != ACM_OK) || (ret2 != ACM_OK)) - { - printk("%s: ERROR instantiating individual ssids for domain 0x%02x.\n", - __func__, subj->domain_id); - acm_free_domain_ssid(ssid); - put_domain(subj); - return ACM_INIT_SSID_ERROR; - } - printk("%s: assigned domain %x the ssidref=%x.\n", + struct acm_ssid_domain *ssid; + struct domain *subj = find_domain_by_id(id); + int ret1, ret2; + + if (subj == NULL) + { + printk("%s: ACM_NULL_POINTER ERROR (id=%x).\n", __func__, id); + return ACM_NULL_POINTER_ERROR; + } + if ((ssid = xmalloc(struct acm_ssid_domain)) == NULL) + return ACM_INIT_SSID_ERROR; + + ssid->datatype = DOMAIN; + ssid->subject = subj; + ssid->domainid = subj->domain_id; + ssid->primary_ssid = NULL; + ssid->secondary_ssid = NULL; + + if (ACM_USE_SECURITY_POLICY != ACM_NULL_POLICY) + ssid->ssidref = ssidref; + else + ssid->ssidref = ACM_DEFAULT_SSID; + + subj->ssid = ssid; + /* now fill in primary and secondary parts; we only get here through hooks */ + if (acm_primary_ops->init_domain_ssid != NULL) + ret1 = acm_primary_ops->init_domain_ssid(&(ssid->primary_ssid), ssidref); + else + ret1 = ACM_OK; + + if (acm_secondary_ops->init_domain_ssid != NULL) + ret2 = acm_secondary_ops->init_domain_ssid(&(ssid->secondary_ssid), ssidref); + else + ret2 = ACM_OK; + + if ((ret1 != ACM_OK) || (ret2 != ACM_OK)) + { + printk("%s: ERROR instantiating individual ssids for domain 0x%02x.\n", + __func__, subj->domain_id); + acm_free_domain_ssid(ssid); + put_domain(subj); + return ACM_INIT_SSID_ERROR; + } + printk("%s: assigned domain %x the ssidref=%x.\n", __func__, id, ssid->ssidref); - put_domain(subj); - return ACM_OK; -} - - -int + put_domain(subj); + return ACM_OK; +} + + +void acm_free_domain_ssid(struct acm_ssid_domain *ssid) { - domid_t id; - - /* domain is already gone, just ssid is left */ - if (ssid == NULL) - { - printk("%s: ACM_NULL_POINTER ERROR.\n", __func__); - return ACM_NULL_POINTER_ERROR; - } - id = ssid->domainid; - ssid->subject = NULL; - - if (acm_primary_ops->free_domain_ssid != NULL) /* null policy */ - acm_primary_ops->free_domain_ssid(ssid->primary_ssid); - ssid->primary_ssid = NULL; - if (acm_secondary_ops->free_domain_ssid != NULL) - acm_secondary_ops->free_domain_ssid(ssid->secondary_ssid); - ssid->secondary_ssid = NULL; - xfree(ssid); - printkd("%s: Freed individual domain ssid (domain=%02x).\n", + /* domain is already gone, just ssid is left */ + if (ssid == NULL) + return; + + ssid->subject = NULL; + if (acm_primary_ops->free_domain_ssid != NULL) /* null policy */ + acm_primary_ops->free_domain_ssid(ssid->primary_ssid); + ssid->primary_ssid = NULL; + if (acm_secondary_ops->free_domain_ssid != NULL) + acm_secondary_ops->free_domain_ssid(ssid->secondary_ssid); + ssid->secondary_ssid = NULL; + xfree(ssid); + printkd("%s: Freed individual domain ssid (domain=%02x).\n", __func__, id); - return ACM_OK; -} +} + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff -r 19af31a59537 -r f31494465fb0 xen/acm/acm_null_hooks.c --- a/xen/acm/acm_null_hooks.c Fri Oct 21 11:06:17 2005 +++ b/xen/acm/acm_null_hooks.c Fri Oct 21 11:07:14 2005 @@ -11,37 +11,38 @@ * published by the Free Software Foundation, version 2 of the * License. */ + #include <acm/acm_hooks.h> static int null_init_domain_ssid(void **ssid, ssidref_t ssidref) { - return ACM_OK; + return ACM_OK; } static void null_free_domain_ssid(void *ssid) { - return; + return; } static int -null_dump_binary_policy(u8 *buf, u16 buf_size) -{ - return 0; +null_dump_binary_policy(u8 *buf, u32 buf_size) +{ + return 0; } static int -null_set_binary_policy(u8 *buf, u16 buf_size) -{ - return ACM_OK; +null_set_binary_policy(u8 *buf, u32 buf_size) +{ + return ACM_OK; } - + static int null_dump_stats(u8 *buf, u16 buf_size) { - /* no stats for NULL policy */ - return 0; + /* no stats for NULL policy */ + return 0; } static int @@ -54,25 +55,35 @@ /* now define the hook structure similarly to LSM */ struct acm_operations acm_null_ops = { - .init_domain_ssid = null_init_domain_ssid, - .free_domain_ssid = null_free_domain_ssid, - .dump_binary_policy = null_dump_binary_policy, - .set_binary_policy = null_set_binary_policy, - .dump_statistics = null_dump_stats, - .dump_ssid_types = null_dump_ssid_types, - /* domain management control hooks */ - .pre_domain_create = NULL, - .post_domain_create = NULL, - .fail_domain_create = NULL, - .post_domain_destroy = NULL, - /* event channel control hooks */ - .pre_eventchannel_unbound = NULL, - .fail_eventchannel_unbound = NULL, - .pre_eventchannel_interdomain = NULL, - .fail_eventchannel_interdomain = NULL, - /* grant table control hooks */ - .pre_grant_map_ref = NULL, - .fail_grant_map_ref = NULL, - .pre_grant_setup = NULL, - .fail_grant_setup = NULL + .init_domain_ssid = null_init_domain_ssid, + .free_domain_ssid = null_free_domain_ssid, + .dump_binary_policy = null_dump_binary_policy, + .set_binary_policy = null_set_binary_policy, + .dump_statistics = null_dump_stats, + .dump_ssid_types = null_dump_ssid_types, + /* domain management control hooks */ + .pre_domain_create = NULL, + .post_domain_create = NULL, + .fail_domain_create = NULL, + .post_domain_destroy = NULL, + /* event channel control hooks */ + .pre_eventchannel_unbound = NULL, + .fail_eventchannel_unbound = NULL, + .pre_eventchannel_interdomain = NULL, + .fail_eventchannel_interdomain = NULL, + /* grant table control hooks */ + .pre_grant_map_ref = NULL, + .fail_grant_map_ref = NULL, + .pre_grant_setup = NULL, + .fail_grant_setup = NULL }; + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff -r 19af31a59537 -r f31494465fb0 xen/acm/acm_policy.c --- a/xen/acm/acm_policy.c Fri Oct 21 11:06:17 2005 +++ b/xen/acm/acm_policy.c Fri Oct 21 11:07:14 2005 @@ -32,165 +32,166 @@ #include <acm/acm_endian.h> int -acm_set_policy(void *buf, u16 buf_size, int isuserbuffer) +acm_set_policy(void *buf, u32 buf_size, int isuserbuffer) { - u8 *policy_buffer = NULL; - struct acm_policy_buffer *pol; - + u8 *policy_buffer = NULL; + struct acm_policy_buffer *pol; + if (buf_size < sizeof(struct acm_policy_buffer)) - return -EFAULT; - - /* 1. copy buffer from domain */ - if ((policy_buffer = xmalloc_array(u8, buf_size)) == NULL) - return -ENOMEM; - - if (isuserbuffer) { - if (copy_from_user(policy_buffer, buf, buf_size)) + return -EFAULT; + + /* 1. copy buffer from domain */ + if ((policy_buffer = xmalloc_array(u8, buf_size)) == NULL) + return -ENOMEM; + + if (isuserbuffer) { + if (copy_from_user(policy_buffer, buf, buf_size)) { - printk("%s: Error copying!\n",__func__); - goto error_free; - } - } else - memcpy(policy_buffer, buf, buf_size); - - /* 2. some sanity checking */ - pol = (struct acm_policy_buffer *)policy_buffer; - - if ((ntohl(pol->magic) != ACM_MAGIC) || - (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)) + printk("%s: Error copying!\n",__func__); + goto error_free; + } + } else + memcpy(policy_buffer, buf, buf_size); + + /* 2. some sanity checking */ + pol = (struct acm_policy_buffer *)policy_buffer; + + if ((ntohl(pol->magic) != ACM_MAGIC) || + (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)) + printkd("%s: Wrong policy magics or versions!\n", __func__); + goto error_free; + } + if (buf_size != ntohl(pol->len)) { - printk("%s: ERROR in buf size.\n", __func__); - goto error_free; - } - - /* get bin_policy lock and rewrite policy (release old one) */ - write_lock(&acm_bin_pol_rwlock); - - /* 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. set secondary policy data */ - if (acm_secondary_ops->set_binary_policy(buf + ntohl(pol->secondary_buffer_offset), - ntohl(pol->len) - - ntohl(pol->secondary_buffer_offset))) - goto error_lock_free; - - write_unlock(&acm_bin_pol_rwlock); - xfree(policy_buffer); - return ACM_OK; + printk("%s: ERROR in buf size.\n", __func__); + goto error_free; + } + + /* get bin_policy lock and rewrite policy (release old one) */ + write_lock(&acm_bin_pol_rwlock); + + /* 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. set secondary policy data */ + if (acm_secondary_ops->set_binary_policy(buf + ntohl(pol->secondary_buffer_offset), + ntohl(pol->len) - + ntohl(pol->secondary_buffer_offset))) + goto error_lock_free; + + write_unlock(&acm_bin_pol_rwlock); + xfree(policy_buffer); + return ACM_OK; error_lock_free: - write_unlock(&acm_bin_pol_rwlock); + write_unlock(&acm_bin_pol_rwlock); error_free: - printk("%s: Error setting policy.\n", __func__); - xfree(policy_buffer); - return -EFAULT; -} - -int -acm_get_policy(void *buf, u16 buf_size) -{ - u8 *policy_buffer; - int ret; - struct acm_policy_buffer *bin_pol; - + printk("%s: Error setting policy.\n", __func__); + xfree(policy_buffer); + return -EFAULT; +} + +int +acm_get_policy(void *buf, u32 buf_size) +{ + u8 *policy_buffer; + int ret; + struct acm_policy_buffer *bin_pol; + if (buf_size < sizeof(struct acm_policy_buffer)) - return -EFAULT; - - if ((policy_buffer = xmalloc_array(u8, buf_size)) == NULL) - return -ENOMEM; - - read_lock(&acm_bin_pol_rwlock); - - bin_pol = (struct acm_policy_buffer *)policy_buffer; - bin_pol->magic = htonl(ACM_MAGIC); - 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 = htonl(ntohl(bin_pol->len)); - bin_pol->secondary_buffer_offset = htonl(ntohl(bin_pol->len)); + return -EFAULT; + + if ((policy_buffer = xmalloc_array(u8, buf_size)) == NULL) + return -ENOMEM; + + read_lock(&acm_bin_pol_rwlock); + + bin_pol = (struct acm_policy_buffer *)policy_buffer; + bin_pol->magic = htonl(ACM_MAGIC); + 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 = htonl(ntohl(bin_pol->len)); + bin_pol->secondary_buffer_offset = htonl(ntohl(bin_pol->len)); - 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) - goto error_free_unlock; - - bin_pol->len = htonl(ntohl(bin_pol->len) + ret); - bin_pol->secondary_buffer_offset = htonl(ntohl(bin_pol->len)); - - 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) - goto error_free_unlock; - - bin_pol->len = htonl(ntohl(bin_pol->len) + ret); - if (copy_to_user(buf, policy_buffer, ntohl(bin_pol->len))) - goto error_free_unlock; - - read_unlock(&acm_bin_pol_rwlock); - xfree(policy_buffer); - return ACM_OK; + 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) + goto error_free_unlock; + + bin_pol->len = htonl(ntohl(bin_pol->len) + ret); + bin_pol->secondary_buffer_offset = htonl(ntohl(bin_pol->len)); + + 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) + goto error_free_unlock; + + bin_pol->len = htonl(ntohl(bin_pol->len) + ret); + if (copy_to_user(buf, policy_buffer, ntohl(bin_pol->len))) + goto error_free_unlock; + + read_unlock(&acm_bin_pol_rwlock); + xfree(policy_buffer); + return ACM_OK; error_free_unlock: - read_unlock(&acm_bin_pol_rwlock); - printk("%s: Error getting policy.\n", __func__); - xfree(policy_buffer); - return -EFAULT; + read_unlock(&acm_bin_pol_rwlock); + printk("%s: Error getting policy.\n", __func__); + xfree(policy_buffer); + return -EFAULT; } int acm_dump_statistics(void *buf, u16 buf_size) -{ +{ /* send stats to user space */ - u8 *stats_buffer; - int len1, len2; - struct acm_stats_buffer acm_stats; - - if ((stats_buffer = xmalloc_array(u8, buf_size)) == NULL) - return -ENOMEM; - - read_lock(&acm_bin_pol_rwlock); + u8 *stats_buffer; + int len1, len2; + struct acm_stats_buffer acm_stats; + + if ((stats_buffer = xmalloc_array(u8, buf_size)) == NULL) + return -ENOMEM; + + read_lock(&acm_bin_pol_rwlock); - len1 = acm_primary_ops->dump_statistics(stats_buffer + sizeof(struct acm_stats_buffer), - buf_size - sizeof(struct acm_stats_buffer)); - if (len1 < 0) - goto error_lock_free; - - len2 = acm_secondary_ops->dump_statistics(stats_buffer + sizeof(struct acm_stats_buffer) + len1, - buf_size - sizeof(struct acm_stats_buffer) - len1); - if (len2 < 0) - goto error_lock_free; - - acm_stats.magic = htonl(ACM_MAGIC); - 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)); - - if (copy_to_user(buf, stats_buffer, sizeof(struct acm_stats_buffer) + len1 + len2)) - goto error_lock_free; - - read_unlock(&acm_bin_pol_rwlock); - xfree(stats_buffer); - return ACM_OK; + len1 = acm_primary_ops->dump_statistics(stats_buffer + sizeof(struct acm_stats_buffer), + buf_size - sizeof(struct acm_stats_buffer)); + if (len1 < 0) + goto error_lock_free; + + len2 = acm_secondary_ops->dump_statistics(stats_buffer + sizeof(struct acm_stats_buffer) + len1, + buf_size - sizeof(struct acm_stats_buffer) - len1); + if (len2 < 0) + goto error_lock_free; + + acm_stats.magic = htonl(ACM_MAGIC); + 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)); + + if (copy_to_user(buf, stats_buffer, sizeof(struct acm_stats_buffer) + len1 + len2)) + goto error_lock_free; + + read_unlock(&acm_bin_pol_rwlock); + xfree(stats_buffer); + return ACM_OK; error_lock_free: - read_unlock(&acm_bin_pol_rwlock); - xfree(stats_buffer); - return -EFAULT; + read_unlock(&acm_bin_pol_rwlock); + xfree(stats_buffer); + return -EFAULT; } @@ -198,57 +199,88 @@ acm_get_ssid(ssidref_t ssidref, u8 *buf, u16 buf_size) { /* send stats to user space */ - u8 *ssid_buffer; - int ret; - struct acm_ssid_buffer *acm_ssid; - if (buf_size < sizeof(struct acm_ssid_buffer)) - return -EFAULT; - - if ((ssid_buffer = xmalloc_array(u8, buf_size)) == NULL) - return -ENOMEM; - - read_lock(&acm_bin_pol_rwlock); - - acm_ssid = (struct acm_ssid_buffer *)ssid_buffer; - acm_ssid->len = sizeof(struct acm_ssid_buffer); - acm_ssid->ssidref = ssidref; - acm_ssid->primary_policy_code = acm_bin_pol.primary_policy_code; - acm_ssid->secondary_policy_code = acm_bin_pol.secondary_policy_code; - acm_ssid->primary_types_offset = acm_ssid->len; - - /* ret >= 0 --> ret == max_types */ - ret = acm_primary_ops->dump_ssid_types(ACM_PRIMARY(ssidref), - ssid_buffer + acm_ssid->primary_types_offset, - buf_size - acm_ssid->primary_types_offset); - if (ret < 0) - goto error_free_unlock; - - acm_ssid->len += ret; - acm_ssid->primary_max_types = ret; - - acm_ssid->secondary_types_offset = acm_ssid->len; - - ret = acm_secondary_ops->dump_ssid_types(ACM_SECONDARY(ssidref), - ssid_buffer + acm_ssid->secondary_types_offset, - buf_size - acm_ssid->secondary_types_offset); - if (ret < 0) - goto error_free_unlock; - - acm_ssid->len += ret; - acm_ssid->secondary_max_types = ret; - - if (copy_to_user(buf, ssid_buffer, acm_ssid->len)) - goto error_free_unlock; - - read_unlock(&acm_bin_pol_rwlock); - xfree(ssid_buffer); - return ACM_OK; + u8 *ssid_buffer; + int ret; + struct acm_ssid_buffer *acm_ssid; + if (buf_size < sizeof(struct acm_ssid_buffer)) + return -EFAULT; + + if ((ssid_buffer = xmalloc_array(u8, buf_size)) == NULL) + return -ENOMEM; + + read_lock(&acm_bin_pol_rwlock); + + acm_ssid = (struct acm_ssid_buffer *)ssid_buffer; + acm_ssid->len = sizeof(struct acm_ssid_buffer); + acm_ssid->ssidref = ssidref; + acm_ssid->primary_policy_code = acm_bin_pol.primary_policy_code; + acm_ssid->secondary_policy_code = acm_bin_pol.secondary_policy_code; + acm_ssid->primary_types_offset = acm_ssid->len; + + /* ret >= 0 --> ret == max_types */ + ret = acm_primary_ops->dump_ssid_types(ACM_PRIMARY(ssidref), + ssid_buffer + acm_ssid->primary_types_offset, + buf_size - acm_ssid->primary_types_offset); + if (ret < 0) + goto error_free_unlock; + + acm_ssid->len += ret; + acm_ssid->primary_max_types = ret; + acm_ssid->secondary_types_offset = acm_ssid->len; + + ret = acm_secondary_ops->dump_ssid_types(ACM_SECONDARY(ssidref), + ssid_buffer + acm_ssid->secondary_types_offset, + buf_size - acm_ssid->secondary_types_offset); + if (ret < 0) + goto error_free_unlock; + + acm_ssid->len += ret; + acm_ssid->secondary_max_types = ret; + + if (copy_to_user(buf, ssid_buffer, acm_ssid->len)) + goto error_free_unlock; + + read_unlock(&acm_bin_pol_rwlock); + xfree(ssid_buffer); + return ACM_OK; error_free_unlock: - read_unlock(&acm_bin_pol_rwlock); - printk("%s: Error getting ssid.\n", __func__); - xfree(ssid_buffer); - return -ENOMEM; -} - -/*eof*/ + read_unlock(&acm_bin_pol_rwlock); + printk("%s: Error getting ssid.\n", __func__); + xfree(ssid_buffer); + return -ENOMEM; +} + +int +acm_get_decision(ssidref_t ssidref1, ssidref_t ssidref2, + enum acm_hook_type hook) +{ + int ret = ACM_ACCESS_DENIED; + switch (hook) { + + case SHARING: + /* SHARING Hook restricts access in STE policy only */ + ret = acm_sharing(ssidref1, ssidref2); + break; + + default: + /* deny */ + break; + } + + printkd("%s: ssid1=%x, ssid2=%x, decision=%s.\n", + __func__, ssidref1, ssidref2, + (ret == ACM_ACCESS_PERMITTED) ? "GRANTED" : "DENIED"); + + return ret; +} + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff -r 19af31a59537 -r f31494465fb0 xen/acm/acm_simple_type_enforcement_hooks.c --- a/xen/acm/acm_simple_type_enforcement_hooks.c Fri Oct 21 11:06:17 2005 +++ b/xen/acm/acm_simple_type_enforcement_hooks.c Fri Oct 21 11:07:14 2005 @@ -24,6 +24,7 @@ * share at least on common type. * */ + #include <xen/lib.h> #include <asm/types.h> #include <asm/current.h> @@ -35,34 +36,34 @@ struct ste_binary_policy ste_bin_pol; static inline int have_common_type (ssidref_t ref1, ssidref_t ref2) { - int i; - for(i=0; i< ste_bin_pol.max_types; i++) - if ( ste_bin_pol.ssidrefs[ref1*ste_bin_pol.max_types + i] && - ste_bin_pol.ssidrefs[ref2*ste_bin_pol.max_types + i]) { - printkd("%s: common type #%02x.\n", __func__, i); - return 1; - } - return 0; + int i; + for(i=0; i< ste_bin_pol.max_types; i++) + if ( ste_bin_pol.ssidrefs[ref1*ste_bin_pol.max_types + i] && + ste_bin_pol.ssidrefs[ref2*ste_bin_pol.max_types + i]) { + printkd("%s: common type #%02x.\n", __func__, i); + return 1; + } + return 0; } /* Helper function: return = (subj and obj share a common type) */ static int share_common_type(struct domain *subj, struct domain *obj) { - ssidref_t ref_s, ref_o; - int ret; - - if ((subj == NULL) || (obj == NULL) || (subj->ssid == NULL) || (obj->ssid == NULL)) - return 0; - read_lock(&acm_bin_pol_rwlock); - /* lookup the policy-local ssids */ - ref_s = ((struct ste_ssid *)(GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, - (struct acm_ssid_domain *)subj->ssid)))->ste_ssidref; - ref_o = ((struct ste_ssid *)(GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, - (struct acm_ssid_domain *)obj->ssid)))->ste_ssidref; - /* check whether subj and obj share a common ste type */ - ret = have_common_type(ref_s, ref_o); - read_unlock(&acm_bin_pol_rwlock); - return ret; + ssidref_t ref_s, ref_o; + int ret; + + if ((subj == NULL) || (obj == NULL) || (subj->ssid == NULL) || (obj->ssid == NULL)) + return 0; + read_lock(&acm_bin_pol_rwlock); + /* lookup the policy-local ssids */ + ref_s = ((struct ste_ssid *)(GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, + (struct acm_ssid_domain *)subj->ssid)))->ste_ssidref; + ref_o = ((struct ste_ssid *)(GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, + (struct acm_ssid_domain *)obj->ssid)))->ste_ssidref; + /* check whether subj and obj share a common ste type */ + ret = have_common_type(ref_s, ref_o); + read_unlock(&acm_bin_pol_rwlock); + return ret; } /* @@ -71,26 +72,26 @@ */ int acm_init_ste_policy(void) { - /* minimal startup policy; policy write-locked already */ - ste_bin_pol.max_types = 1; - ste_bin_pol.max_ssidrefs = 2; - ste_bin_pol.ssidrefs = (domaintype_t *)xmalloc_array(domaintype_t, 2); - memset(ste_bin_pol.ssidrefs, 0, 2); - - if (ste_bin_pol.ssidrefs == NULL) - return ACM_INIT_SSID_ERROR; - - /* initialize state so that dom0 can start up and communicate with itself */ - ste_bin_pol.ssidrefs[1] = 1; - - /* init stats */ - atomic_set(&(ste_bin_pol.ec_eval_count), 0); - atomic_set(&(ste_bin_pol.ec_denied_count), 0); - atomic_set(&(ste_bin_pol.ec_cachehit_count), 0); - atomic_set(&(ste_bin_pol.gt_eval_count), 0); - atomic_set(&(ste_bin_pol.gt_denied_count), 0); - atomic_set(&(ste_bin_pol.gt_cachehit_count), 0); - return ACM_OK; + /* minimal startup policy; policy write-locked already */ + ste_bin_pol.max_types = 1; + ste_bin_pol.max_ssidrefs = 2; + ste_bin_pol.ssidrefs = (domaintype_t *)xmalloc_array(domaintype_t, 2); + memset(ste_bin_pol.ssidrefs, 0, 2); + + if (ste_bin_pol.ssidrefs == NULL) + return ACM_INIT_SSID_ERROR; + + /* initialize state so that dom0 can start up and communicate with itself */ + ste_bin_pol.ssidrefs[1] = 1; + + /* init stats */ + atomic_set(&(ste_bin_pol.ec_eval_count), 0); + atomic_set(&(ste_bin_pol.ec_denied_count), 0); + atomic_set(&(ste_bin_pol.ec_cachehit_count), 0); + atomic_set(&(ste_bin_pol.gt_eval_count), 0); + atomic_set(&(ste_bin_pol.gt_denied_count), 0); + atomic_set(&(ste_bin_pol.gt_cachehit_count), 0); + return ACM_OK; } @@ -98,62 +99,68 @@ static int ste_init_domain_ssid(void **ste_ssid, ssidref_t ssidref) { - int i; - struct ste_ssid *ste_ssidp = xmalloc(struct ste_ssid); - traceprintk("%s.\n", __func__); - - if (ste_ssidp == NULL) - return ACM_INIT_SSID_ERROR; - - /* get policy-local ssid reference */ - ste_ssidp->ste_ssidref = GET_SSIDREF(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, ssidref); - if ((ste_ssidp->ste_ssidref >= ste_bin_pol.max_ssidrefs) || - (ste_ssidp->ste_ssidref == ACM_DEFAULT_LOCAL_SSID)) { - printkd("%s: ERROR ste_ssidref (%x) undefined or unset (0).\n", - __func__, ste_ssidp->ste_ssidref); - xfree(ste_ssidp); - return ACM_INIT_SSID_ERROR; - } - /* clean ste cache */ - for (i=0; i<ACM_TE_CACHE_SIZE; i++) - ste_ssidp->ste_cache[i].valid = FREE; - - (*ste_ssid) = ste_ssidp; - printkd("%s: determined ste_ssidref to %x.\n", - __func__, ste_ssidp->ste_ssidref); - return ACM_OK; + int i; + struct ste_ssid *ste_ssidp = xmalloc(struct ste_ssid); + traceprintk("%s.\n", __func__); + + if (ste_ssidp == NULL) + return ACM_INIT_SSID_ERROR; + + /* get policy-local ssid reference */ + ste_ssidp->ste_ssidref = GET_SSIDREF(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, ssidref); + if ((ste_ssidp->ste_ssidref >= ste_bin_pol.max_ssidrefs) || + (ste_ssidp->ste_ssidref == ACM_DEFAULT_LOCAL_SSID)) { + printkd("%s: ERROR ste_ssidref (%x) undefined or unset (0).\n", + __func__, ste_ssidp->ste_ssidref); + xfree(ste_ssidp); + return ACM_INIT_SSID_ERROR; + } + /* clean ste cache */ + for (i=0; i<ACM_TE_CACHE_SIZE; i++) + ste_ssidp->ste_cache[i].valid = FREE; + + (*ste_ssid) = ste_ssidp; + printkd("%s: determined ste_ssidref to %x.\n", + __func__, ste_ssidp->ste_ssidref); + return ACM_OK; } static void ste_free_domain_ssid(void *ste_ssid) { - traceprintk("%s.\n", __func__); - if (ste_ssid != NULL) - xfree(ste_ssid); - return; + traceprintk("%s.\n", __func__); + if (ste_ssid != NULL) + xfree(ste_ssid); + return; } /* dump type enforcement cache; policy read-locked already */ static int -ste_dump_policy(u8 *buf, u16 buf_size) { - struct acm_ste_policy_buffer *ste_buf = (struct acm_ste_policy_buffer *)buf; - int ret = 0; - - 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 + ntohl(ste_buf->ste_ssid_offset), - ste_bin_pol.ssidrefs, - sizeof(domaintype_t), - ste_bin_pol.max_ssidrefs*ste_bin_pol.max_types); - - return ret; +ste_dump_policy(u8 *buf, u32 buf_size) { + struct acm_ste_policy_buffer *ste_buf = (struct acm_ste_policy_buffer *)buf; + int ret = 0; + + if (buf_size < sizeof(struct acm_ste_policy_buffer)) + return -EINVAL; + + 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; + + if (buf_size < ret) + return -EINVAL; + + /* now copy buffer over */ + 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); + + return ret; } /* ste_init_state is called when a policy is changed to detect violations (return != 0). @@ -176,83 +183,83 @@ /* go through all domains and adjust policy as if this domain was started now */ pd = &domain_list; for ( pd = &domain_list; *pd != NULL; pd = &(*pd)->next_in_list ) { - ste_ssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, - (struct acm_ssid_domain *)(*pd)->ssid); - ste_ssidref = ste_ssid->ste_ssidref; - traceprintk("%s: validating policy for eventch domain %x (ste-Ref=%x).\n", - __func__, (*pd)->domain_id, ste_ssidref); - /* a) check for event channel conflicts */ - for (port=0; port < NR_EVTCHN_BUCKETS; port++) { - spin_lock(&(*pd)->evtchn_lock); - if ((*pd)->evtchn[port] == NULL) { - spin_unlock(&(*pd)->evtchn_lock); - continue; - } - if ((*pd)->evtchn[port]->state == ECS_INTERDOMAIN) { - rdom = (*pd)->evtchn[port]->u.interdomain.remote_dom; - rdomid = rdom->domain_id; - /* rdom now has remote domain */ - ste_rssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, - (struct acm_ssid_domain *)(rdom->ssid)); - ste_rssidref = ste_rssid->ste_ssidref; - } else if ((*pd)->evtchn[port]->state == ECS_UNBOUND) { - rdomid = (*pd)->evtchn[port]->u.unbound.remote_domid; - if ((rdom = find_domain_by_id(rdomid)) == NULL) { - printk("%s: Error finding domain to id %x!\n", __func__, rdomid); - goto out; - } - /* rdom now has remote domain */ - ste_rssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, - (struct acm_ssid_domain *)(rdom->ssid)); - ste_rssidref = ste_rssid->ste_ssidref; - put_domain(rdom); - } else { - spin_unlock(&(*pd)->evtchn_lock); - continue; /* port unused */ - } - spin_unlock(&(*pd)->evtchn_lock); - - /* rdom now has remote domain */ - ste_rssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, - (struct acm_ssid_domain *)(rdom->ssid)); - ste_rssidref = ste_rssid->ste_ssidref; - traceprintk("%s: eventch: domain %x (ssidref %x) --> domain %x (rssidref %x) used (port %x).\n", - __func__, (*pd)->domain_id, ste_ssidref, rdom->domain_id, ste_rssidref, port); - /* check whether on subj->ssid, obj->ssid share a common type*/ - if (!have_common_type(ste_ssidref, ste_rssidref)) { - printkd("%s: Policy violation in event channel domain %x -> domain %x.\n", - __func__, (*pd)->domain_id, rdomid); - goto out; - } - } - /* b) check for grant table conflicts on shared pages */ - if ((*pd)->grant_table->shared == NULL) { - printkd("%s: Grant ... sharing for domain %x not setup!\n", __func__, (*pd)->domain_id); - continue; - } - for ( i = 0; i < NR_GRANT_ENTRIES; i++ ) { - sha_copy = (*pd)->grant_table->shared[i]; - if ( sha_copy.flags ) { - printkd("%s: grant dom (%hu) SHARED (%d) flags:(%hx) dom:(%hu) frame:(%lx)\n", - __func__, (*pd)->domain_id, i, sha_copy.flags, sha_copy.domid, - (unsigned long)sha_copy.frame); - rdomid = sha_copy.domid; - if ((rdom = find_domain_by_id(rdomid)) == NULL) { - printkd("%s: domain not found ERROR!\n", __func__); - goto out; - }; - /* rdom now has remote domain */ - ste_rssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, - (struct acm_ssid_domain *)(rdom->ssid)); - ste_rssidref = ste_rssid->ste_ssidref; - put_domain(rdom); - if (!have_common_type(ste_ssidref, ste_rssidref)) { - printkd("%s: Policy violation in grant table sharing domain %x -> domain %x.\n", - __func__, (*pd)->domain_id, rdomid); - goto out; - } - } - } + ste_ssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, + (struct acm_ssid_domain *)(*pd)->ssid); + ste_ssidref = ste_ssid->ste_ssidref; + traceprintk("%s: validating policy for eventch domain %x (ste-Ref=%x).\n", + __func__, (*pd)->domain_id, ste_ssidref); + /* a) check for event channel conflicts */ + for (port=0; port < NR_EVTCHN_BUCKETS; port++) { + spin_lock(&(*pd)->evtchn_lock); + if ((*pd)->evtchn[port] == NULL) { + spin_unlock(&(*pd)->evtchn_lock); + continue; + } + if ((*pd)->evtchn[port]->state == ECS_INTERDOMAIN) { + rdom = (*pd)->evtchn[port]->u.interdomain.remote_dom; + rdomid = rdom->domain_id; + /* rdom now has remote domain */ + ste_rssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, + (struct acm_ssid_domain *)(rdom->ssid)); + ste_rssidref = ste_rssid->ste_ssidref; + } else if ((*pd)->evtchn[port]->state == ECS_UNBOUND) { + rdomid = (*pd)->evtchn[port]->u.unbound.remote_domid; + if ((rdom = find_domain_by_id(rdomid)) == NULL) { + printk("%s: Error finding domain to id %x!\n", __func__, rdomid); + goto out; + } + /* rdom now has remote domain */ + ste_rssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, + (struct acm_ssid_domain *)(rdom->ssid)); + ste_rssidref = ste_rssid->ste_ssidref; + put_domain(rdom); + } else { + spin_unlock(&(*pd)->evtchn_lock); + continue; /* port unused */ + } + spin_unlock(&(*pd)->evtchn_lock); + + /* rdom now has remote domain */ + ste_rssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, + (struct acm_ssid_domain *)(rdom->ssid)); + ste_rssidref = ste_rssid->ste_ssidref; + traceprintk("%s: eventch: domain %x (ssidref %x) --> domain %x (rssidref %x) used (port %x).\n", + __func__, (*pd)->domain_id, ste_ssidref, rdom->domain_id, ste_rssidref, port); + /* check whether on subj->ssid, obj->ssid share a common type*/ + if (!have_common_type(ste_ssidref, ste_rssidref)) { + printkd("%s: Policy violation in event channel domain %x -> domain %x.\n", + __func__, (*pd)->domain_id, rdomid); + goto out; + } + } + /* b) check for grant table conflicts on shared pages */ + if ((*pd)->grant_table->shared == NULL) { + printkd("%s: Grant ... sharing for domain %x not setup!\n", __func__, (*pd)->domain_id); + continue; + } + for ( i = 0; i < NR_GRANT_ENTRIES; i++ ) { + sha_copy = (*pd)->grant_table->shared[i]; + if ( sha_copy.flags ) { + printkd("%s: grant dom (%hu) SHARED (%d) flags:(%hx) dom:(%hu) frame:(%lx)\n", + __func__, (*pd)->domain_id, i, sha_copy.flags, sha_copy.domid, + (unsigned long)sha_copy.frame); + rdomid = sha_copy.domid; + if ((rdom = find_domain_by_id(rdomid)) == NULL) { + printkd("%s: domain not found ERROR!\n", __func__); + goto out; + }; + /* rdom now has remote domain */ + ste_rssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, + (struct acm_ssid_domain *)(rdom->ssid)); + ste_rssidref = ste_rssid->ste_ssidref; + put_domain(rdom); + if (!have_common_type(ste_ssidref, ste_rssidref)) { + printkd("%s: Policy violation in grant table sharing domain %x -> domain %x.\n", + __func__, (*pd)->domain_id, rdomid); + goto out; + } + } + } } violation = 0; out: @@ -267,110 +274,78 @@ /* set new policy; policy write-locked already */ static int -ste_set_policy(u8 *buf, u16 buf_size) -{ - struct acm_ste_policy_buffer *ste_buf = (struct acm_ste_policy_buffer *)buf; - void *ssidrefsbuf; - struct ste_ssid *ste_ssid; - struct domain **pd; - int i; - - /* Convert endianess of policy */ - 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); - if (ssidrefsbuf == NULL) { - return -ENOMEM; - } - if (ste_buf->ste_ssid_offset + sizeof(domaintype_t) * ste_buf->ste_max_ssidrefs*ste_buf->ste_max_types > buf_size) - goto error_free; - - arrcpy(ssidrefsbuf, - buf + ste_buf->ste_ssid_offset, - sizeof(domaintype_t), - ste_buf->ste_max_ssidrefs*ste_buf->ste_max_types); - - /* 2. now re-calculate sharing decisions based on running domains; - * this can fail if new policy is conflicting with sharing of running domains - * now: reject violating new policy; future: adjust sharing through revoking sharing */ - if (ste_init_state(ste_buf, (domaintype_t *)ssidrefsbuf)) { - printk("%s: New policy conflicts with running domains. Policy load aborted.\n", __func__); - goto error_free; /* new policy conflicts with sharing of running domains */ - } - /* 3. replace old policy (activate new policy) */ - ste_bin_pol.max_types = ste_buf->ste_max_types; - ste_bin_pol.max_ssidrefs = ste_buf->ste_max_ssidrefs; - if (ste_bin_pol.ssidrefs) - xfree(ste_bin_pol.ssidrefs); - ste_bin_pol.ssidrefs = (domaintype_t *)ssidrefsbuf; - - /* clear all ste caches */ - read_lock(&domlist_lock); - pd = &domain_list; - for ( pd = &domain_list; *pd != NULL; pd = &(*pd)->next_in_list ) { - ste_ssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, - (struct acm_ssid_domain *)(*pd)->ssid); - for (i=0; i<ACM_TE_CACHE_SIZE; i++) - ste_ssid->ste_cache[i].valid = FREE; - } - read_unlock(&domlist_lock); - return ACM_OK; - -error_free: - printk("%s: ERROR setting policy.\n", __func__); - if (ssidrefsbuf != NULL) xfree(ssidrefsbuf); - return -EFAULT; +ste_set_policy(u8 *buf, u32 buf_size) +{ + struct acm_ste_policy_buffer *ste_buf = (struct acm_ste_policy_buffer *)buf; + void *ssidrefsbuf; + struct ste_ssid *ste_ssid; + struct domain **pd; + int i; + + if (buf_size < sizeof(struct acm_ste_policy_buffer)) + return -EINVAL; + + /* Convert endianess of policy */ + 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); + if (ssidrefsbuf == NULL) { + return -ENOMEM; + } + if (ste_buf->ste_ssid_offset + sizeof(domaintype_t) * ste_buf->ste_max_ssidrefs*ste_buf->ste_max_types > buf_size) + goto error_free; + + arrcpy(ssidrefsbuf, + buf + ste_buf->ste_ssid_offset, + sizeof(domaintype_t), + ste_buf->ste_max_ssidrefs*ste_buf->ste_max_types); + + /* 2. now re-calculate sharing decisions based on running domains; + * this can fail if new policy is conflicting with sharing of running domains + * now: reject violating new policy; future: adjust sharing through revoking sharing */ + if (ste_init_state(ste_buf, (domaintype_t *)ssidrefsbuf)) { + printk("%s: New policy conflicts with running domains. Policy load aborted.\n", __func__); + goto error_free; /* new policy conflicts with sharing of running domains */ + } + /* 3. replace old policy (activate new policy) */ + ste_bin_pol.max_types = ste_buf->ste_max_types; + ste_bin_pol.max_ssidrefs = ste_buf->ste_max_ssidrefs; + if (ste_bin_pol.ssidrefs) + xfree(ste_bin_pol.ssidrefs); + ste_bin_pol.ssidrefs = (domaintype_t *)ssidrefsbuf; + + /* clear all ste caches */ + read_lock(&domlist_lock); + pd = &domain_list; + for ( pd = &domain_list; *pd != NULL; pd = &(*pd)->next_in_list ) { + ste_ssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, + (struct acm_ssid_domain *)(*pd)->ssid); + for (i=0; i<ACM_TE_CACHE_SIZE; i++) + ste_ssid->ste_cache[i].valid = FREE; + } + read_unlock(&domlist_lock); + return ACM_OK; + + error_free: + printk("%s: ERROR setting policy.\n", __func__); + if (ssidrefsbuf != NULL) xfree(ssidrefsbuf); + return -EFAULT; } static int ste_dump_stats(u8 *buf, u16 buf_len) { struct acm_ste_stats_buffer stats; - -#ifdef ACM_DEBUG - int i; - struct ste_ssid *ste_ssid; - struct domain **pd; - - printk("ste: Decision caches:\n"); - /* go through all domains and adjust policy as if this domain was started now */ - read_lock(&domlist_lock); /* go by domain? or directly by global? event/grant list */ - pd = &domain_list; - for ( pd = &domain_list; *pd != NULL; pd = &(*pd)->next_in_list ) { - printk("ste: Cache Domain %02x.\n", (*pd)->domain_id); - ste_ssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, - (struct acm_ssid_domain *)(*pd)->ssid); - for (i=0; i<ACM_TE_CACHE_SIZE; i++) - printk("\t\tcache[%02x] = %s, domid=%x.\n", i, - (ste_ssid->ste_cache[i].valid == VALID) ? - "VALID" : "FREE", - (ste_ssid->ste_cache[i].valid == VALID) ? - ste_ssid->ste_cache[i].id : 0xffffffff); - } - read_unlock(&domlist_lock); - /* init stats */ - printk("STE-Policy Security Hook Statistics:\n"); - printk("ste: event_channel eval_count = %x\n", atomic_read(&(ste_bin_pol.ec_eval_count))); - printk("ste: event_channel denied_count = %x\n", atomic_read(&(ste_bin_pol.ec_denied_count))); - printk("ste: event_channel cache_hit_count = %x\n", atomic_read(&(ste_bin_pol.ec_cachehit_count))); - printk("ste:\n"); - printk("ste: grant_table eval_count = %x\n", atomic_read(&(ste_bin_pol.gt_eval_count))); - printk("ste: grant_table denied_count = %x\n", atomic_read(&(ste_bin_pol.gt_denied_count))); - printk("ste: grant_table cache_hit_count = %x\n", atomic_read(&(ste_bin_pol.gt_cachehit_count))); -#endif - - if (buf_len < sizeof(struct acm_ste_stats_buffer)) - return -ENOMEM; /* now send the hook counts to user space */ stats.ec_eval_count = htonl(atomic_read(&ste_bin_pol.ec_eval_count)); @@ -379,6 +354,10 @@ stats.gt_denied_count = htonl(atomic_read(&ste_bin_pol.gt_denied_count)); stats.ec_cachehit_count = htonl(atomic_read(&ste_bin_pol.ec_cachehit_count)); stats.gt_cachehit_count = htonl(atomic_read(&ste_bin_pol.gt_cachehit_count)); + + if (buf_len < sizeof(struct acm_ste_stats_buffer)) + return -ENOMEM; + memcpy(buf, &stats, sizeof(struct acm_ste_stats_buffer)); return sizeof(struct acm_ste_stats_buffer); } @@ -392,12 +371,12 @@ if (ste_bin_pol.max_types > len) return -EFAULT; - if (ssidref >= ste_bin_pol.max_ssidrefs) - return -EFAULT; + if (ssidref >= ste_bin_pol.max_ssidrefs) + return -EFAULT; /* read types for chwall ssidref */ for(i=0; i< ste_bin_pol.max_types; i++) { - if (ste_bin_pol.ssidrefs[ssidref * ste_bin_pol.max_types + i]) + if (ste_bin_pol.ssidrefs[ssidref * ste_bin_pol.max_types + i]) buf[i] = 1; else buf[i] = 0; @@ -409,40 +388,40 @@ * returns 1 == cache hit */ static int inline check_cache(struct domain *dom, domid_t rdom) { - struct ste_ssid *ste_ssid; - int i; - - printkd("checking cache: %x --> %x.\n", dom->domain_id, rdom); - ste_ssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, - (struct acm_ssid_domain *)(dom)->ssid); - - for(i=0; i< ACM_TE_CACHE_SIZE; i++) { - if ((ste_ssid->ste_cache[i].valid == VALID) && - (ste_ssid->ste_cache[i].id == rdom)) { - printkd("cache hit (entry %x, id= %x!\n", i, ste_ssid->ste_cache[i].id); - return 1; - } - } - return 0; + struct ste_ssid *ste_ssid; + int i; + + printkd("checking cache: %x --> %x.\n", dom->domain_id, rdom); + ste_ssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, + (struct acm_ssid_domain *)(dom)->ssid); + + for(i=0; i< ACM_TE_CACHE_SIZE; i++) { + if ((ste_ssid->ste_cache[i].valid == VALID) && + (ste_ssid->ste_cache[i].id == rdom)) { + printkd("cache hit (entry %x, id= %x!\n", i, ste_ssid->ste_cache[i].id); + return 1; + } + } + return 0; } /* we only get here if there is NO entry yet; no duplication check! */ static void inline cache_result(struct domain *subj, struct domain *obj) { - struct ste_ssid *ste_ssid; - int i; - printkd("caching from doms: %x --> %x.\n", subj->domain_id, obj->domain_id); - ste_ssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, - (struct acm_ssid_domain *)(subj)->ssid); - for(i=0; i< ACM_TE_CACHE_SIZE; i++) - if (ste_ssid->ste_cache[i].valid == FREE) - break; - if (i< ACM_TE_CACHE_SIZE) { - ste_ssid->ste_cache[i].valid = VALID; - ste_ssid->ste_cache[i].id = obj->domain_id; - } else - printk ("Cache of dom %x is full!\n", subj->domain_id); + struct ste_ssid *ste_ssid; + int i; + printkd("caching from doms: %x --> %x.\n", subj->domain_id, obj->domain_id); + ste_ssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, + (struct acm_ssid_domain *)(subj)->ssid); + for(i=0; i< ACM_TE_CACHE_SIZE; i++) + if (ste_ssid->ste_cache[i].valid == FREE) + break; + if (i< ACM_TE_CACHE_SIZE) { + ste_ssid->ste_cache[i].valid = VALID; + ste_ssid->ste_cache[i].id = obj->domain_id; + } else + printk ("Cache of dom %x is full!\n", subj->domain_id); } /* deletes entries for domain 'id' from all caches (re-use) */ @@ -458,12 +437,12 @@ read_lock(&domlist_lock); /* look through caches of all domains */ pd = &domain_list; for ( pd = &domain_list; *pd != NULL; pd = &(*pd)->next_in_list ) { - ste_ssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, - (struct acm_ssid_domain *)(*pd)->ssid); - for (i=0; i<ACM_TE_CACHE_SIZE; i++) - if ((ste_ssid->ste_cache[i].valid == VALID) && - (ste_ssid->ste_cache[i].id = id)) - ste_ssid->ste_cache[i].valid = FREE; + ste_ssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, + (struct acm_ssid_domain *)(*pd)->ssid); + for (i=0; i<ACM_TE_CACHE_SIZE; i++) + if ((ste_ssid->ste_cache[i].valid == VALID) && + (ste_ssid->ste_cache[i].id = id)) + ste_ssid->ste_cache[i].valid = FREE; } read_unlock(&domlist_lock); } @@ -482,15 +461,15 @@ read_lock(&acm_bin_pol_rwlock); ste_ssidref = GET_SSIDREF(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, ssidref); if (ste_ssidref == ACM_DEFAULT_LOCAL_SSID) { - printk("%s: ERROR STE SSID is NOT SET but policy enforced.\n", __func__); - read_unlock(&acm_bin_pol_rwlock); - return ACM_ACCESS_DENIED; /* catching and indicating config error */ + printk("%s: ERROR STE SSID is NOT SET but policy enforced.\n", __func__); + read_unlock(&acm_bin_pol_rwlock); + return ACM_ACCESS_DENIED; /* catching and indicating config error */ } if (ste_ssidref >= ste_bin_pol.max_ssidrefs) { - printk("%s: ERROR ste_ssidref > max(%x).\n", - __func__, ste_bin_pol.max_ssidrefs-1); - read_unlock(&acm_bin_pol_rwlock); - return ACM_ACCESS_DENIED; + printk("%s: ERROR ste_ssidref > max(%x).\n", + __func__, ste_bin_pol.max_ssidrefs-1); + read_unlock(&acm_bin_pol_rwlock); + return ACM_ACCESS_DENIED; } read_unlock(&acm_bin_pol_rwlock); return ACM_ACCESS_PERMITTED; @@ -506,163 +485,193 @@ /* -------- EVENTCHANNEL OPERATIONS -----------*/ static int ste_pre_eventchannel_unbound(domid_t id) { - struct domain *subj, *obj; - int ret; - traceprintk("%s: dom%x-->dom%x.\n", - __func__, current->domain->domain_id, id); - - if (check_cache(current->domain, id)) { - atomic_inc(&ste_bin_pol.ec_cachehit_count); - return ACM_ACCESS_PERMITTED; - } - atomic_inc(&ste_bin_pol.ec_eval_count); - subj = current->domain; - obj = find_domain_by_id(id); - - if (share_common_type(subj, obj)) { - cache_result(subj, obj); - ret = ACM_ACCESS_PERMITTED; - } else { - atomic_inc(&ste_bin_pol.ec_denied_count); - ret = ACM_ACCESS_DENIED; - } - if (obj != NULL) - put_domain(obj); - return ret; + struct domain *subj, *obj; + int ret; + traceprintk("%s: dom%x-->dom%x.\n", + __func__, current->domain->domain_id, id); + + if (check_cache(current->domain, id)) { + atomic_inc(&ste_bin_pol.ec_cachehit_count); + return ACM_ACCESS_PERMITTED; + } + atomic_inc(&ste_bin_pol.ec_eval_count); + subj = current->domain; + obj = find_domain_by_id(id); + + if (share_common_type(subj, obj)) { + cache_result(subj, obj); + ret = ACM_ACCESS_PERMITTED; + } else { + atomic_inc(&ste_bin_pol.ec_denied_count); + ret = ACM_ACCESS_DENIED; + } + if (obj != NULL) + put_domain(obj); + return ret; } static int ste_pre_eventchannel_interdomain(domid_t id1, domid_t id2) { - struct domain *subj, *obj; - int ret; - traceprintk("%s: dom%x-->dom%x.\n", __func__, - (id1 == DOMID_SELF) ? current->domain->domain_id : id1, - (id2 == DOMID_SELF) ? current->domain->domain_id : id2); - - /* following is a bit longer but ensures that we - * "put" only domains that we where "find"-ing - */ - if (id1 == DOMID_SELF) id1 = current->domain->domain_id; - if (id2 == DOMID_SELF) id2 = current->domain->domain_id; - - subj = find_domain_by_id(id1); - obj = find_domain_by_id(id2); - if ((subj == NULL) || (obj == NULL)) { - ret = ACM_ACCESS_DENIED; - goto out; - } - /* cache check late, but evtchn is not on performance critical path */ - if (check_cache(subj, obj->domain_id)) { - atomic_inc(&ste_bin_pol.ec_cachehit_count); - ret = ACM_ACCESS_PERMITTED; - goto out; - } - atomic_inc(&ste_bin_pol.ec_eval_count); - - if (share_common_type(subj, obj)) { - cache_result(subj, obj); - ret = ACM_ACCESS_PERMITTED; - } else { - atomic_inc(&ste_bin_pol.ec_denied_count); - ret = ACM_ACCESS_DENIED; - } + struct domain *subj, *obj; + int ret; + traceprintk("%s: dom%x-->dom%x.\n", __func__, + (id1 == DOMID_SELF) ? current->domain->domain_id : id1, + (id2 == DOMID_SELF) ? current->domain->domain_id : id2); + + /* following is a bit longer but ensures that we + * "put" only domains that we where "find"-ing + */ + if (id1 == DOMID_SELF) id1 = current->domain->domain_id; + if (id2 == DOMID_SELF) id2 = current->domain->domain_id; + + subj = find_domain_by_id(id1); + obj = find_domain_by_id(id2); + if ((subj == NULL) || (obj == NULL)) { + ret = ACM_ACCESS_DENIED; + goto out; + } + /* cache check late, but evtchn is not on performance critical path */ + if (check_cache(subj, obj->domain_id)) { + atomic_inc(&ste_bin_pol.ec_cachehit_count); + ret = ACM_ACCESS_PERMITTED; + goto out; + } + atomic_inc(&ste_bin_pol.ec_eval_count); + + if (share_common_type(subj, obj)) { + cache_result(subj, obj); + ret = ACM_ACCESS_PERMITTED; + } else { + atomic_inc(&ste_bin_pol.ec_denied_count); + ret = ACM_ACCESS_DENIED; + } out: - if (obj != NULL) - put_domain(obj); - if (subj != NULL) - put_domain(subj); - return ret; + if (obj != NULL) + put_domain(obj); + if (subj != NULL) + put_domain(subj); + return ret; } /* -------- SHARED MEMORY OPERATIONS -----------*/ static int ste_pre_grant_map_ref (domid_t id) { - struct domain *obj, *subj; - int ret; - traceprintk("%s: dom%x-->dom%x.\n", __func__, - current->domain->domain_id, id); - - if (check_cache(current->domain, id)) { - atomic_inc(&ste_bin_pol.gt_cachehit_count); - return ACM_ACCESS_PERMITTED; - } - atomic_inc(&ste_bin_pol.gt_eval_count); - subj = current->domain; - obj = find_domain_by_id(id); - - if (share_common_type(subj, obj)) { - cache_result(subj, obj); - ret = ACM_ACCESS_PERMITTED; - } else { - atomic_inc(&ste_bin_pol.gt_denied_count); - printkd("%s: ACCESS DENIED!\n", __func__); - ret = ACM_ACCESS_DENIED; - } - if (obj != NULL) - put_domain(obj); - return ret; -} + struct domain *obj, *subj; + int ret; + traceprintk("%s: dom%x-->dom%x.\n", __func__, + current->domain->domain_id, id); + + if (check_cache(current->domain, id)) { + atomic_inc(&ste_bin_pol.gt_cachehit_count); + return ACM_ACCESS_PERMITTED; + } + atomic_inc(&ste_bin_pol.gt_eval_count); + subj = current->domain; + obj = find_domain_by_id(id); + + if (share_common_type(subj, obj)) { + cache_result(subj, obj); + ret = ACM_ACCESS_PERMITTED; + } else { + atomic_inc(&ste_bin_pol.gt_denied_count); + printkd("%s: ACCESS DENIED!\n", __func__); + ret = ACM_ACCESS_DENIED; + } + if (obj != NULL) + put_domain(obj); + return ret; +} + /* since setting up grant tables involves some implicit information flow from the creating domain to the domain that is setup, we check types in addition to the general authorization */ static int ste_pre_grant_setup (domid_t id) { - struct domain *obj, *subj; - int ret; - traceprintk("%s: dom%x-->dom%x.\n", __func__, - current->domain->domain_id, id); - - if (check_cache(current->domain, id)) { - atomic_inc(&ste_bin_pol.gt_cachehit_count); - return ACM_ACCESS_PERMITTED; - } - atomic_inc(&ste_bin_pol.gt_eval_count); - /* a) check authorization (eventually use specific capabilities) */ - if (!IS_PRIV(current->domain)) { - printk("%s: Grant table management authorization denied ERROR!\n", __func__); - return ACM_ACCESS_DENIED; - } - /* b) check types */ - subj = current->domain; - obj = find_domain_by_id(id); - - if (share_common_type(subj, obj)) { - cache_result(subj, obj); - ret = ACM_ACCESS_PERMITTED; - } else { - atomic_inc(&ste_bin_pol.gt_denied_count); - ret = ACM_ACCESS_DENIED; - } - if (obj != NULL) - put_domain(obj); - return ret; -} + struct domain *obj, *subj; + int ret; + traceprintk("%s: dom%x-->dom%x.\n", __func__, + current->domain->domain_id, id); + + if (check_cache(current->domain, id)) { + atomic_inc(&ste_bin_pol.gt_cachehit_count); + return ACM_ACCESS_PERMITTED; + } + atomic_inc(&ste_bin_pol.gt_eval_count); + /* a) check authorization (eventually use specific capabilities) */ + if (!IS_PRIV(current->domain)) { + printk("%s: Grant table management authorization denied ERROR!\n", __func__); + return ACM_ACCESS_DENIED; + } + /* b) check types */ + subj = current->domain; + obj = find_domain_by_id(id); + + if (share_common_type(subj, obj)) { + cache_result(subj, obj); + ret = ACM_ACCESS_PERMITTED; + } else { + atomic_inc(&ste_bin_pol.gt_denied_count); + ret = ACM_ACCESS_DENIED; + } + if (obj != NULL) + put_domain(obj); + return ret; +} + +/* -------- DOMAIN-Requested Decision hooks -----------*/ + +static int +ste_sharing(ssidref_t ssidref1, ssidref_t ssidref2) { + if (have_common_type ( + GET_SSIDREF(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, ssidref1), + GET_SSIDREF(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, ssidref2) + )) + return ACM_ACCESS_PERMITTED; + else + return ACM_ACCESS_DENIED; +} + /* now define the hook structure similarly to LSM */ struct acm_operations acm_simple_type_enforcement_ops = { - /* policy management services */ - .init_domain_ssid = ste_init_domain_ssid, - .free_domain_ssid = ste_free_domain_ssid, - .dump_binary_policy = ste_dump_policy, - .set_binary_policy = ste_set_policy, - .dump_statistics = ste_dump_stats, + + /* policy management services */ + .init_domain_ssid = ste_init_domain_ssid, + .free_domain_ssid = ste_free_domain_ssid, + .dump_binary_policy = ste_dump_policy, + .set_binary_policy = ste_set_policy, + .dump_statistics = ste_dump_stats, .dump_ssid_types = ste_dump_ssid_types, - /* domain management control hooks */ - .pre_domain_create = ste_pre_domain_create, - .post_domain_create = NULL, - .fail_domain_create = NULL, - .post_domain_destroy = ste_post_domain_destroy, - /* event channel control hooks */ - .pre_eventchannel_unbound = ste_pre_eventchannel_unbound, - .fail_eventchannel_unbound = NULL, - .pre_eventchannel_interdomain = ste_pre_eventchannel_interdomain, - .fail_eventchannel_interdomain = NULL, - /* grant table control hooks */ - .pre_grant_map_ref = ste_pre_grant_map_ref, - .fail_grant_map_ref = NULL, - .pre_grant_setup = ste_pre_grant_setup, - .fail_grant_setup = NULL, + + /* domain management control hooks */ + .pre_domain_create = ste_pre_domain_create, + .post_domain_create = NULL, + .fail_domain_create = NULL, + .post_domain_destroy = ste_post_domain_destroy, + + /* event channel control hooks */ + .pre_eventchannel_unbound = ste_pre_eventchannel_unbound, + .fail_eventchannel_unbound = NULL, + .pre_eventchannel_interdomain = ste_pre_eventchannel_interdomain, + .fail_eventchannel_interdomain = NULL, + + /* grant table control hooks */ + .pre_grant_map_ref = ste_pre_grant_map_ref, + .fail_grant_map_ref = NULL, + .pre_grant_setup = ste_pre_grant_setup, + .fail_grant_setup = NULL, + .sharing = ste_sharing, }; + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff -r 19af31a59537 -r f31494465fb0 xen/arch/x86/domain.c --- a/xen/arch/x86/domain.c Fri Oct 21 11:06:17 2005 +++ b/xen/arch/x86/domain.c Fri Oct 21 11:07:14 2005 @@ -254,6 +254,7 @@ void arch_do_createdomain(struct vcpu *v) { struct domain *d = v->domain; + l1_pgentry_t gdt_l1e; int vcpuid; if ( is_idle_task(d) ) @@ -282,12 +283,10 @@ * GDT, and the old VCPU# is invalid in the new domain, we would otherwise * try to load CS from an invalid table. */ + gdt_l1e = l1e_from_page(virt_to_page(gdt_table), PAGE_HYPERVISOR); for ( vcpuid = 0; vcpuid < MAX_VIRT_CPUS; vcpuid++ ) - { d->arch.mm_perdomain_pt[ - (vcpuid << PDPT_VCPU_SHIFT) + FIRST_RESERVED_GDT_PAGE] = - l1e_from_page(virt_to_page(gdt_table), PAGE_HYPERVISOR); - } + (vcpuid << PDPT_VCPU_SHIFT) + FIRST_RESERVED_GDT_PAGE] = gdt_l1e; v->arch.guest_vtable = __linear_l2_table; v->arch.shadow_vtable = __shadow_linear_l2_table; diff -r 19af31a59537 -r f31494465fb0 xen/arch/x86/setup.c --- a/xen/arch/x86/setup.c Fri Oct 21 11:06:17 2005 +++ b/xen/arch/x86/setup.c Fri Oct 21 11:07:14 2005 @@ -141,7 +141,7 @@ static void __init start_of_day(void) { int i; - unsigned long vgdt; + unsigned long vgdt, gdt_pfn; early_cpu_init(); @@ -164,10 +164,10 @@ * noted in arch_do_createdomain(), we must map for every possible VCPU#. */ vgdt = GDT_VIRT_START(current) + FIRST_RESERVED_GDT_BYTE; + gdt_pfn = virt_to_phys(gdt_table) >> PAGE_SHIFT; for ( i = 0; i < MAX_VIRT_CPUS; i++ ) { - map_pages_to_xen( - vgdt, virt_to_phys(gdt_table) >> PAGE_SHIFT, 1, PAGE_HYPERVISOR); + map_pages_to_xen(vgdt, gdt_pfn, 1, PAGE_HYPERVISOR); vgdt += 1 << PDPT_VCPU_VA_SHIFT; } diff -r 19af31a59537 -r f31494465fb0 xen/common/acm_ops.c --- a/xen/common/acm_ops.c Fri Oct 21 11:06:17 2005 +++ b/xen/common/acm_ops.c Fri Oct 21 11:07:14 2005 @@ -31,22 +31,23 @@ #if (ACM_USE_SECURITY_POLICY == ACM_NULL_POLICY) -long do_acm_op(acm_op_t * u_acm_op) +long do_acm_op(struct acm_op * u_acm_op) { return -ENOSYS; } #else -typedef enum acm_operation { +enum acm_operation { POLICY, /* access to policy interface (early drop) */ GETPOLICY, /* dump policy cache */ SETPOLICY, /* set policy cache (controls security) */ DUMPSTATS, /* dump policy statistics */ - GETSSID /* retrieve ssidref for domain id */ -} acm_operation_t; - -int acm_authorize_acm_ops(struct domain *d, acm_operation_t pops) + GETSSID, /* retrieve ssidref for domain id (decide inside authorized domains) */ + GETDECISION /* retrieve ACM decision from authorized domains */ +}; + +int acm_authorize_acm_ops(struct domain *d, enum acm_operation pops) { /* all policy management functions are restricted to privileged domains, * soon we will introduce finer-grained privileges for policy operations @@ -59,10 +60,10 @@ return ACM_ACCESS_PERMITTED; } -long do_acm_op(acm_op_t * u_acm_op) +long do_acm_op(struct acm_op * u_acm_op) { long ret = 0; - acm_op_t curop, *op = &curop; + struct acm_op curop, *op = &curop; /* check here policy decision for policy commands */ /* for now allow DOM0 only, later indepedently */ @@ -78,81 +79,148 @@ 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; + { + 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; + { + 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; + { + 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; case ACM_GETSSID: - { - ssidref_t ssidref; - - if (acm_authorize_acm_ops(current->domain, GETSSID)) - return -EACCES; - - if (op->u.getssid.get_ssid_by == SSIDREF) - ssidref = op->u.getssid.id.ssidref; - else if (op->u.getssid.get_ssid_by == DOMAINID) { - struct domain *subj = find_domain_by_id(op->u.getssid.id.domainid); - if (!subj) - return -ESRCH; /* domain not found */ - - ssidref = ((struct acm_ssid_domain *)(subj->ssid))->ssidref; - put_domain(subj); - } else - return -ESRCH; - - ret = acm_get_ssid(ssidref, - op->u.getssid.ssidbuf, - op->u.getssid.ssidbuf_size); - if (ret == ACM_OK) - ret = 0; - else - ret = -ESRCH; - } - break; + { + ssidref_t ssidref; + + if (acm_authorize_acm_ops(current->domain, GETSSID)) + return -EACCES; + printkd("%s: getting SSID.\n", __func__); + if (op->u.getssid.get_ssid_by == SSIDREF) + ssidref = op->u.getssid.id.ssidref; + else if (op->u.getssid.get_ssid_by == DOMAINID) { + struct domain *subj = find_domain_by_id(op->u.getssid.id.domainid); + if (!subj) + return -ESRCH; /* domain not found */ + + ssidref = ((struct acm_ssid_domain *)(subj->ssid))->ssidref; + put_domain(subj); + } else + return -ESRCH; + + ret = acm_get_ssid(ssidref, + op->u.getssid.ssidbuf, + op->u.getssid.ssidbuf_size); + if (ret == ACM_OK) + ret = 0; + else + ret = -ESRCH; + } + break; + + case ACM_GETDECISION: + { + ssidref_t ssidref1, ssidref2; + + if (acm_authorize_acm_ops(current->domain, GETDECISION)) { + ret = -EACCES; + goto out; + } + printkd("%s: getting access control decision.\n", __func__); + if (op->u.getdecision.get_decision_by1 == SSIDREF) { + ssidref1 = op->u.getdecision.id1.ssidref; + } + else if (op->u.getdecision.get_decision_by1 == DOMAINID) { + struct domain *subj = find_domain_by_id(op->u.getdecision.id1.domainid); + if (!subj) { + ret = -ESRCH; /* domain not found */ + goto out; + } + ssidref1 = ((struct acm_ssid_domain *)(subj->ssid))->ssidref; + put_domain(subj); + } else { + ret = -ESRCH; + goto out; + } + if (op->u.getdecision.get_decision_by2 == SSIDREF) { + ssidref2 = op->u.getdecision.id2.ssidref; + } + else if (op->u.getdecision.get_decision_by2 == DOMAINID) { + struct domain *subj = find_domain_by_id(op->u.getdecision.id2.domainid); + if (!subj) { + ret = -ESRCH; /* domain not found */ + goto out; + } + ssidref2 = ((struct acm_ssid_domain *)(subj->ssid))->ssidref; + put_domain(subj); + } else { + ret = -ESRCH; + goto out; + } + ret = acm_get_decision(ssidref1, ssidref2, op->u.getdecision.hook); + } + break; default: ret = -ESRCH; - - } + } + + out: + if (ret == ACM_ACCESS_PERMITTED) { + op->u.getdecision.acm_decision = ACM_ACCESS_PERMITTED; + ret = 0; + } else if (ret == ACM_ACCESS_DENIED) { + op->u.getdecision.acm_decision = ACM_ACCESS_DENIED; + ret = 0; + } else { + op->u.getdecision.acm_decision = ACM_ACCESS_DENIED; + if (ret > 0) + ret = -ret; + } + /* copy decision back to user space */ + copy_to_user(u_acm_op, op, sizeof(*op)); return ret; } #endif + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff -r 19af31a59537 -r f31494465fb0 xen/common/dom0_ops.c --- a/xen/common/dom0_ops.c Fri Oct 21 11:06:17 2005 +++ b/xen/common/dom0_ops.c Fri Oct 21 11:07:14 2005 @@ -199,7 +199,7 @@ /* * If we're on a HT system, we only use the first HT for dom0, other * domains will all share the second HT of each CPU. Since dom0 is on - * CPU 0, we favour high numbered CPUs in the event of a tie. + * CPU 0, we favour high numbered CPUs in the event of a tie. */ pro = smp_num_siblings - 1; for ( i = pro; i < num_online_cpus(); i += smp_num_siblings ) diff -r 19af31a59537 -r f31494465fb0 xen/common/sched_sedf.c --- a/xen/common/sched_sedf.c Fri Oct 21 11:06:17 2005 +++ b/xen/common/sched_sedf.c Fri Oct 21 11:07:14 2005 @@ -1150,7 +1150,7 @@ inf->block_tot++; #endif if (unlikely(now < PERIOD_BEGIN(inf))) { - PRINT(4,"extratime unblock\n"); + PRINT(4,"extratime unblock\n"); /* unblocking in extra-time! */ #if (EXTRA == EXTRA_BLOCK_WEIGHT) if (inf->status & EXTRA_WANT_PEN_Q) { @@ -1459,3 +1459,13 @@ .wake = sedf_wake, .adjdom = sedf_adjdom, }; + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff -r 19af31a59537 -r f31494465fb0 xen/include/acm/acm_core.h --- a/xen/include/acm/acm_core.h Fri Oct 21 11:06:17 2005 +++ b/xen/include/acm/acm_core.h Fri Oct 21 11:07:14 2005 @@ -15,6 +15,7 @@ * for the access control module and relevant policies * */ + #ifndef _ACM_CORE_H #define _ACM_CORE_H @@ -25,30 +26,30 @@ /* Xen-internal representation of the binary policy */ struct acm_binary_policy { - u16 primary_policy_code; - u16 secondary_policy_code; - void *primary_binary_policy; - void *secondary_binary_policy; - + u16 primary_policy_code; + u16 secondary_policy_code; + void *primary_binary_policy; + void *secondary_binary_policy; + }; struct chwall_binary_policy { - u16 max_types; - u16 max_ssidrefs; - u16 max_conflictsets; - domaintype_t *ssidrefs; /* [max_ssidrefs][max_types] */ - domaintype_t *conflict_aggregate_set; /* [max_types] */ - domaintype_t *running_types; /* [max_types] */ - domaintype_t *conflict_sets; /* [max_conflictsets][max_types]*/ + u32 max_types; + u32 max_ssidrefs; + u32 max_conflictsets; + domaintype_t *ssidrefs; /* [max_ssidrefs][max_types] */ + domaintype_t *conflict_aggregate_set; /* [max_types] */ + domaintype_t *running_types; /* [max_types] */ + domaintype_t *conflict_sets; /* [max_conflictsets][max_types]*/ }; struct ste_binary_policy { - u16 max_types; - u16 max_ssidrefs; - domaintype_t *ssidrefs; /* [max_ssidrefs][max_types] */ - atomic_t ec_eval_count, gt_eval_count; - atomic_t ec_denied_count, gt_denied_count; - atomic_t ec_cachehit_count, gt_cachehit_count; + u32 max_types; + u32 max_ssidrefs; + domaintype_t *ssidrefs; /* [max_ssidrefs][max_types] */ + atomic_t ec_eval_count, gt_eval_count; + atomic_t ec_denied_count, gt_denied_count; + atomic_t ec_cachehit_count, gt_cachehit_count; }; /* global acm policy */ @@ -63,7 +64,7 @@ /* defines number of access decisions to other domains can be cached * one entry per domain, TE does not distinguish evtchn or grant_table */ -#define ACM_TE_CACHE_SIZE 8 +#define ACM_TE_CACHE_SIZE 8 enum acm_ste_flag { VALID, FREE }; /* cache line: @@ -72,57 +73,67 @@ * on domain cache_line.id */ struct acm_ste_cache_line { - enum acm_ste_flag valid; - domid_t id; + enum acm_ste_flag valid; + domid_t id; }; /* general definition of a subject security id */ struct acm_ssid_domain { - enum acm_datatype datatype; /* type of subject (e.g., partition) */ - ssidref_t ssidref; /* combined security reference */ - void *primary_ssid; /* primary policy ssid part (e.g. chinese wall) */ - void *secondary_ssid; /* secondary policy ssid part (e.g. type enforcement) */ - struct domain *subject; /* backpointer to subject structure */ - domid_t domainid; /* replicate id */ + enum acm_datatype datatype; /* type of subject (e.g., partition) */ + ssidref_t ssidref; /* combined security reference */ + void *primary_ssid; /* primary policy ssid part (e.g. chinese wall) */ + void *secondary_ssid; /* secondary policy ssid part (e.g. type enforcement) */ + struct domain *subject; /* backpointer to subject structure */ + domid_t domainid; /* replicate id */ }; /* chinese wall ssid type */ struct chwall_ssid { - ssidref_t chwall_ssidref; + ssidref_t chwall_ssidref; }; /* simple type enforcement ssid type */ struct ste_ssid { - ssidref_t ste_ssidref; - struct acm_ste_cache_line ste_cache[ACM_TE_CACHE_SIZE]; /* decision cache */ + ssidref_t ste_ssidref; + struct acm_ste_cache_line ste_cache[ACM_TE_CACHE_SIZE]; /* decision cache */ }; /* macros to access ssidref for primary / secondary policy - * primary ssidref = lower 16 bit - * secondary ssidref = higher 16 bit + * primary ssidref = lower 16 bit + * secondary ssidref = higher 16 bit */ #define ACM_PRIMARY(ssidref) \ - ((ssidref) & 0xffff) + ((ssidref) & 0xffff) #define ACM_SECONDARY(ssidref) \ - ((ssidref) >> 16) + ((ssidref) >> 16) #define GET_SSIDREF(POLICY, ssidref) \ - ((POLICY) == acm_bin_pol.primary_policy_code) ? \ - ACM_PRIMARY(ssidref) : ACM_SECONDARY(ssidref) + ((POLICY) == acm_bin_pol.primary_policy_code) ? \ + ACM_PRIMARY(ssidref) : ACM_SECONDARY(ssidref) /* macros to access ssid pointer for primary / secondary policy */ #define GET_SSIDP(POLICY, ssid) \ - ((POLICY) == acm_bin_pol.primary_policy_code) ? \ - ((ssid)->primary_ssid) : ((ssid)->secondary_ssid) + ((POLICY) == acm_bin_pol.primary_policy_code) ? \ + ((ssid)->primary_ssid) : ((ssid)->secondary_ssid) /* 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, int isuserbuffer); -int acm_get_policy(void *buf, u16 buf_size); +void acm_free_domain_ssid(struct acm_ssid_domain *ssid); +int acm_set_policy(void *buf, u32 buf_size, int isuserbuffer); +int acm_get_policy(void *buf, u32 buf_size); int acm_dump_statistics(void *buf, u16 buf_size); int acm_get_ssid(ssidref_t ssidref, u8 *buf, u16 buf_size); +int acm_get_decision(ssidref_t ssidref1, ssidref_t ssidref2, enum acm_hook_type hook); #endif +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff -r 19af31a59537 -r f31494465fb0 xen/include/acm/acm_endian.h --- a/xen/include/acm/acm_endian.h Fri Oct 21 11:06:17 2005 +++ b/xen/include/acm/acm_endian.h Fri Oct 21 11:07:14 2005 @@ -18,6 +18,7 @@ * big-endian policy interface * */ + #ifndef _ACM_ENDIAN_H #define _ACM_ENDIAN_H @@ -30,10 +31,10 @@ { if (little_endian) return - ( (((x) >> 24) & 0xff )| - (((x) >> 8) & 0xff00 )| - (((x) << 8) & 0xff0000 )| - (((x) << 24) & 0xff000000) ); + ( (((x) >> 24) & 0xff )| + (((x) >> 8) & 0xff00 )| + (((x) << 8) & 0xff0000 )| + (((x) << 24) & 0xff000000) ); else return x; } @@ -42,10 +43,10 @@ { if (little_endian) return - ( (((x) >> 8) & 0xff )| - (((x) << 8) & 0xff00 ) ); + ( (((x) >> 8) & 0xff )| + (((x) << 8) & 0xff00 ) ); else - return x; + return x; } #define htonl(x) ntohl(x) @@ -55,8 +56,8 @@ { unsigned int i = 0; while (i < n) { - dest[i] = htons(src[i]); - i++; + dest[i] = htons(src[i]); + i++; } } @@ -64,8 +65,8 @@ { unsigned int i = 0; while (i < n) { - dest[i] = htonl(src[i]); - i++; + dest[i] = htonl(src[i]); + i++; } } @@ -86,3 +87,13 @@ } #endif + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff -r 19af31a59537 -r f31494465fb0 xen/include/acm/acm_hooks.h --- a/xen/include/acm/acm_hooks.h Fri Oct 21 11:06:17 2005 +++ b/xen/include/acm/acm_hooks.h Fri Oct 21 11:07:14 2005 @@ -15,6 +15,7 @@ * sHype hooks that are called throughout Xen. * */ + #ifndef _ACM_HOOKS_H #define _ACM_HOOKS_H @@ -89,8 +90,8 @@ /* policy management functions (must always be defined!) */ int (*init_domain_ssid) (void **ssid, ssidref_t ssidref); void (*free_domain_ssid) (void *ssid); - int (*dump_binary_policy) (u8 *buffer, u16 buf_size); - int (*set_binary_policy) (u8 *buffer, u16 buf_size); + int (*dump_binary_policy) (u8 *buffer, u32 buf_size); + int (*set_binary_policy) (u8 *buffer, u32 buf_size); int (*dump_statistics) (u8 *buffer, u16 buf_size); int (*dump_ssid_types) (ssidref_t ssidref, u8 *buffer, u16 buf_size); /* domain management control hooks (can be NULL) */ @@ -108,6 +109,8 @@ void (*fail_grant_map_ref) (domid_t id); int (*pre_grant_setup) (domid_t id); void (*fail_grant_setup) (domid_t id); + /* generic domain-requested decision hooks (can be NULL) */ + int (*sharing) (ssidref_t ssidref1, ssidref_t ssidref2); }; /* global variables */ @@ -144,6 +147,8 @@ { return 0; } static inline void acm_post_domain0_create(domid_t domid) { return; } +static inline int acm_sharing(ssidref_t ssidref1, ssidref_t ssidref2) +{ return 0; } #else @@ -281,7 +286,8 @@ break; case EVTCHNOP_bind_interdomain: ret = acm_pre_eventchannel_interdomain( - op->u.bind_interdomain.dom1, op->u.bind_interdomain.dom2); + current->domain->domain_id, + op->u.bind_interdomain.remote_dom); break; default: ret = 0; /* ok */ @@ -341,6 +347,18 @@ acm_post_domain_create(domid, ACM_DOM0_SSIDREF); } +static inline int acm_sharing(ssidref_t ssidref1, ssidref_t ssidref2) +{ + if ((acm_primary_ops->sharing != NULL) && + acm_primary_ops->sharing(ssidref1, ssidref2)) + return ACM_ACCESS_DENIED; + else if ((acm_secondary_ops->sharing != NULL) && + acm_secondary_ops->sharing(ssidref1, ssidref2)) { + return ACM_ACCESS_DENIED; + } else + return ACM_ACCESS_PERMITTED; +} + extern int acm_init(unsigned int *initrdidx, const multiboot_info_t *mbi, unsigned long start); @@ -348,3 +366,13 @@ #endif #endif + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff -r 19af31a59537 -r f31494465fb0 xen/include/public/acm.h --- a/xen/include/public/acm.h Fri Oct 21 11:06:17 2005 +++ b/xen/include/public/acm.h Fri Oct 21 11:07:14 2005 @@ -52,9 +52,9 @@ #define ACM_ERROR -4 /* External ACCESS DECISIONS */ -#define ACM_ACCESS_PERMITTED 0 -#define ACM_ACCESS_DENIED -111 -#define ACM_NULL_POINTER_ERROR -200 +#define ACM_ACCESS_PERMITTED 0 +#define ACM_ACCESS_DENIED -111 +#define ACM_NULL_POINTER_ERROR -200 /* primary policy in lower 4 bits */ #define ACM_NULL_POLICY 0 @@ -83,6 +83,9 @@ /* defines a ssid reference used by xen */ typedef uint32_t ssidref_t; + +/* hooks that are known to domains */ +enum acm_hook_type {NONE=0, SHARING}; /* -------security policy relevant type definitions-------- */ diff -r 19af31a59537 -r f31494465fb0 xen/include/public/acm_ops.h --- a/xen/include/public/acm_ops.h Fri Oct 21 11:06:17 2005 +++ b/xen/include/public/acm_ops.h Fri Oct 21 11:07:14 2005 @@ -27,36 +27,36 @@ * 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 0xAAAA0004 +#define ACM_INTERFACE_VERSION 0xAAAA0005 /************************************************************************/ #define ACM_SETPOLICY 4 -typedef struct acm_setpolicy { +struct acm_setpolicy { /* OUT variables */ void *pushcache; - uint16_t pushcache_size; -} acm_setpolicy_t; + uint32_t pushcache_size; +}; #define ACM_GETPOLICY 5 -typedef struct acm_getpolicy { +struct acm_getpolicy { /* OUT variables */ void *pullcache; - uint16_t pullcache_size; -} acm_getpolicy_t; + uint32_t pullcache_size; +}; #define ACM_DUMPSTATS 6 -typedef struct acm_dumpstats { +struct acm_dumpstats { void *pullcache; - uint16_t pullcache_size; -} acm_dumpstats_t; + uint32_t pullcache_size; +}; #define ACM_GETSSID 7 -enum get_type {UNSET, SSIDREF, DOMAINID}; -typedef struct acm_getssid { +enum get_type {UNSET=0, SSIDREF, DOMAINID}; +struct acm_getssid { enum get_type get_ssid_by; union { domaintype_t domainid; @@ -64,18 +64,35 @@ } id; void *ssidbuf; uint16_t ssidbuf_size; -} acm_getssid_t; +}; -typedef struct acm_op { +#define ACM_GETDECISION 8 +struct acm_getdecision { + enum get_type get_decision_by1; /* in */ + enum get_type get_decision_by2; + union { + domaintype_t domainid; + ssidref_t ssidref; + } id1; + union { + domaintype_t domainid; + ssidref_t ssidref; + } id2; + enum acm_hook_type hook; + int acm_decision; /* out */ +}; + +struct acm_op { uint32_t cmd; uint32_t interface_version; /* ACM_INTERFACE_VERSION */ union { - acm_setpolicy_t setpolicy; - acm_getpolicy_t getpolicy; - acm_dumpstats_t dumpstats; - acm_getssid_t getssid; + struct acm_setpolicy setpolicy; + struct acm_getpolicy getpolicy; + struct acm_dumpstats dumpstats; + struct acm_getssid getssid; + struct acm_getdecision getdecision; } u; -} acm_op_t; +}; #endif /* __XEN_PUBLIC_ACM_OPS_H__ */ diff -r 19af31a59537 -r f31494465fb0 patches/linux-2.6.12/2.6.12.6.patch --- /dev/null Fri Oct 21 11:06:17 2005 +++ b/patches/linux-2.6.12/2.6.12.6.patch Fri Oct 21 11:07:14 2005 @@ -0,0 +1,1738 @@ +diff --git a/Makefile b/Makefile +--- a/Makefile ++++ b/Makefile +@@ -1,7 +1,7 @@ + VERSION = 2 + PATCHLEVEL = 6 + SUBLEVEL = 12 +-EXTRAVERSION = ++EXTRAVERSION = .6 + NAME=Woozy Numbat + + # *DOCUMENTATION* +@@ -1149,7 +1149,7 @@ endif # KBUILD_EXTMOD + #(which is the most common case IMHO) to avoid unneeded clutter in the big tags file. + #Adding $(srctree) adds about 20M on i386 to the size of the output file! + +-ifeq ($(KBUILD_OUTPUT),) ++ifeq ($(src),$(obj)) + __srctree = + else + __srctree = $(srctree)/ +diff --git a/arch/i386/kernel/cpu/cpufreq/powernow-k8.c b/arch/i386/kernel/cpu/cpufreq/powernow-k8.c +--- a/arch/i386/kernel/cpu/cpufreq/powernow-k8.c ++++ b/arch/i386/kernel/cpu/cpufreq/powernow-k8.c +@@ -44,7 +44,7 @@ + + #define PFX "powernow-k8: " + #define BFX PFX "BIOS error: " +-#define VERSION "version 1.40.2" ++#define VERSION "version 1.40.4" + #include "powernow-k8.h" + + /* serialize freq changes */ +@@ -978,7 +978,7 @@ static int __init powernowk8_cpu_init(st + { + struct powernow_k8_data *data; + cpumask_t oldmask = CPU_MASK_ALL; +- int rc; ++ int rc, i; + + if (!check_supported_cpu(pol->cpu)) + return -ENODEV; +@@ -1064,7 +1064,9 @@ static int __init powernowk8_cpu_init(st + printk("cpu_init done, current fid 0x%x, vid 0x%x\n", + data->currfid, data->currvid); + +- powernow_data[pol->cpu] = data; ++ for_each_cpu_mask(i, cpu_core_map[pol->cpu]) { ++ powernow_data[i] = data; ++ } + + return 0; + +diff --git a/arch/i386/kernel/process.c b/arch/i386/kernel/process.c +--- a/arch/i386/kernel/process.c ++++ b/arch/i386/kernel/process.c +@@ -827,6 +827,8 @@ asmlinkage int sys_get_thread_area(struc + if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX) + return -EINVAL; + ++ memset(&info, 0, sizeof(info)); ++ + desc = current->thread.tls_array + idx - GDT_ENTRY_TLS_MIN; + + info.entry_number = idx; +diff --git a/arch/ia64/kernel/ptrace.c b/arch/ia64/kernel/ptrace.c +--- a/arch/ia64/kernel/ptrace.c ++++ b/arch/ia64/kernel/ptrace.c +@@ -945,6 +945,13 @@ access_uarea (struct task_struct *child, + *data = (pt->cr_ipsr & IPSR_MASK); + return 0; + ++ case PT_AR_RSC: ++ if (write_access) ++ pt->ar_rsc = *data | (3 << 2); /* force PL3 */ ++ else ++ *data = pt->ar_rsc; ++ return 0; ++ + case PT_AR_RNAT: + urbs_end = ia64_get_user_rbs_end(child, pt, NULL); + rnat_addr = (long) ia64_rse_rnat_addr((long *) +@@ -996,9 +1003,6 @@ access_uarea (struct task_struct *child, + case PT_AR_BSPSTORE: + ptr = pt_reg_addr(pt, ar_bspstore); + break; +- case PT_AR_RSC: +- ptr = pt_reg_addr(pt, ar_rsc); +- break; + case PT_AR_UNAT: + ptr = pt_reg_addr(pt, ar_unat); + break; +@@ -1234,7 +1238,7 @@ ptrace_getregs (struct task_struct *chil + static long + ptrace_setregs (struct task_struct *child, struct pt_all_user_regs __user *ppr) + { +- unsigned long psr, ec, lc, rnat, bsp, cfm, nat_bits, val = 0; ++ unsigned long psr, rsc, ec, lc, rnat, bsp, cfm, nat_bits, val = 0; + struct unw_frame_info info; + struct switch_stack *sw; + struct ia64_fpreg fpval; +@@ -1267,7 +1271,7 @@ ptrace_setregs (struct task_struct *chil + /* app regs */ + + retval |= __get_user(pt->ar_pfs, &ppr->ar[PT_AUR_PFS]); +- retval |= __get_user(pt->ar_rsc, &ppr->ar[PT_AUR_RSC]); ++ retval |= __get_user(rsc, &ppr->ar[PT_AUR_RSC]); + retval |= __get_user(pt->ar_bspstore, &ppr->ar[PT_AUR_BSPSTORE]); + retval |= __get_user(pt->ar_unat, &ppr->ar[PT_AUR_UNAT]); + retval |= __get_user(pt->ar_ccv, &ppr->ar[PT_AUR_CCV]); +@@ -1365,6 +1369,7 @@ ptrace_setregs (struct task_struct *chil + retval |= __get_user(nat_bits, &ppr->nat); + + retval |= access_uarea(child, PT_CR_IPSR, &psr, 1); ++ retval |= access_uarea(child, PT_AR_RSC, &rsc, 1); + retval |= access_uarea(child, PT_AR_EC, &ec, 1); + retval |= access_uarea(child, PT_AR_LC, &lc, 1); + retval |= access_uarea(child, PT_AR_RNAT, &rnat, 1); +diff --git a/arch/ia64/kernel/signal.c b/arch/ia64/kernel/signal.c +--- a/arch/ia64/kernel/signal.c ++++ b/arch/ia64/kernel/signal.c +@@ -94,7 +94,7 @@ sys_sigaltstack (const stack_t __user *u + static long + restore_sigcontext (struct sigcontext __user *sc, struct sigscratch *scr) + { +- unsigned long ip, flags, nat, um, cfm; ++ unsigned long ip, flags, nat, um, cfm, rsc; + long err; + + /* Always make any pending restarted system calls return -EINTR */ +@@ -106,7 +106,7 @@ restore_sigcontext (struct sigcontext __ + err |= __get_user(ip, &sc->sc_ip); /* instruction pointer */ + err |= __get_user(cfm, &sc->sc_cfm); + err |= __get_user(um, &sc->sc_um); /* user mask */ +- err |= __get_user(scr->pt.ar_rsc, &sc->sc_ar_rsc); ++ err |= __get_user(rsc, &sc->sc_ar_rsc); + err |= __get_user(scr->pt.ar_unat, &sc->sc_ar_unat); + err |= __get_user(scr->pt.ar_fpsr, &sc->sc_ar_fpsr); + err |= __get_user(scr->pt.ar_pfs, &sc->sc_ar_pfs); +@@ -119,6 +119,7 @@ restore_sigcontext (struct sigcontext __ + err |= __copy_from_user(&scr->pt.r15, &sc->sc_gr[15], 8); /* r15 */ + + scr->pt.cr_ifs = cfm | (1UL << 63); ++ scr->pt.ar_rsc = rsc | (3 << 2); /* force PL3 */ + + /* establish new instruction pointer: */ + scr->pt.cr_iip = ip & ~0x3UL; +diff --git a/arch/ppc/kernel/time.c b/arch/ppc/kernel/time.c +--- a/arch/ppc/kernel/time.c ++++ b/arch/ppc/kernel/time.c +@@ -89,6 +89,9 @@ unsigned long tb_to_ns_scale; + + extern unsigned long wall_jiffies; + ++/* used for timezone offset */ ++static long timezone_offset; ++ + DEFINE_SPINLOCK(rtc_lock); + + EXPORT_SYMBOL(rtc_lock); +@@ -170,7 +173,7 @@ void timer_interrupt(struct pt_regs * re + xtime.tv_sec - last_rtc_update >= 659 && + abs((xtime.tv_nsec / 1000) - (1000000-1000000/HZ)) < 500000/HZ && + jiffies - wall_jiffies == 1) { +- if (ppc_md.set_rtc_time(xtime.tv_sec+1 + time_offset) == 0) ++ if (ppc_md.set_rtc_time(xtime.tv_sec+1 + timezone_offset) == 0) + last_rtc_update = xtime.tv_sec+1; + else + /* Try again one minute later */ +@@ -286,7 +289,7 @@ void __init time_init(void) + unsigned old_stamp, stamp, elapsed; + + if (ppc_md.time_init != NULL) +- time_offset = ppc_md.time_init(); ++ timezone_offset = ppc_md.time_init(); + + if (__USE_RTC()) { + /* 601 processor: dec counts down by 128 every 128ns */ +@@ -331,10 +334,10 @@ void __init time_init(void) + set_dec(tb_ticks_per_jiffy); + + /* If platform provided a timezone (pmac), we correct the time */ +- if (time_offset) { +- sys_tz.tz_minuteswest = -time_offset / 60; ++ if (timezone_offset) { ++ sys_tz.tz_minuteswest = -timezone_offset / 60; + sys_tz.tz_dsttime = 0; +- xtime.tv_sec -= time_offset; ++ xtime.tv_sec -= timezone_offset; + } + set_normalized_timespec(&wall_to_monotonic, + -xtime.tv_sec, -xtime.tv_nsec); +diff --git a/arch/ppc64/boot/zlib.c b/arch/ppc64/boot/zlib.c +--- a/arch/ppc64/boot/zlib.c ++++ b/arch/ppc64/boot/zlib.c +@@ -1307,7 +1307,7 @@ local int huft_build( + { + *t = (inflate_huft *)Z_NULL; + *m = 0; +- return Z_OK; ++ return Z_DATA_ERROR; + } + + +@@ -1351,6 +1351,7 @@ local int huft_build( + if ((j = *p++) != 0) + v[x[j]++] = i; + } while (++i < n); ++ n = x[g]; /* set n to length of v */ + + + /* Generate the Huffman codes and for each, make the table entries */ +diff --git a/arch/um/kernel/process.c b/arch/um/kernel/process.c +--- a/arch/um/kernel/process.c ++++ b/arch/um/kernel/process.c +@@ -130,7 +130,7 @@ int start_fork_tramp(void *thread_arg, u + return(arg.pid); + } + +-static int ptrace_child(void) ++static int ptrace_child(void *arg) + { + int ret; + int pid = os_getpid(), ppid = getppid(); +@@ -159,16 +159,20 @@ static int ptrace_child(void) + _exit(ret); + } + +-static int start_ptraced_child(void) ++static int start_ptraced_child(void **stack_out) + { ++ void *stack; ++ unsigned long sp; + int pid, n, status; + +- pid = fork(); +- if(pid == 0) +- ptrace_child(); +- ++ stack = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC, ++ MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); ++ if(stack == MAP_FAILED) ++ panic("check_ptrace : mmap failed, errno = %d", errno); ++ sp = (unsigned long) stack + PAGE_SIZE - sizeof(void *); ++ pid = clone(ptrace_child, (void *) sp, SIGCHLD, NULL); + if(pid < 0) +- panic("check_ptrace : fork failed, errno = %d", errno); ++ panic("check_ptrace : clone failed, errno = %d", errno); + CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED)); + if(n < 0) + panic("check_ptrace : wait failed, errno = %d", errno); +@@ -176,6 +180,7 @@ static int start_ptraced_child(void) + panic("check_ptrace : expected SIGSTOP, got status = %d", + status); + ++ *stack_out = stack; + return(pid); + } + +@@ -183,12 +188,12 @@ static int start_ptraced_child(void) + * just avoid using sysemu, not panic, but only if SYSEMU features are broken. + * So only for SYSEMU features we test mustpanic, while normal host features + * must work anyway!*/ +-static int stop_ptraced_child(int pid, int exitcode, int mustexit) ++static int stop_ptraced_child(int pid, void *stack, int exitcode, int mustpanic) + { + int status, n, ret = 0; + + if(ptrace(PTRACE_CONT, pid, 0, 0) < 0) +- panic("stop_ptraced_child : ptrace failed, errno = %d", errno); ++ panic("check_ptrace : ptrace failed, errno = %d", errno); + CATCH_EINTR(n = waitpid(pid, &status, 0)); + if(!WIFEXITED(status) || (WEXITSTATUS(status) != exitcode)) { + int exit_with = WEXITSTATUS(status); +@@ -199,13 +204,15 @@ static int stop_ptraced_child(int pid, i + printk("check_ptrace : child exited with exitcode %d, while " + "expecting %d; status 0x%x", exit_with, + exitcode, status); +- if (mustexit) ++ if (mustpanic) + panic("\n"); + else + printk("\n"); + ret = -1; + } + ++ if(munmap(stack, PAGE_SIZE) < 0) ++ panic("check_ptrace : munmap failed, errno = %d", errno); + return ret; + } + +@@ -227,11 +234,12 @@ __uml_setup("nosysemu", nosysemu_cmd_par + + static void __init check_sysemu(void) + { ++ void *stack; + int pid, syscall, n, status, count=0; + + printk("Checking syscall emulation patch for ptrace..."); + sysemu_supported = 0; +- pid = start_ptraced_child(); ++ pid = start_ptraced_child(&stack); + + if(ptrace(PTRACE_SYSEMU, pid, 0, 0) < 0) + goto fail; +@@ -249,7 +257,7 @@ static void __init check_sysemu(void) + panic("check_sysemu : failed to modify system " + "call return, errno = %d", errno); + +- if (stop_ptraced_child(pid, 0, 0) < 0) ++ if (stop_ptraced_child(pid, stack, 0, 0) < 0) + goto fail_stopped; + + sysemu_supported = 1; +@@ -257,7 +265,7 @@ static void __init check_sysemu(void) + set_using_sysemu(!force_sysemu_disabled); + + printk("Checking advanced syscall emulation patch for ptrace..."); +- pid = start_ptraced_child(); ++ pid = start_ptraced_child(&stack); + while(1){ + count++; + if(ptrace(PTRACE_SYSEMU_SINGLESTEP, pid, 0, 0) < 0) +@@ -282,7 +290,7 @@ static void __init check_sysemu(void) + break; + } + } +- if (stop_ptraced_child(pid, 0, 0) < 0) ++ if (stop_ptraced_child(pid, stack, 0, 0) < 0) + goto fail_stopped; + + sysemu_supported = 2; +@@ -293,17 +301,18 @@ static void __init check_sysemu(void) + return; + + fail: +- stop_ptraced_child(pid, 1, 0); ++ stop_ptraced_child(pid, stack, 1, 0); + fail_stopped: + printk("missing\n"); + } + + void __init check_ptrace(void) + { ++ void *stack; + int pid, syscall, n, status; + + printk("Checking that ptrace can change system call numbers..."); +- pid = start_ptraced_child(); ++ pid = start_ptraced_child(&stack); + + if (ptrace(PTRACE_OLDSETOPTIONS, pid, 0, (void *)PTRACE_O_TRACESYSGOOD) < 0) + panic("check_ptrace: PTRACE_SETOPTIONS failed, errno = %d", errno); +@@ -330,7 +339,7 @@ void __init check_ptrace(void) + break; + } + } +- stop_ptraced_child(pid, 0, 1); ++ stop_ptraced_child(pid, stack, 0, 1); + printk("OK\n"); + check_sysemu(); + } +@@ -362,10 +371,11 @@ void forward_pending_sigio(int target) + static inline int check_skas3_ptrace_support(void) + { + struct ptrace_faultinfo fi; ++ void *stack; + int pid, n, ret = 1; + + printf("Checking for the skas3 patch in the host..."); +- pid = start_ptraced_child(); ++ pid = start_ptraced_child(&stack); + + n = ptrace(PTRACE_FAULTINFO, pid, 0, &fi); + if (n < 0) { +@@ -380,7 +390,7 @@ static inline int check_skas3_ptrace_sup + } + + init_registers(pid); +- stop_ptraced_child(pid, 1, 1); ++ stop_ptraced_child(pid, stack, 1, 1); + + return(ret); + } +diff --git a/arch/x86_64/ia32/syscall32.c b/arch/x86_64/ia32/syscall32.c +--- a/arch/x86_64/ia32/syscall32.c ++++ b/arch/x86_64/ia32/syscall32.c +@@ -57,6 +57,7 @@ int syscall32_setup_pages(struct linux_b + int npages = (VSYSCALL32_END - VSYSCALL32_BASE) >> PAGE_SHIFT; + struct vm_area_struct *vma; + struct mm_struct *mm = current->mm; ++ int ret; + + vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL); + if (!vma) +@@ -78,7 +79,11 @@ int syscall32_setup_pages(struct linux_b + vma->vm_mm = mm; + + down_write(&mm->mmap_sem); +- insert_vm_struct(mm, vma); ++ if ((ret = insert_vm_struct(mm, vma))) { ++ up_write(&mm->mmap_sem); ++ kmem_cache_free(vm_area_cachep, vma); ++ return ret; ++ } + mm->total_vm += npages; + up_write(&mm->mmap_sem); + return 0; +diff --git a/arch/x86_64/kernel/setup.c b/arch/x86_64/kernel/setup.c +--- a/arch/x86_64/kernel/setup.c ++++ b/arch/x86_64/kernel/setup.c +@@ -729,8 +729,6 @@ static void __init amd_detect_cmp(struct + int cpu = smp_processor_id(); + int node = 0; + unsigned bits; +- if (c->x86_num_cores == 1) +- return; + + bits = 0; + while ((1 << bits) < c->x86_num_cores) +diff --git a/arch/x86_64/kernel/smp.c b/arch/x86_64/kernel/smp.c +--- a/arch/x86_64/kernel/smp.c ++++ b/arch/x86_64/kernel/smp.c +@@ -284,6 +284,71 @@ struct call_data_struct { + static struct call_data_struct * call_data; + + /* ++ * this function sends a 'generic call function' IPI to one other CPU ++ * in the system. ++ */ ++static void __smp_call_function_single (int cpu, void (*func) (void *info), void *info, ++ int nonatomic, int wait) ++{ ++ struct call_data_struct data; ++ int cpus = 1; ++ ++ data.func = func; ++ data.info = info; ++ atomic_set(&data.started, 0); ++ data.wait = wait; ++ if (wait) ++ atomic_set(&data.finished, 0); ++ ++ call_data = &data; ++ wmb(); ++ /* Send a message to all other CPUs and wait for them to respond */ ++ send_IPI_mask(cpumask_of_cpu(cpu), CALL_FUNCTION_VECTOR); ++ ++ /* Wait for response */ ++ while (atomic_read(&data.started) != cpus) ++ cpu_relax(); ++ ++ if (!wait) ++ return; ++ ++ while (atomic_read(&data.finished) != cpus) ++ cpu_relax(); ++} ++ ++/* ++ * Run a function on another CPU ++ * <func> The function to run. This must be fast and non-blocking. ++ * <info> An arbitrary pointer to pass to the function. ++ * <nonatomic> Currently unused. ++ * <wait> If true, wait until function has completed on other CPUs. ++ * [RETURNS] 0 on success, else a negative status code. ++ * ++ * Does not return until the remote CPU is nearly ready to execute <func> ++ * or is or has executed. ++ */ ++ ++int smp_call_function_single (int cpu, void (*func) (void *info), void *info, ++ int nonatomic, int wait) ++{ ++ ++ int me = get_cpu(); /* prevent preemption and reschedule on another processor */ ++ ++ if (cpu == me) { ++ printk("%s: trying to call self\n", __func__); ++ put_cpu(); ++ return -EBUSY; ++ } ++ spin_lock_bh(&call_lock); ++ ++ __smp_call_function_single(cpu, func,info,nonatomic,wait); ++ ++ spin_unlock_bh(&call_lock); ++ put_cpu(); ++ return 0; ++} ++ ++/* + * this function sends a 'generic call function' IPI to all other CPUs + * in the system. + */ +diff --git a/arch/x86_64/kernel/smpboot.c b/arch/x86_64/kernel/smpboot.c +--- a/arch/x86_64/kernel/smpboot.c ++++ b/arch/x86_64/kernel/smpboot.c +@@ -202,9 +202,6 @@ static __cpuinit void sync_master(void * + { + unsigned long flags, i; + +- if (smp_processor_id() != boot_cpu_id) +- return; +- + go[MASTER] = 0; + + local_irq_save(flags); +@@ -253,7 +250,7 @@ get_delta(long *rt, long *master) + return tcenter - best_tm; + } + +-static __cpuinit void sync_tsc(void) ++static __cpuinit void sync_tsc(unsigned int master) + { + int i, done = 0; + long delta, adj, adjust_latency = 0; +@@ -267,9 +264,17 @@ static __cpuinit void sync_tsc(void) + } t[NUM_ROUNDS] __cpuinitdata; + #endif + ++ printk(KERN_INFO "CPU %d: Syncing TSC to CPU %u.\n", ++ smp_processor_id(), master); ++ + go[MASTER] = 1; + +- smp_call_function(sync_master, NULL, 1, 0); ++ /* It is dangerous to broadcast IPI as cpus are coming up, ++ * as they may not be ready to accept them. So since ++ * we only need to send the ipi to the boot cpu direct ++ * the message, and avoid the race. ++ */ ++ smp_call_function_single(master, sync_master, NULL, 1, 0); + + while (go[MASTER]) /* wait for master to be ready */ + no_cpu_relax(); +@@ -313,16 +318,14 @@ static __cpuinit void sync_tsc(void) + printk(KERN_INFO + "CPU %d: synchronized TSC with CPU %u (last diff %ld cycles, " + "maxerr %lu cycles)\n", +- smp_processor_id(), boot_cpu_id, delta, rt); ++ smp_processor_id(), master, delta, rt); + } + + static void __cpuinit tsc_sync_wait(void) + { + if (notscsync || !cpu_has_tsc) + return; +- printk(KERN_INFO "CPU %d: Syncing TSC to CPU %u.\n", smp_processor_id(), +- boot_cpu_id); +- sync_tsc(); ++ sync_tsc(0); + } + + static __init int notscsync_setup(char *s) +diff --git a/drivers/acpi/pci_irq.c b/drivers/acpi/pci_irq.c +--- a/drivers/acpi/pci_irq.c ++++ b/drivers/acpi/pci_irq.c +@@ -433,8 +433,9 @@ acpi_pci_irq_enable ( + printk(KERN_WARNING PREFIX "PCI Interrupt %s[%c]: no GSI", + pci_name(dev), ('A' + pin)); + /* Interrupt Line values above 0xF are forbidden */ +- if (dev->irq >= 0 && (dev->irq <= 0xF)) { ++ if (dev->irq > 0 && (dev->irq <= 0xF)) { + printk(" - using IRQ %d\n", dev->irq); ++ acpi_register_gsi(dev->irq, ACPI_LEVEL_SENSITIVE, ACPI_ACTIVE_LOW); + return_VALUE(0); + } + else { +diff --git a/drivers/char/rocket.c b/drivers/char/rocket.c +--- a/drivers/char/rocket.c ++++ b/drivers/char/rocket.c +@@ -277,7 +277,7 @@ static void rp_do_receive(struct r_port + ToRecv = space; + + if (ToRecv <= 0) +- return; ++ goto done; + + /* + * if status indicates there are errored characters in the +@@ -359,6 +359,7 @@ static void rp_do_receive(struct r_port + } + /* Push the data up to the tty layer */ + ld->receive_buf(tty, tty->flip.char_buf, tty->flip.flag_buf, count); ++done: + tty_ldisc_deref(ld); + } + +diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c +--- a/drivers/char/tpm/tpm.c ++++ b/drivers/char/tpm/tpm.c +@@ -32,12 +32,6 @@ + + #define TPM_BUFSIZE 2048 + +-/* PCI configuration addresses */ +-#define PCI_GEN_PMCON_1 0xA0 +-#define PCI_GEN1_DEC 0xE4 +-#define PCI_LPC_EN 0xE6 +-#define PCI_GEN2_DEC 0xEC +- + static LIST_HEAD(tpm_chip_list); + static DEFINE_SPINLOCK(driver_lock); + static int dev_mask[32]; +@@ -61,72 +55,6 @@ void tpm_time_expired(unsigned long ptr) + EXPORT_SYMBOL_GPL(tpm_time_expired); + + /* +- * Initialize the LPC bus and enable the TPM ports +- */ +-int tpm_lpc_bus_init(struct pci_dev *pci_dev, u16 base) +-{ +- u32 lpcenable, tmp; +- int is_lpcm = 0; +- +- switch (pci_dev->vendor) { +- case PCI_VENDOR_ID_INTEL: +- switch (pci_dev->device) { +- case PCI_DEVICE_ID_INTEL_82801CA_12: +- case PCI_DEVICE_ID_INTEL_82801DB_12: +- is_lpcm = 1; +- break; +- } +- /* init ICH (enable LPC) */ +- pci_read_config_dword(pci_dev, PCI_GEN1_DEC, &lpcenable); +- lpcenable |= 0x20000000; +- pci_write_config_dword(pci_dev, PCI_GEN1_DEC, lpcenable); +- +- if (is_lpcm) { +- pci_read_config_dword(pci_dev, PCI_GEN1_DEC, +- &lpcenable); +- if ((lpcenable & 0x20000000) == 0) { +- dev_err(&pci_dev->dev, +- "cannot enable LPC\n"); +- return -ENODEV; +- } +- } +- +- /* initialize TPM registers */ +- pci_read_config_dword(pci_dev, PCI_GEN2_DEC, &tmp); +- +- if (!is_lpcm) +- tmp = (tmp & 0xFFFF0000) | (base & 0xFFF0); +- else +- tmp = +- (tmp & 0xFFFF0000) | (base & 0xFFF0) | +- 0x00000001; +- +- pci_write_config_dword(pci_dev, PCI_GEN2_DEC, tmp); +- +- if (is_lpcm) { +- pci_read_config_dword(pci_dev, PCI_GEN_PMCON_1, +- &tmp); +- tmp |= 0x00000004; /* enable CLKRUN */ +- pci_write_config_dword(pci_dev, PCI_GEN_PMCON_1, +- tmp); +- } +- tpm_write_index(0x0D, 0x55); /* unlock 4F */ +- tpm_write_index(0x0A, 0x00); /* int disable */ +- tpm_write_index(0x08, base); /* base addr lo */ +- tpm_write_index(0x09, (base & 0xFF00) >> 8); /* base addr hi */ +- tpm_write_index(0x0D, 0xAA); /* lock 4F */ +- break; +- case PCI_VENDOR_ID_AMD: +- /* nothing yet */ +- break; +- } +- +- return 0; +-} +- +-EXPORT_SYMBOL_GPL(tpm_lpc_bus_init); +- +-/* + * Internal kernel interface to transmit TPM commands + */ + static ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf, +@@ -590,10 +518,6 @@ int tpm_pm_resume(struct pci_dev *pci_de + if (chip == NULL) + return -ENODEV; + +- spin_lock(&driver_lock); +- tpm_lpc_bus_init(pci_dev, chip->vendor->base); +- spin_unlock(&driver_lock); +- + return 0; + } + +diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h +--- a/drivers/char/tpm/tpm.h ++++ b/drivers/char/tpm/tpm.h +@@ -79,8 +79,6 @@ static inline void tpm_write_index(int i + } + + extern void tpm_time_expired(unsigned long); +-extern int tpm_lpc_bus_init(struct pci_dev *, u16); +- + extern int tpm_register_hardware(struct pci_dev *, + struct tpm_vendor_specific *); + extern int tpm_open(struct inode *, struct file *); +diff --git a/drivers/char/tpm/tpm_atmel.c b/drivers/char/tpm/tpm_atmel.c +--- a/drivers/char/tpm/tpm_atmel.c ++++ b/drivers/char/tpm/tpm_atmel.c +@@ -22,7 +22,10 @@ + #include "tpm.h" + + /* Atmel definitions */ +-#define TPM_ATML_BASE 0x400 ++enum tpm_atmel_addr { ++ TPM_ATMEL_BASE_ADDR_LO = 0x08, ++ TPM_ATMEL_BASE_ADDR_HI = 0x09 ++}; + + /* write status bits */ + #define ATML_STATUS_ABORT 0x01 +@@ -127,7 +130,6 @@ static struct tpm_vendor_specific tpm_at + .cancel = tpm_atml_cancel, + .req_complete_mask = ATML_STATUS_BUSY | ATML_STATUS_DATA_AVAIL, + .req_complete_val = ATML_STATUS_DATA_AVAIL, +- .base = TPM_ATML_BASE, + .miscdev = { .fops = &atmel_ops, }, + }; + +@@ -136,14 +138,16 @@ static int __devinit tpm_atml_init(struc + { + u8 version[4]; + int rc = 0; ++ int lo, hi; + + if (pci_enable_device(pci_dev)) + return -EIO; + +- if (tpm_lpc_bus_init(pci_dev, TPM_ATML_BASE)) { +- rc = -ENODEV; +- goto out_err; +- } ++ lo = tpm_read_index( TPM_ATMEL_BASE_ADDR_LO ); ++ hi = tpm_read_index( TPM_ATMEL_BASE_ADDR_HI ); ++ ++ tpm_atmel.base = (hi<<8)|lo; ++ dev_dbg( &pci_dev->dev, "Operating with base: 0x%x\n", tpm_atmel.base); + + /* verify that it is an Atmel part */ + if (tpm_read_index(4) != 'A' || tpm_read_index(5) != 'T' +diff --git a/drivers/char/tpm/tpm_nsc.c b/drivers/char/tpm/tpm_nsc.c +--- a/drivers/char/tpm/tpm_nsc.c ++++ b/drivers/char/tpm/tpm_nsc.c +@@ -24,6 +24,10 @@ + /* National definitions */ + #define TPM_NSC_BASE 0x360 + #define TPM_NSC_IRQ 0x07 ++#define TPM_NSC_BASE0_HI 0x60 ++#define TPM_NSC_BASE0_LO 0x61 ++#define TPM_NSC_BASE1_HI 0x62 ++#define TPM_NSC_BASE1_LO 0x63 + + #define NSC_LDN_INDEX 0x07 + #define NSC_SID_INDEX 0x20 +@@ -234,7 +238,6 @@ static struct tpm_vendor_specific tpm_ns + .cancel = tpm_nsc_cancel, + .req_complete_mask = NSC_STATUS_OBF, + .req_complete_val = NSC_STATUS_OBF, +- .base = TPM_NSC_BASE, + .miscdev = { .fops = &nsc_ops, }, + + }; +@@ -243,15 +246,16 @@ static int __devinit tpm_nsc_init(struct + const struct pci_device_id *pci_id) + { + int rc = 0; ++ int lo, hi; ++ ++ hi = tpm_read_index(TPM_NSC_BASE0_HI); ++ lo = tpm_read_index(TPM_NSC_BASE0_LO); ++ ++ tpm_nsc.base = (hi<<8) | lo; + + if (pci_enable_device(pci_dev)) + return -EIO; + +- if (tpm_lpc_bus_init(pci_dev, TPM_NSC_BASE)) { +- rc = -ENODEV; +- goto out_err; +- } +- + /* verify that it is a National part (SID) */ + if (tpm_read_index(NSC_SID_INDEX) != 0xEF) { + rc = -ENODEV; +diff --git a/drivers/char/tty_ioctl.c b/drivers/char/tty_ioctl.c +--- a/drivers/char/tty_ioctl.c ++++ b/drivers/char/tty_ioctl.c +@@ -476,11 +476,11 @@ int n_tty_ioctl(struct tty_struct * tty, + ld = tty_ldisc_ref(tty); + switch (arg) { + case TCIFLUSH: +- if (ld->flush_buffer) ++ if (ld && ld->flush_buffer) + ld->flush_buffer(tty); + break; + case TCIOFLUSH: +- if (ld->flush_buffer) ++ if (ld && ld->flush_buffer) + ld->flush_buffer(tty); + /* fall through */ + case TCOFLUSH: +diff --git a/drivers/media/video/cx88/cx88-video.c b/drivers/media/video/cx88/cx88-video.c +--- a/drivers/media/video/cx88/cx88-video.c ++++ b/drivers/media/video/cx88/cx88-video.c +@@ -261,7 +261,7 @@ static struct cx88_ctrl cx8800_ctls[] = + .default_value = 0, + .type = V4L2_CTRL_TYPE_INTEGER, + }, +- .off = 0, ++ .off = 128, + .reg = MO_HUE, + .mask = 0x00ff, + .shift = 0, +diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c +--- a/drivers/net/e1000/e1000_main.c ++++ b/drivers/net/e1000/e1000_main.c +@@ -2307,6 +2307,7 @@ e1000_xmit_frame(struct sk_buff *skb, st + tso = e1000_tso(adapter, skb); + if (tso < 0) { + dev_kfree_skb_any(skb); ++ spin_unlock_irqrestore(&adapter->tx_lock, flags); + return NETDEV_TX_OK; + } + +diff --git a/drivers/net/hamradio/Kconfig b/drivers/net/hamradio/Kconfig +--- a/drivers/net/hamradio/Kconfig ++++ b/drivers/net/hamradio/Kconfig +@@ -17,7 +17,7 @@ config MKISS + + config 6PACK + tristate "Serial port 6PACK driver" +- depends on AX25 && BROKEN_ON_SMP ++ depends on AX25 + ---help--- + 6pack is a transmission protocol for the data exchange between your + PC and your TNC (the Terminal Node Controller acts as a kind of +diff --git a/drivers/net/shaper.c b/drivers/net/shaper.c +--- a/drivers/net/shaper.c ++++ b/drivers/net/shaper.c +@@ -135,10 +135,8 @@ static int shaper_start_xmit(struct sk_b + { + struct shaper *shaper = dev->priv; + struct sk_buff *ptr; +- +- if (down_trylock(&shaper->sem)) +- return -1; + ++ spin_lock(&shaper->lock); + ptr=shaper->sendq.prev; + + /* +@@ -232,7 +230,7 @@ static int shaper_start_xmit(struct sk_b + shaper->stats.collisions++; + } + shaper_kick(shaper); +- up(&shaper->sem); ++ spin_unlock(&shaper->lock); + return 0; + } + +@@ -271,11 +269,9 @@ static void shaper_timer(unsigned long d + { + struct shaper *shaper = (struct shaper *)data; + +- if (!down_trylock(&shaper->sem)) { +- shaper_kick(shaper); +- up(&shaper->sem); +- } else +- mod_timer(&shaper->timer, jiffies); ++ spin_lock(&shaper->lock); ++ shaper_kick(shaper); ++ spin_unlock(&shaper->lock); + } + + /* +@@ -332,21 +328,6 @@ static void shaper_kick(struct shaper *s + + + /* +- * Flush the shaper queues on a closedown +- */ +- +-static void shaper_flush(struct shaper *shaper) +-{ +- struct sk_buff *skb; +- +- down(&shaper->sem); +- while((skb=skb_dequeue(&shaper->sendq))!=NULL) +- dev_kfree_skb(skb); +- shaper_kick(shaper); +- up(&shaper->sem); +-} +- +-/* + * Bring the interface up. We just disallow this until a + * bind. + */ +@@ -375,7 +356,15 @@ static int shaper_open(struct net_device + static int shaper_close(struct net_device *dev) + { + struct shaper *shaper=dev->priv; +- shaper_flush(shaper); ++ struct sk_buff *skb; ++ ++ while ((skb = skb_dequeue(&shaper->sendq)) != NULL) ++ dev_kfree_skb(skb); ++ ++ spin_lock_bh(&shaper->lock); ++ shaper_kick(shaper); ++ spin_unlock_bh(&shaper->lock); ++ + del_timer_sync(&shaper->timer); + return 0; + } +@@ -576,6 +565,7 @@ static void shaper_init_priv(struct net_ + init_timer(&sh->timer); + sh->timer.function=shaper_timer; + sh->timer.data=(unsigned long)sh; ++ spin_lock_init(&sh->lock); + } + + /* +diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c +--- a/drivers/pci/pci-driver.c ++++ b/drivers/pci/pci-driver.c +@@ -396,7 +396,7 @@ int pci_register_driver(struct pci_drive + /* FIXME, once all of the existing PCI drivers have been fixed to set + * the pci shutdown function, this test can go away. */ + if (!drv->driver.shutdown) +- drv->driver.shutdown = pci_device_shutdown, ++ drv->driver.shutdown = pci_device_shutdown; + drv->driver.owner = drv->owner; + drv->driver.kobj.ktype = &pci_driver_kobj_type; + pci_init_dynids(&drv->dynids); +diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c +--- a/drivers/scsi/qla2xxx/qla_init.c ++++ b/drivers/scsi/qla2xxx/qla_init.c +@@ -1914,9 +1914,11 @@ qla2x00_reg_remote_port(scsi_qla_host_t + rport_ids.roles |= FC_RPORT_ROLE_FCP_TARGET; + + fcport->rport = rport = fc_remote_port_add(ha->host, 0, &rport_ids); +- if (!rport) ++ if (!rport) { + qla_printk(KERN_WARNING, ha, + "Unable to allocate fc remote port!\n"); ++ return; ++ } + + if (rport->scsi_target_id != -1 && rport->scsi_target_id < MAX_TARGETS) + fcport->os_target_id = rport->scsi_target_id; +diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c +--- a/drivers/scsi/qla2xxx/qla_os.c ++++ b/drivers/scsi/qla2xxx/qla_os.c +@@ -1150,7 +1150,7 @@ iospace_error_exit: + */ + int qla2x00_probe_one(struct pci_dev *pdev, struct qla_board_info *brd_info) + { +- int ret; ++ int ret = -ENODEV; + device_reg_t __iomem *reg; + struct Scsi_Host *host; + scsi_qla_host_t *ha; +@@ -1161,7 +1161,7 @@ int qla2x00_probe_one(struct pci_dev *pd + fc_port_t *fcport; + + if (pci_enable_device(pdev)) +- return -1; ++ goto probe_out; + + host = scsi_host_alloc(&qla2x00_driver_template, + sizeof(scsi_qla_host_t)); +@@ -1183,9 +1183,8 @@ int qla2x00_probe_one(struct pci_dev *pd + + /* Configure PCI I/O space */ + ret = qla2x00_iospace_config(ha); +- if (ret != 0) { +- goto probe_alloc_failed; +- } ++ if (ret) ++ goto probe_failed; + + /* Sanitize the information from PCI BIOS. */ + host->irq = pdev->irq; +@@ -1258,23 +1257,10 @@ int qla2x00_probe_one(struct pci_dev *pd + qla_printk(KERN_WARNING, ha, + "[ERROR] Failed to allocate memory for adapter\n"); + +- goto probe_alloc_failed; ++ ret = -ENOMEM; ++ goto probe_failed; + } + +- pci_set_drvdata(pdev, ha); +- host->this_id = 255; +- host->cmd_per_lun = 3; +- host->unique_id = ha->instance; +- host->max_cmd_len = MAX_CMDSZ; +- host->max_channel = ha->ports - 1; +- host->max_id = ha->max_targets; +- host->max_lun = ha->max_luns; +- host->transportt = qla2xxx_transport_template; +- if (scsi_add_host(host, &pdev->dev)) +- goto probe_alloc_failed; +- +- qla2x00_alloc_sysfs_attr(ha); +- + if (qla2x00_initialize_adapter(ha) && + !(ha->device_flags & DFLG_NO_CABLE)) { + +@@ -1285,11 +1271,10 @@ int qla2x00_probe_one(struct pci_dev *pd + "Adapter flags %x.\n", + ha->host_no, ha->device_flags)); + ++ ret = -ENODEV; + goto probe_failed; + } + +- qla2x00_init_host_attr(ha); +- + /* + * Startup the kernel thread for this host adapter + */ +@@ -1299,17 +1284,26 @@ int qla2x00_probe_one(struct pci_dev *pd + qla_printk(KERN_WARNING, ha, + "Unable to start DPC thread!\n"); + ++ ret = -ENODEV; + goto probe_failed; + } + wait_for_completion(&ha->dpc_inited); + ++ host->this_id = 255; ++ host->cmd_per_lun = 3; ++ host->unique_id = ha->instance; ++ host->max_cmd_len = MAX_CMDSZ; ++ host->max_channel = ha->ports - 1; ++ host->max_lun = MAX_LUNS; ++ host->transportt = qla2xxx_transport_template; ++ + if (IS_QLA2100(ha) || IS_QLA2200(ha)) + ret = request_irq(host->irq, qla2100_intr_handler, + SA_INTERRUPT|SA_SHIRQ, ha->brd_info->drv_name, ha); + else + ret = request_irq(host->irq, qla2300_intr_handler, + SA_INTERRUPT|SA_SHIRQ, ha->brd_info->drv_name, ha); +- if (ret != 0) { ++ if (ret) { + qla_printk(KERN_WARNING, ha, + "Failed to reserve interrupt %d already in use.\n", + host->irq); +@@ -1363,9 +1357,18 @@ int qla2x00_probe_one(struct pci_dev *pd + msleep(10); + } + ++ pci_set_drvdata(pdev, ha); + ha->flags.init_done = 1; + num_hosts++; + ++ ret = scsi_add_host(host, &pdev->dev); ++ if (ret) ++ goto probe_failed; ++ ++ qla2x00_alloc_sysfs_attr(ha); ++ ++ qla2x00_init_host_attr(ha); ++ + qla_printk(KERN_INFO, ha, "\n" + " QLogic Fibre Channel HBA Driver: %s\n" + " QLogic %s - %s\n" +@@ -1384,9 +1387,6 @@ int qla2x00_probe_one(struct pci_dev *pd + probe_failed: + fc_remove_host(ha->host); + +- scsi_remove_host(host); +- +-probe_alloc_failed: + qla2x00_free_device(ha); + + scsi_host_put(host); +@@ -1394,7 +1394,8 @@ probe_alloc_failed: + probe_disable_device: + pci_disable_device(pdev); + +- return -1; ++probe_out: ++ return ret; + } + EXPORT_SYMBOL_GPL(qla2x00_probe_one); + +diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c +--- a/drivers/scsi/sg.c ++++ b/drivers/scsi/sg.c +@@ -2969,23 +2969,22 @@ static void * dev_seq_start(struct seq_f + { + struct sg_proc_deviter * it = kmalloc(sizeof(*it), GFP_KERNEL); + ++ s->private = it; + if (! it) + return NULL; ++ + if (NULL == sg_dev_arr) +- goto err1; ++ return NULL; + it->index = *pos; + it->max = sg_last_dev(); + if (it->index >= it->max) +- goto err1; ++ return NULL; + return it; +-err1: +- kfree(it); +- return NULL; + } + + static void * dev_seq_next(struct seq_file *s, void *v, loff_t *pos) + { +- struct sg_proc_deviter * it = (struct sg_proc_deviter *) v; ++ struct sg_proc_deviter * it = s->private; + + *pos = ++it->index; + return (it->index < it->max) ? it : NULL; +@@ -2993,7 +2992,9 @@ static void * dev_seq_next(struct seq_fi + + static void dev_seq_stop(struct seq_file *s, void *v) + { +- kfree (v); ++ struct sg_proc_deviter * it = s->private; ++ ++ kfree (it); + } + + static int sg_proc_open_dev(struct inode *inode, struct file *file) +diff --git a/drivers/usb/net/usbnet.c b/drivers/usb/net/usbnet.c +--- a/drivers/usb/net/usbnet.c ++++ b/drivers/usb/net/usbnet.c +@@ -1922,7 +1922,7 @@ static int genelink_rx_fixup (struct usb + + // copy the packet data to the new skb + memcpy(skb_put(gl_skb, size), packet->packet_data, size); +- skb_return (dev, skb); ++ skb_return (dev, gl_skb); + } + + // advance to the next packet +diff --git a/fs/bio.c b/fs/bio.c +--- a/fs/bio.c ++++ b/fs/bio.c +@@ -261,6 +261,7 @@ inline void __bio_clone(struct bio *bio, + */ + bio->bi_vcnt = bio_src->bi_vcnt; + bio->bi_size = bio_src->bi_size; ++ bio->bi_idx = bio_src->bi_idx; + bio_phys_segments(q, bio); + bio_hw_segments(q, bio); + } +diff --git a/fs/char_dev.c b/fs/char_dev.c +--- a/fs/char_dev.c ++++ b/fs/char_dev.c +@@ -139,7 +139,7 @@ __unregister_chrdev_region(unsigned majo + struct char_device_struct *cd = NULL, **cp; + int i = major_to_index(major); + +- up(&chrdevs_lock); ++ down(&chrdevs_lock); + for (cp = &chrdevs[i]; *cp; cp = &(*cp)->next) + if ((*cp)->major == major && + (*cp)->baseminor == baseminor && +diff --git a/fs/exec.c b/fs/exec.c +--- a/fs/exec.c ++++ b/fs/exec.c +@@ -649,6 +649,7 @@ static inline int de_thread(struct task_ + } + sig->group_exit_task = NULL; + sig->notify_count = 0; ++ sig->real_timer.data = (unsigned long)current; + spin_unlock_irq(lock); + + /* +diff --git a/fs/isofs/compress.c b/fs/isofs/compress.c +--- a/fs/isofs/compress.c ++++ b/fs/isofs/compress.c +@@ -129,8 +129,14 @@ static int zisofs_readpage(struct file * + cend = le32_to_cpu(*(__le32 *)(bh->b_data + (blockendptr & bufmask))); + brelse(bh); + ++ if (cstart > cend) ++ goto eio; ++ + csize = cend-cstart; + ++ if (csize > deflateBound(1UL << zisofs_block_shift)) ++ goto eio; ++ + /* Now page[] contains an array of pages, any of which can be NULL, + and the locks on which we hold. We should now read the data and + release the pages. If the pages are NULL the decompressed data +diff --git a/include/asm-i386/string.h b/include/asm-i386/string.h +--- a/include/asm-i386/string.h ++++ b/include/asm-i386/string.h +@@ -116,7 +116,8 @@ __asm__ __volatile__( + "orb $1,%%al\n" + "3:" + :"=a" (__res), "=&S" (d0), "=&D" (d1) +- :"1" (cs),"2" (ct)); ++ :"1" (cs),"2" (ct) ++ :"memory"); + return __res; + } + +@@ -138,8 +139,9 @@ __asm__ __volatile__( + "3:\tsbbl %%eax,%%eax\n\t" + "orb $1,%%al\n" + "4:" +- :"=a" (__res), "=&S" (d0), "=&D" (d1), "=&c" (d2) +- :"1" (cs),"2" (ct),"3" (count)); ++ :"=a" (__res), "=&S" (d0), "=&D" (d1), "=&c" (d2) ++ :"1" (cs),"2" (ct),"3" (count) ++ :"memory"); + return __res; + } + +@@ -158,7 +160,9 @@ __asm__ __volatile__( + "movl $1,%1\n" + "2:\tmovl %1,%0\n\t" + "decl %0" +- :"=a" (__res), "=&S" (d0) : "1" (s),"0" (c)); ++ :"=a" (__res), "=&S" (d0) ++ :"1" (s),"0" (c) ++ :"memory"); + return __res; + } + +@@ -175,7 +179,9 @@ __asm__ __volatile__( + "leal -1(%%esi),%0\n" + "2:\ttestb %%al,%%al\n\t" + "jne 1b" +- :"=g" (__res), "=&S" (d0), "=&a" (d1) :"0" (0),"1" (s),"2" (c)); ++ :"=g" (__res), "=&S" (d0), "=&a" (d1) ++ :"0" (0),"1" (s),"2" (c) ++ :"memory"); + return __res; + } + +@@ -189,7 +195,9 @@ __asm__ __volatile__( + "scasb\n\t" + "notl %0\n\t" + "decl %0" +- :"=c" (__res), "=&D" (d0) :"1" (s),"a" (0), "0" (0xffffffffu)); ++ :"=c" (__res), "=&D" (d0) ++ :"1" (s),"a" (0), "0" (0xffffffffu) ++ :"memory"); + return __res; + } + +@@ -333,7 +341,9 @@ __asm__ __volatile__( + "je 1f\n\t" + "movl $1,%0\n" + "1:\tdecl %0" +- :"=D" (__res), "=&c" (d0) : "a" (c),"0" (cs),"1" (count)); ++ :"=D" (__res), "=&c" (d0) ++ :"a" (c),"0" (cs),"1" (count) ++ :"memory"); + return __res; + } + +@@ -369,7 +379,7 @@ __asm__ __volatile__( + "je 2f\n\t" + "stosb\n" + "2:" +- : "=&c" (d0), "=&D" (d1) ++ :"=&c" (d0), "=&D" (d1) + :"a" (c), "q" (count), "0" (count/4), "1" ((long) s) + :"memory"); + return (s); +@@ -392,7 +402,8 @@ __asm__ __volatile__( + "jne 1b\n" + "3:\tsubl %2,%0" + :"=a" (__res), "=&d" (d0) +- :"c" (s),"1" (count)); ++ :"c" (s),"1" (count) ++ :"memory"); + return __res; + } + /* end of additional stuff */ +@@ -473,7 +484,8 @@ static inline void * memscan(void * addr + "dec %%edi\n" + "1:" + : "=D" (addr), "=c" (size) +- : "0" (addr), "1" (size), "a" (c)); ++ : "0" (addr), "1" (size), "a" (c) ++ : "memory"); + return addr; + } + +diff --git a/include/asm-x86_64/smp.h b/include/asm-x86_64/smp.h +--- a/include/asm-x86_64/smp.h ++++ b/include/asm-x86_64/smp.h +@@ -46,6 +46,8 @@ extern int pic_mode; + extern int smp_num_siblings; + extern void smp_flush_tlb(void); + extern void smp_message_irq(int cpl, void *dev_id, struct pt_regs *regs); ++extern int smp_call_function_single (int cpuid, void (*func) (void *info), void *info, ++ int retry, int wait); + extern void smp_send_reschedule(int cpu); + extern void smp_invalidate_rcv(void); /* Process an NMI */ + extern void zap_low_mappings(void); +diff --git a/include/linux/if_shaper.h b/include/linux/if_shaper.h +--- a/include/linux/if_shaper.h ++++ b/include/linux/if_shaper.h +@@ -23,7 +23,7 @@ struct shaper + __u32 shapeclock; + unsigned long recovery; /* Time we can next clock a packet out on + an empty queue */ +- struct semaphore sem; ++ spinlock_t lock; + struct net_device_stats stats; + struct net_device *dev; + int (*hard_start_xmit) (struct sk_buff *skb, +diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h +--- a/include/linux/skbuff.h ++++ b/include/linux/skbuff.h +@@ -1192,7 +1192,7 @@ static inline void *skb_header_pointer(c + { + int hlen = skb_headlen(skb); + +- if (offset + len <= hlen) ++ if (hlen - offset >= len) + return skb->data + offset; + + if (skb_copy_bits(skb, offset, buffer, len) < 0) +diff --git a/include/linux/zlib.h b/include/linux/zlib.h +--- a/include/linux/zlib.h ++++ b/include/linux/zlib.h +@@ -506,6 +506,11 @@ extern int zlib_deflateReset (z_streamp + stream state was inconsistent (such as zalloc or state being NULL). + */ + ++static inline unsigned long deflateBound(unsigned long s) ++{ ++ return s + ((s + 7) >> 3) + ((s + 63) >> 6) + 11; ++} ++ + extern int zlib_deflateParams (z_streamp strm, int level, int strategy); + /* + Dynamically update the compression level and compression strategy. The +diff --git a/kernel/module.c b/kernel/module.c +--- a/kernel/module.c ++++ b/kernel/module.c +@@ -249,13 +249,18 @@ static inline unsigned int block_size(in + /* Created by linker magic */ + extern char __per_cpu_start[], __per_cpu_end[]; + +-static void *percpu_modalloc(unsigned long size, unsigned long align) ++static void *percpu_modalloc(unsigned long size, unsigned long align, ++ const char *name) + { + unsigned long extra; + unsigned int i; + void *ptr; + +- BUG_ON(align > SMP_CACHE_BYTES); ++ if (align > SMP_CACHE_BYTES) { ++ printk(KERN_WARNING "%s: per-cpu alignment %li > %i\n", ++ name, align, SMP_CACHE_BYTES); ++ align = SMP_CACHE_BYTES; ++ } + + ptr = __per_cpu_start; + for (i = 0; i < pcpu_num_used; ptr += block_size(pcpu_size[i]), i++) { +@@ -347,7 +352,8 @@ static int percpu_modinit(void) + } + __initcall(percpu_modinit); + #else /* ... !CONFIG_SMP */ +-static inline void *percpu_modalloc(unsigned long size, unsigned long align) ++static inline void *percpu_modalloc(unsigned long size, unsigned long align, ++ const char *name) + { + return NULL; + } +@@ -1554,7 +1560,8 @@ static struct module *load_module(void _ + if (pcpuindex) { + /* We have a special allocation for this section. */ + percpu = percpu_modalloc(sechdrs[pcpuindex].sh_size, +- sechdrs[pcpuindex].sh_addralign); ++ sechdrs[pcpuindex].sh_addralign, ++ mod->name); + if (!percpu) { + err = -ENOMEM; + goto free_mod; +diff --git a/kernel/signal.c b/kernel/signal.c +--- a/kernel/signal.c ++++ b/kernel/signal.c +@@ -686,7 +686,7 @@ static void handle_stop_signal(int sig, + { + struct task_struct *t; + +- if (p->flags & SIGNAL_GROUP_EXIT) ++ if (p->signal->flags & SIGNAL_GROUP_EXIT) + /* + * The process is in the middle of dying already. + */ +diff --git a/lib/inflate.c b/lib/inflate.c +--- a/lib/inflate.c ++++ b/lib/inflate.c +@@ -326,7 +326,7 @@ DEBG("huft1 "); + { + *t = (struct huft *)NULL; + *m = 0; +- return 0; ++ return 2; + } + + DEBG("huft2 "); +@@ -374,6 +374,7 @@ DEBG("huft5 "); + if ((j = *p++) != 0) + v[x[j]++] = i; + } while (++i < n); ++ n = x[g]; /* set n to length of v */ + + DEBG("h6 "); + +@@ -410,12 +411,13 @@ DEBG1("1 "); + DEBG1("2 "); + f -= a + 1; /* deduct codes from patterns left */ + xp = c + k; +- while (++j < z) /* try smaller tables up to z bits */ +- { +- if ((f <<= 1) <= *++xp) +- break; /* enough codes to use up j bits */ +- f -= *xp; /* else deduct codes from patterns */ +- } ++ if (j < z) ++ while (++j < z) /* try smaller tables up to z bits */ ++ { ++ if ((f <<= 1) <= *++xp) ++ break; /* enough codes to use up j bits */ ++ f -= *xp; /* else deduct codes from patterns */ ++ } + } + DEBG1("3 "); + z = 1 << j; /* table entries for j-bit table */ +diff --git a/mm/memory.c b/mm/memory.c +--- a/mm/memory.c ++++ b/mm/memory.c +@@ -1164,7 +1164,7 @@ int remap_pfn_range(struct vm_area_struc + { + pgd_t *pgd; + unsigned long next; +- unsigned long end = addr + size; ++ unsigned long end = addr + PAGE_ALIGN(size); + struct mm_struct *mm = vma->vm_mm; + int err; + +diff --git a/mm/mempolicy.c b/mm/mempolicy.c +--- a/mm/mempolicy.c ++++ b/mm/mempolicy.c +@@ -409,7 +409,7 @@ asmlinkage long sys_set_mempolicy(int mo + struct mempolicy *new; + DECLARE_BITMAP(nodes, MAX_NUMNODES); + +- if (mode > MPOL_MAX) ++ if (mode < 0 || mode > MPOL_MAX) + return -EINVAL; + err = get_nodes(nodes, nmask, maxnode, mode); + if (err) +diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c +--- a/net/8021q/vlan.c ++++ b/net/8021q/vlan.c +@@ -578,6 +578,14 @@ static int vlan_device_event(struct noti + if (!vlandev) + continue; + ++ if (netif_carrier_ok(dev)) { ++ if (!netif_carrier_ok(vlandev)) ++ netif_carrier_on(vlandev); ++ } else { ++ if (netif_carrier_ok(vlandev)) ++ netif_carrier_off(vlandev); ++ } ++ + if ((vlandev->state & VLAN_LINK_STATE_MASK) != flgs) { + vlandev->state = (vlandev->state &~ VLAN_LINK_STATE_MASK) + | flgs; +diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c +--- a/net/ipv4/icmp.c ++++ b/net/ipv4/icmp.c +@@ -349,12 +349,12 @@ static void icmp_push_reply(struct icmp_ + { + struct sk_buff *skb; + +- ip_append_data(icmp_socket->sk, icmp_glue_bits, icmp_param, +- icmp_param->data_len+icmp_param->head_len, +- icmp_param->head_len, +- ipc, rt, MSG_DONTWAIT); +- +- if ((skb = skb_peek(&icmp_socket->sk->sk_write_queue)) != NULL) { ++ if (ip_append_data(icmp_socket->sk, icmp_glue_bits, icmp_param, ++ icmp_param->data_len+icmp_param->head_len, ++ icmp_param->head_len, ++ ipc, rt, MSG_DONTWAIT) < 0) ++ ip_flush_pending_frames(icmp_socket->sk); ++ else if ((skb = skb_peek(&icmp_socket->sk->sk_write_queue)) != NULL) { + struct icmphdr *icmph = skb->h.icmph; + unsigned int csum = 0; + struct sk_buff *skb1; +diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c +--- a/net/ipv4/ip_output.c ++++ b/net/ipv4/ip_output.c +@@ -111,7 +111,6 @@ static int ip_dev_loopback_xmit(struct s + #ifdef CONFIG_NETFILTER_DEBUG + nf_debug_ip_loopback_xmit(newskb); + #endif +- nf_reset(newskb); + netif_rx(newskb); + return 0; + } +@@ -196,8 +195,6 @@ static inline int ip_finish_output2(stru + nf_debug_ip_finish_output2(skb); + #endif /*CONFIG_NETFILTER_DEBUG*/ + +- nf_reset(skb); +- + if (hh) { + int hh_alen; + +diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c +--- a/net/ipv4/ip_sockglue.c ++++ b/net/ipv4/ip_sockglue.c +@@ -848,6 +848,9 @@ mc_msf_out: + + case IP_IPSEC_POLICY: + case IP_XFRM_POLICY: ++ err = -EPERM; ++ if (!capable(CAP_NET_ADMIN)) ++ break; + err = xfrm_user_policy(sk, optname, optval, optlen); + break; + +diff --git a/net/ipv4/netfilter/ip_conntrack_core.c b/net/ipv4/netfilter/ip_conntrack_core.c +--- a/net/ipv4/netfilter/ip_conntrack_core.c ++++ b/net/ipv4/netfilter/ip_conntrack_core.c +@@ -1124,6 +1124,9 @@ void ip_conntrack_cleanup(void) + schedule(); + goto i_see_dead_people; + } ++ /* wait until all references to ip_conntrack_untracked are dropped */ ++ while (atomic_read(&ip_conntrack_untracked.ct_general.use) > 1) ++ schedule(); + + kmem_cache_destroy(ip_conntrack_cachep); + kmem_cache_destroy(ip_conntrack_expect_cachep); +diff --git a/net/ipv4/netfilter/ip_conntrack_standalone.c b/net/ipv4/netfilter/ip_conntrack_standalone.c +--- a/net/ipv4/netfilter/ip_conntrack_standalone.c ++++ b/net/ipv4/netfilter/ip_conntrack_standalone.c +@@ -432,6 +432,13 @@ static unsigned int ip_conntrack_defrag( + const struct net_device *out, + int (*okfn)(struct sk_buff *)) + { ++#if !defined(CONFIG_IP_NF_NAT) && !defined(CONFIG_IP_NF_NAT_MODULE) ++ /* Previously seen (loopback)? Ignore. Do this before ++ fragment check. */ ++ if ((*pskb)->nfct) ++ return NF_ACCEPT; ++#endif ++ + /* Gather fragments. */ + if ((*pskb)->nh.iph->frag_off & htons(IP_MF|IP_OFFSET)) { + *pskb = ip_ct_gather_frags(*pskb, +diff --git a/net/ipv4/netfilter/ip_nat_proto_tcp.c b/net/ipv4/netfilter/ip_nat_proto_tcp.c +--- a/net/ipv4/netfilter/ip_nat_proto_tcp.c ++++ b/net/ipv4/netfilter/ip_nat_proto_tcp.c +@@ -40,7 +40,8 @@ tcp_unique_tuple(struct ip_conntrack_tup + enum ip_nat_manip_type maniptype, + const struct ip_conntrack *conntrack) + { +- static u_int16_t port, *portptr; ++ static u_int16_t port; ++ u_int16_t *portptr; + unsigned int range_size, min, i; + + if (maniptype == IP_NAT_MANIP_SRC) +diff --git a/net/ipv4/netfilter/ip_nat_proto_udp.c b/net/ipv4/netfilter/ip_nat_proto_udp.c +--- a/net/ipv4/netfilter/ip_nat_proto_udp.c ++++ b/net/ipv4/netfilter/ip_nat_proto_udp.c +@@ -41,7 +41,8 @@ udp_unique_tuple(struct ip_conntrack_tup + enum ip_nat_manip_type maniptype, + const struct ip_conntrack *conntrack) + { +- static u_int16_t port, *portptr; ++ static u_int16_t port; ++ u_int16_t *portptr; + unsigned int range_size, min, i; + + if (maniptype == IP_NAT_MANIP_SRC) +diff --git a/net/ipv6/ip6_input.c b/net/ipv6/ip6_input.c +--- a/net/ipv6/ip6_input.c ++++ b/net/ipv6/ip6_input.c +@@ -198,12 +198,13 @@ resubmit: + if (!raw_sk) { + if (xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb)) { + IP6_INC_STATS_BH(IPSTATS_MIB_INUNKNOWNPROTOS); +- icmpv6_param_prob(skb, ICMPV6_UNK_NEXTHDR, nhoff); ++ icmpv6_send(skb, ICMPV6_PARAMPROB, ++ ICMPV6_UNK_NEXTHDR, nhoff, ++ skb->dev); + } +- } else { ++ } else + IP6_INC_STATS_BH(IPSTATS_MIB_INDELIVERS); +- kfree_skb(skb); +- } ++ kfree_skb(skb); + } + rcu_read_unlock(); + return 0; +diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c +--- a/net/ipv6/ipv6_sockglue.c ++++ b/net/ipv6/ipv6_sockglue.c +@@ -503,6 +503,9 @@ done: + break; + case IPV6_IPSEC_POLICY: + case IPV6_XFRM_POLICY: ++ retv = -EPERM; ++ if (!capable(CAP_NET_ADMIN)) ++ break; + retv = xfrm_user_policy(sk, optname, optval, optlen); + break; + +diff --git a/net/ipv6/netfilter/ip6_queue.c b/net/ipv6/netfilter/ip6_queue.c +--- a/net/ipv6/netfilter/ip6_queue.c ++++ b/net/ipv6/netfilter/ip6_queue.c +@@ -76,7 +76,9 @@ static DECLARE_MUTEX(ipqnl_sem); + static void + ipq_issue_verdict(struct ipq_queue_entry *entry, int verdict) + { ++ local_bh_disable(); + nf_reinject(entry->skb, entry->info, verdict); ++ local_bh_enable(); + kfree(entry); + } + +diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c +--- a/net/netlink/af_netlink.c ++++ b/net/netlink/af_netlink.c +@@ -315,8 +315,8 @@ err: + static void netlink_remove(struct sock *sk) + { + netlink_table_grab(); +- nl_table[sk->sk_protocol].hash.entries--; +- sk_del_node_init(sk); ++ if (sk_del_node_init(sk)) ++ nl_table[sk->sk_protocol].hash.entries--; + if (nlk_sk(sk)->groups) + __sk_del_bind_node(sk); + netlink_table_ungrab(); +@@ -429,7 +429,12 @@ retry: + err = netlink_insert(sk, pid); + if (err == -EADDRINUSE) + goto retry; +- return 0; ++ ++ /* If 2 threads race to autobind, that is fine. */ ++ if (err == -EBUSY) ++ err = 0; ++ ++ return err; + } + + static inline int netlink_capable(struct socket *sock, unsigned int flag) +diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c +--- a/net/packet/af_packet.c ++++ b/net/packet/af_packet.c +@@ -274,6 +274,9 @@ static int packet_rcv_spkt(struct sk_buf + dst_release(skb->dst); + skb->dst = NULL; + ++ /* drop conntrack reference */ ++ nf_reset(skb); ++ + spkt = (struct sockaddr_pkt*)skb->cb; + + skb_push(skb, skb->data-skb->mac.raw); +@@ -517,6 +520,9 @@ static int packet_rcv(struct sk_buff *sk + dst_release(skb->dst); + skb->dst = NULL; + ++ /* drop conntrack reference */ ++ nf_reset(skb); ++ + spin_lock(&sk->sk_receive_queue.lock); + po->stats.tp_packets++; + __skb_queue_tail(&sk->sk_receive_queue, skb); +diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c +--- a/net/xfrm/xfrm_user.c ++++ b/net/xfrm/xfrm_user.c +@@ -1180,6 +1180,9 @@ static struct xfrm_policy *xfrm_compile_ + if (nr > XFRM_MAX_DEPTH) + return NULL; + ++ if (p->dir > XFRM_POLICY_OUT) ++ return NULL; ++ + xp = xfrm_policy_alloc(GFP_KERNEL); + if (xp == NULL) { + *dir = -ENOBUFS; +diff --git a/security/keys/keyring.c b/security/keys/keyring.c +--- a/security/keys/keyring.c ++++ b/security/keys/keyring.c +@@ -188,7 +188,11 @@ static void keyring_destroy(struct key * + + if (keyring->description) { + write_lock(&keyring_name_lock); +- list_del(&keyring->type_data.link); ++ ++ if (keyring->type_data.link.next != NULL && ++ !list_empty(&keyring->type_data.link)) ++ list_del(&keyring->type_data.link); ++ + write_unlock(&keyring_name_lock); + } + +diff --git a/security/keys/process_keys.c b/security/keys/process_keys.c +--- a/security/keys/process_keys.c ++++ b/security/keys/process_keys.c +@@ -641,7 +641,7 @@ long join_session_keyring(const char *na + keyring = keyring_alloc(name, tsk->uid, tsk->gid, 0, NULL); + if (IS_ERR(keyring)) { + ret = PTR_ERR(keyring); +- goto error; ++ goto error2; + } + } + else if (IS_ERR(keyring)) { diff -r 19af31a59537 -r f31494465fb0 tools/security/get_decision.c --- /dev/null Fri Oct 21 11:06:17 2005 +++ b/tools/security/get_decision.c Fri Oct 21 11:07:14 2005 @@ -0,0 +1,176 @@ +/**************************************************************** + * get_decision.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. + * + * An example program that shows how to retrieve an access control + * decision from the hypervisor ACM based on the currently active policy. + * + */ + +#include <unistd.h> +#include <stdio.h> +#include <errno.h> +#include <fcntl.h> +#include <getopt.h> +#include <sys/mman.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <stdlib.h> +#include <sys/ioctl.h> +#include <string.h> +#include <netinet/in.h> +#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)) + +void usage(char *progname) +{ + printf("Use: %s \n", progname); + printf(" Test program illustrating the retrieval of\n"); + printf(" access control decisions from xen. At this time,\n"); + printf(" only sharing (STE) policy decisions are supported.\n"); + printf(" parameter options:\n"); + printf("\t -i domid -i domid\n"); + printf("\t -i domid -s ssidref\n"); + printf("\t -s ssidref -s ssidref\n\n"); + exit(-1); +} + +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, struct acm_op *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; +} + + +/************************ get decision ******************************/ + +/* this example uses two domain ids and retrieves the decision if these domains + * can share information (useful, i.e., to enforce policy onto network traffic in dom0 + */ +int acm_get_decision(int xc_handle, int argc, char *const argv[]) +{ + struct acm_op op; + int ret; + + op.cmd = ACM_GETDECISION; + op.interface_version = ACM_INTERFACE_VERSION; + op.u.getdecision.get_decision_by1 = UNSET; + op.u.getdecision.get_decision_by2 = UNSET; + op.u.getdecision.hook = SHARING; + + while (1) { + int c = getopt(argc, argv, "i:s:"); + if (c == -1) + break; + + if (c == 'i') { + if (op.u.getdecision.get_decision_by1 == UNSET) { + op.u.getdecision.get_decision_by1 = DOMAINID; + op.u.getdecision.id1.domainid = strtoul(optarg, NULL, 0); + } else if (op.u.getdecision.get_decision_by2 == UNSET) { + op.u.getdecision.get_decision_by2 = DOMAINID; + op.u.getdecision.id2.domainid = strtoul(optarg, NULL, 0); + } else + usage(argv[0]); + } else if (c == 's') { + if (op.u.getdecision.get_decision_by1 == UNSET) { + op.u.getdecision.get_decision_by1 = SSIDREF; + op.u.getdecision.id1.ssidref = strtoul(optarg, NULL, 0); + } else if (op.u.getdecision.get_decision_by2 == UNSET) { + op.u.getdecision.get_decision_by2 = SSIDREF; + op.u.getdecision.id2.ssidref = strtoul(optarg, NULL, 0); + } else + usage(argv[0]); + } else + usage(argv[0]); + } + if ((op.u.getdecision.get_decision_by1 == UNSET) || + (op.u.getdecision.get_decision_by2 == UNSET)) + usage(argv[0]); + + if ((ret = do_acm_op(xc_handle, &op))) { + printf("%s: Error getting decision (%d).\n", __func__, ret); + printf("%s: decision = %s.\n", __func__, + (op.u.getdecision.acm_decision == + ACM_ACCESS_PERMITTED) ? "PERMITTED" : ((op.u.getdecision. + acm_decision == + ACM_ACCESS_DENIED) + ? "DENIED" : + "ERROR")); + return ret; + } + return op.u.getdecision.acm_decision; +} + +/***************************** main **************************************/ + +int main(int argc, char **argv) +{ + + int acm_cmd_fd, ret = 0; + + if (argc < 5) + 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); + } + + ret = acm_get_decision(acm_cmd_fd, argc, argv); + + printf("Decision: %s (%d)\n", + (ret == ACM_ACCESS_PERMITTED) ? "PERMITTED" : + ((ret == ACM_ACCESS_DENIED) ? "DENIED" : "ERROR"), ret); + + close(acm_cmd_fd); + return ret; +} diff -r 19af31a59537 -r f31494465fb0 patches/linux-2.6.12/2.6.12.5.patch --- a/patches/linux-2.6.12/2.6.12.5.patch Fri Oct 21 11:06:17 2005 +++ /dev/null Fri Oct 21 11:07:14 2005 @@ -1,1614 +0,0 @@ -diff --git a/Makefile b/Makefile ---- a/Makefile -+++ b/Makefile -@@ -1,7 +1,7 @@ - VERSION = 2 - PATCHLEVEL = 6 - SUBLEVEL = 12 --EXTRAVERSION = -+EXTRAVERSION = .5 - NAME=Woozy Numbat - - # *DOCUMENTATION* -@@ -1149,7 +1149,7 @@ endif # KBUILD_EXTMOD - #(which is the most common case IMHO) to avoid unneeded clutter in the big tags file. - #Adding $(srctree) adds about 20M on i386 to the size of the output file! - --ifeq ($(KBUILD_OUTPUT),) -+ifeq ($(src),$(obj)) - __srctree = - else - __srctree = $(srctree)/ -diff --git a/arch/i386/kernel/cpu/cpufreq/powernow-k8.c b/arch/i386/kernel/cpu/cpufreq/powernow-k8.c ---- a/arch/i386/kernel/cpu/cpufreq/powernow-k8.c -+++ b/arch/i386/kernel/cpu/cpufreq/powernow-k8.c -@@ -44,7 +44,7 @@ - - #define PFX "powernow-k8: " - #define BFX PFX "BIOS error: " --#define VERSION "version 1.40.2" -+#define VERSION "version 1.40.4" - #include "powernow-k8.h" - - /* serialize freq changes */ -@@ -978,7 +978,7 @@ static int __init powernowk8_cpu_init(st - { - struct powernow_k8_data *data; - cpumask_t oldmask = CPU_MASK_ALL; -- int rc; -+ int rc, i; - - if (!check_supported_cpu(pol->cpu)) - return -ENODEV; -@@ -1064,7 +1064,9 @@ static int __init powernowk8_cpu_init(st - printk("cpu_init done, current fid 0x%x, vid 0x%x\n", - data->currfid, data->currvid); - -- powernow_data[pol->cpu] = data; -+ for_each_cpu_mask(i, cpu_core_map[pol->cpu]) { -+ powernow_data[i] = data; -+ } - - return 0; - -diff --git a/arch/i386/kernel/process.c b/arch/i386/kernel/process.c ---- a/arch/i386/kernel/process.c -+++ b/arch/i386/kernel/process.c -@@ -827,6 +827,8 @@ asmlinkage int sys_get_thread_area(struc - if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX) - return -EINVAL; - -+ memset(&info, 0, sizeof(info)); -+ - desc = current->thread.tls_array + idx - GDT_ENTRY_TLS_MIN; - - info.entry_number = idx; -diff --git a/arch/ia64/kernel/ptrace.c b/arch/ia64/kernel/ptrace.c ---- a/arch/ia64/kernel/ptrace.c -+++ b/arch/ia64/kernel/ptrace.c -@@ -945,6 +945,13 @@ access_uarea (struct task_struct *child, - *data = (pt->cr_ipsr & IPSR_MASK); - return 0; - -+ case PT_AR_RSC: -+ if (write_access) -+ pt->ar_rsc = *data | (3 << 2); /* force PL3 */ -+ else -+ *data = pt->ar_rsc; -+ return 0; -+ - case PT_AR_RNAT: - urbs_end = ia64_get_user_rbs_end(child, pt, NULL); - rnat_addr = (long) ia64_rse_rnat_addr((long *) -@@ -996,9 +1003,6 @@ access_uarea (struct task_struct *child, - case PT_AR_BSPSTORE: - ptr = pt_reg_addr(pt, ar_bspstore); - break; -- case PT_AR_RSC: -- ptr = pt_reg_addr(pt, ar_rsc); -- break; - case PT_AR_UNAT: - ptr = pt_reg_addr(pt, ar_unat); - break; -@@ -1234,7 +1238,7 @@ ptrace_getregs (struct task_struct *chil - static long - ptrace_setregs (struct task_struct *child, struct pt_all_user_regs __user *ppr) - { -- unsigned long psr, ec, lc, rnat, bsp, cfm, nat_bits, val = 0; -+ unsigned long psr, rsc, ec, lc, rnat, bsp, cfm, nat_bits, val = 0; - struct unw_frame_info info; - struct switch_stack *sw; - struct ia64_fpreg fpval; -@@ -1267,7 +1271,7 @@ ptrace_setregs (struct task_struct *chil - /* app regs */ - - retval |= __get_user(pt->ar_pfs, &ppr->ar[PT_AUR_PFS]); -- retval |= __get_user(pt->ar_rsc, &ppr->ar[PT_AUR_RSC]); -+ retval |= __get_user(rsc, &ppr->ar[PT_AUR_RSC]); - retval |= __get_user(pt->ar_bspstore, &ppr->ar[PT_AUR_BSPSTORE]); - retval |= __get_user(pt->ar_unat, &ppr->ar[PT_AUR_UNAT]); - retval |= __get_user(pt->ar_ccv, &ppr->ar[PT_AUR_CCV]); -@@ -1365,6 +1369,7 @@ ptrace_setregs (struct task_struct *chil - retval |= __get_user(nat_bits, &ppr->nat); - - retval |= access_uarea(child, PT_CR_IPSR, &psr, 1); -+ retval |= access_uarea(child, PT_AR_RSC, &rsc, 1); - retval |= access_uarea(child, PT_AR_EC, &ec, 1); - retval |= access_uarea(child, PT_AR_LC, &lc, 1); - retval |= access_uarea(child, PT_AR_RNAT, &rnat, 1); -diff --git a/arch/ia64/kernel/signal.c b/arch/ia64/kernel/signal.c ---- a/arch/ia64/kernel/signal.c -+++ b/arch/ia64/kernel/signal.c -@@ -94,7 +94,7 @@ sys_sigaltstack (const stack_t __user *u - static long - restore_sigcontext (struct sigcontext __user *sc, struct sigscratch *scr) - { -- unsigned long ip, flags, nat, um, cfm; -+ unsigned long ip, flags, nat, um, cfm, rsc; - long err; - - /* Always make any pending restarted system calls return -EINTR */ -@@ -106,7 +106,7 @@ restore_sigcontext (struct sigcontext __ - err |= __get_user(ip, &sc->sc_ip); /* instruction pointer */ - err |= __get_user(cfm, &sc->sc_cfm); - err |= __get_user(um, &sc->sc_um); /* user mask */ -- err |= __get_user(scr->pt.ar_rsc, &sc->sc_ar_rsc); -+ err |= __get_user(rsc, &sc->sc_ar_rsc); - err |= __get_user(scr->pt.ar_unat, &sc->sc_ar_unat); - err |= __get_user(scr->pt.ar_fpsr, &sc->sc_ar_fpsr); - err |= __get_user(scr->pt.ar_pfs, &sc->sc_ar_pfs); -@@ -119,6 +119,7 @@ restore_sigcontext (struct sigcontext __ - err |= __copy_from_user(&scr->pt.r15, &sc->sc_gr[15], 8); /* r15 */ - - scr->pt.cr_ifs = cfm | (1UL << 63); -+ scr->pt.ar_rsc = rsc | (3 << 2); /* force PL3 */ - - /* establish new instruction pointer: */ - scr->pt.cr_iip = ip & ~0x3UL; -diff --git a/arch/ppc/kernel/time.c b/arch/ppc/kernel/time.c ---- a/arch/ppc/kernel/time.c -+++ b/arch/ppc/kernel/time.c -@@ -89,6 +89,9 @@ unsigned long tb_to_ns_scale; - - extern unsigned long wall_jiffies; - -+/* used for timezone offset */ -+static long timezone_offset; -+ - DEFINE_SPINLOCK(rtc_lock); - - EXPORT_SYMBOL(rtc_lock); -@@ -170,7 +173,7 @@ void timer_interrupt(struct pt_regs * re - xtime.tv_sec - last_rtc_update >= 659 && - abs((xtime.tv_nsec / 1000) - (1000000-1000000/HZ)) < 500000/HZ && - jiffies - wall_jiffies == 1) { -- if (ppc_md.set_rtc_time(xtime.tv_sec+1 + time_offset) == 0) -+ if (ppc_md.set_rtc_time(xtime.tv_sec+1 + timezone_offset) == 0) - last_rtc_update = xtime.tv_sec+1; - else - /* Try again one minute later */ -@@ -286,7 +289,7 @@ void __init time_init(void) - unsigned old_stamp, stamp, elapsed; - - if (ppc_md.time_init != NULL) -- time_offset = ppc_md.time_init(); -+ timezone_offset = ppc_md.time_init(); - - if (__USE_RTC()) { - /* 601 processor: dec counts down by 128 every 128ns */ -@@ -331,10 +334,10 @@ void __init time_init(void) - set_dec(tb_ticks_per_jiffy); - - /* If platform provided a timezone (pmac), we correct the time */ -- if (time_offset) { -- sys_tz.tz_minuteswest = -time_offset / 60; -+ if (timezone_offset) { -+ sys_tz.tz_minuteswest = -timezone_offset / 60; - sys_tz.tz_dsttime = 0; -- xtime.tv_sec -= time_offset; -+ xtime.tv_sec -= timezone_offset; - } - set_normalized_timespec(&wall_to_monotonic, - -xtime.tv_sec, -xtime.tv_nsec); -diff --git a/arch/ppc64/boot/zlib.c b/arch/ppc64/boot/zlib.c ---- a/arch/ppc64/boot/zlib.c -+++ b/arch/ppc64/boot/zlib.c -@@ -1307,7 +1307,7 @@ local int huft_build( - { - *t = (inflate_huft *)Z_NULL; - *m = 0; -- return Z_OK; -+ return Z_DATA_ERROR; - } - - -@@ -1351,6 +1351,7 @@ local int huft_build( - if ((j = *p++) != 0) - v[x[j]++] = i; - } while (++i < n); -+ n = x[g]; /* set n to length of v */ - - - /* Generate the Huffman codes and for each, make the table entries */ -diff --git a/arch/um/kernel/process.c b/arch/um/kernel/process.c ---- a/arch/um/kernel/process.c -+++ b/arch/um/kernel/process.c -@@ -130,7 +130,7 @@ int start_fork_tramp(void *thread_arg, u - return(arg.pid); - } - --static int ptrace_child(void) -+static int ptrace_child(void *arg) - { - int ret; - int pid = os_getpid(), ppid = getppid(); -@@ -159,16 +159,20 @@ static int ptrace_child(void) - _exit(ret); - } - --static int start_ptraced_child(void) -+static int start_ptraced_child(void **stack_out) - { -+ void *stack; -+ unsigned long sp; - int pid, n, status; - -- pid = fork(); -- if(pid == 0) -- ptrace_child(); -- -+ stack = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC, -+ MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); -+ if(stack == MAP_FAILED) -+ panic("check_ptrace : mmap failed, errno = %d", errno); -+ sp = (unsigned long) stack + PAGE_SIZE - sizeof(void *); -+ pid = clone(ptrace_child, (void *) sp, SIGCHLD, NULL); - if(pid < 0) -- panic("check_ptrace : fork failed, errno = %d", errno); -+ panic("check_ptrace : clone failed, errno = %d", errno); - CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED)); - if(n < 0) - panic("check_ptrace : wait failed, errno = %d", errno); -@@ -176,6 +180,7 @@ static int start_ptraced_child(void) - panic("check_ptrace : expected SIGSTOP, got status = %d", - status); - -+ *stack_out = stack; - return(pid); - } - -@@ -183,12 +188,12 @@ static int start_ptraced_child(void) - * just avoid using sysemu, not panic, but only if SYSEMU features are broken. - * So only for SYSEMU features we test mustpanic, while normal host features - * must work anyway!*/ --static int stop_ptraced_child(int pid, int exitcode, int mustexit) -+static int stop_ptraced_child(int pid, void *stack, int exitcode, int mustpanic) - { - int status, n, ret = 0; - - if(ptrace(PTRACE_CONT, pid, 0, 0) < 0) -- panic("stop_ptraced_child : ptrace failed, errno = %d", errno); -+ panic("check_ptrace : ptrace failed, errno = %d", errno); - CATCH_EINTR(n = waitpid(pid, &status, 0)); - if(!WIFEXITED(status) || (WEXITSTATUS(status) != exitcode)) { - int exit_with = WEXITSTATUS(status); -@@ -199,13 +204,15 @@ static int stop_ptraced_child(int pid, i - printk("check_ptrace : child exited with exitcode %d, while " - "expecting %d; status 0x%x", exit_with, - exitcode, status); -- if (mustexit) -+ if (mustpanic) - panic("\n"); - else - printk("\n"); - ret = -1; - } - -+ if(munmap(stack, PAGE_SIZE) < 0) -+ panic("check_ptrace : munmap failed, errno = %d", errno); - return ret; - } - -@@ -227,11 +234,12 @@ __uml_setup("nosysemu", nosysemu_cmd_par - - static void __init check_sysemu(void) - { -+ void *stack; - int pid, syscall, n, status, count=0; - - printk("Checking syscall emulation patch for ptrace..."); - sysemu_supported = 0; -- pid = start_ptraced_child(); -+ pid = start_ptraced_child(&stack); - - if(ptrace(PTRACE_SYSEMU, pid, 0, 0) < 0) - goto fail; -@@ -249,7 +257,7 @@ static void __init check_sysemu(void) - panic("check_sysemu : failed to modify system " - "call return, errno = %d", errno); - -- if (stop_ptraced_child(pid, 0, 0) < 0) -+ if (stop_ptraced_child(pid, stack, 0, 0) < 0) - goto fail_stopped; - - sysemu_supported = 1; -@@ -257,7 +265,7 @@ static void __init check_sysemu(void) - set_using_sysemu(!force_sysemu_disabled); - - printk("Checking advanced syscall emulation patch for ptrace..."); -- pid = start_ptraced_child(); -+ pid = start_ptraced_child(&stack); - while(1){ - count++; - if(ptrace(PTRACE_SYSEMU_SINGLESTEP, pid, 0, 0) < 0) -@@ -282,7 +290,7 @@ static void __init check_sysemu(void) - break; - } - } -- if (stop_ptraced_child(pid, 0, 0) < 0) -+ if (stop_ptraced_child(pid, stack, 0, 0) < 0) - goto fail_stopped; - - sysemu_supported = 2; -@@ -293,17 +301,18 @@ static void __init check_sysemu(void) - return; - - fail: -- stop_ptraced_child(pid, 1, 0); -+ stop_ptraced_child(pid, stack, 1, 0); - fail_stopped: - printk("missing\n"); - } - - void __init check_ptrace(void) - { -+ void *stack; - int pid, syscall, n, status; - - printk("Checking that ptrace can change system call numbers..."); -- pid = start_ptraced_child(); -+ pid = start_ptraced_child(&stack); - - if (ptrace(PTRACE_OLDSETOPTIONS, pid, 0, (void *)PTRACE_O_TRACESYSGOOD) < 0) - panic("check_ptrace: PTRACE_SETOPTIONS failed, errno = %d", errno); -@@ -330,7 +339,7 @@ void __init check_ptrace(void) - break; - } - } -- stop_ptraced_child(pid, 0, 1); -+ stop_ptraced_child(pid, stack, 0, 1); - printk("OK\n"); - check_sysemu(); - } -@@ -362,10 +371,11 @@ void forward_pending_sigio(int target) - static inline int check_skas3_ptrace_support(void) - { - struct ptrace_faultinfo fi; -+ void *stack; - int pid, n, ret = 1; - - printf("Checking for the skas3 patch in the host..."); -- pid = start_ptraced_child(); -+ pid = start_ptraced_child(&stack); - - n = ptrace(PTRACE_FAULTINFO, pid, 0, &fi); - if (n < 0) { -@@ -380,7 +390,7 @@ static inline int check_skas3_ptrace_sup - } - - init_registers(pid); -- stop_ptraced_child(pid, 1, 1); -+ stop_ptraced_child(pid, stack, 1, 1); - - return(ret); - } -diff --git a/arch/x86_64/ia32/syscall32.c b/arch/x86_64/ia32/syscall32.c ---- a/arch/x86_64/ia32/syscall32.c -+++ b/arch/x86_64/ia32/syscall32.c -@@ -57,6 +57,7 @@ int syscall32_setup_pages(struct linux_b - int npages = (VSYSCALL32_END - VSYSCALL32_BASE) >> PAGE_SHIFT; - struct vm_area_struct *vma; - struct mm_struct *mm = current->mm; -+ int ret; - - vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL); - if (!vma) -@@ -78,7 +79,11 @@ int syscall32_setup_pages(struct linux_b - vma->vm_mm = mm; - - down_write(&mm->mmap_sem); -- insert_vm_struct(mm, vma); -+ if ((ret = insert_vm_struct(mm, vma))) { -+ up_write(&mm->mmap_sem); -+ kmem_cache_free(vm_area_cachep, vma); -+ return ret; -+ } - mm->total_vm += npages; - up_write(&mm->mmap_sem); - return 0; -diff --git a/arch/x86_64/kernel/setup.c b/arch/x86_64/kernel/setup.c ---- a/arch/x86_64/kernel/setup.c -+++ b/arch/x86_64/kernel/setup.c -@@ -729,8 +729,6 @@ static void __init amd_detect_cmp(struct - int cpu = smp_processor_id(); - int node = 0; - unsigned bits; -- if (c->x86_num_cores == 1) -- return; - - bits = 0; - while ((1 << bits) < c->x86_num_cores) -diff --git a/arch/x86_64/kernel/smp.c b/arch/x86_64/kernel/smp.c ---- a/arch/x86_64/kernel/smp.c -+++ b/arch/x86_64/kernel/smp.c -@@ -284,6 +284,71 @@ struct call_data_struct { - static struct call_data_struct * call_data; - - /* -+ * this function sends a 'generic call function' IPI to one other CPU -+ * in the system. -+ */ -+static void __smp_call_function_single (int cpu, void (*func) (void *info), void *info, -+ int nonatomic, int wait) -+{ -+ struct call_data_struct data; -+ int cpus = 1; -+ -+ data.func = func; -+ data.info = info; -+ atomic_set(&data.started, 0); -+ data.wait = wait; -+ if (wait) -+ atomic_set(&data.finished, 0); -+ -+ call_data = &data; -+ wmb(); -+ /* Send a message to all other CPUs and wait for them to respond */ -+ send_IPI_mask(cpumask_of_cpu(cpu), CALL_FUNCTION_VECTOR); -+ -+ /* Wait for response */ -+ while (atomic_read(&data.started) != cpus) -+ cpu_relax(); -+ -+ if (!wait) -+ return; -+ -+ while (atomic_read(&data.finished) != cpus) -+ cpu_relax(); -+} -+ -+/* -+ * Run a function on another CPU -+ * <func> The function to run. This must be fast and non-blocking. -+ * <info> An arbitrary pointer to pass to the function. -+ * <nonatomic> Currently unused. -+ * <wait> If true, wait until function has completed on other CPUs. -+ * [RETURNS] 0 on success, else a negative status code. -+ * -+ * Does not return until the remote CPU is nearly ready to execute <func> -+ * or is or has executed. -+ */ -+ -+int smp_call_function_single (int cpu, void (*func) (void *info), void *info, -+ int nonatomic, int wait) -+{ -+ -+ int me = get_cpu(); /* prevent preemption and reschedule on another processor */ -+ -+ if (cpu == me) { -+ printk("%s: trying to call self\n", __func__); -+ put_cpu(); -+ return -EBUSY; -+ } -+ spin_lock_bh(&call_lock); -+ -+ __smp_call_function_single(cpu, func,info,nonatomic,wait); -+ -+ spin_unlock_bh(&call_lock); -+ put_cpu(); -+ return 0; -+} -+ -+/* - * this function sends a 'generic call function' IPI to all other CPUs - * in the system. - */ -diff --git a/arch/x86_64/kernel/smpboot.c b/arch/x86_64/kernel/smpboot.c ---- a/arch/x86_64/kernel/smpboot.c -+++ b/arch/x86_64/kernel/smpboot.c -@@ -202,9 +202,6 @@ static __cpuinit void sync_master(void * - { - unsigned long flags, i; - -- if (smp_processor_id() != boot_cpu_id) -- return; -- - go[MASTER] = 0; - - local_irq_save(flags); -@@ -253,7 +250,7 @@ get_delta(long *rt, long *master) - return tcenter - best_tm; - } - --static __cpuinit void sync_tsc(void) -+static __cpuinit void sync_tsc(unsigned int master) - { - int i, done = 0; - long delta, adj, adjust_latency = 0; -@@ -267,9 +264,17 @@ static __cpuinit void sync_tsc(void) - } t[NUM_ROUNDS] __cpuinitdata; - #endif - -+ printk(KERN_INFO "CPU %d: Syncing TSC to CPU %u.\n", -+ smp_processor_id(), master); -+ - go[MASTER] = 1; - -- smp_call_function(sync_master, NULL, 1, 0); -+ /* It is dangerous to broadcast IPI as cpus are coming up, -+ * as they may not be ready to accept them. So since -+ * we only need to send the ipi to the boot cpu direct -+ * the message, and avoid the race. -+ */ -+ smp_call_function_single(master, sync_master, NULL, 1, 0); - - while (go[MASTER]) /* wait for master to be ready */ - no_cpu_relax(); -@@ -313,16 +318,14 @@ static __cpuinit void sync_tsc(void) - printk(KERN_INFO - "CPU %d: synchronized TSC with CPU %u (last diff %ld cycles, " - "maxerr %lu cycles)\n", -- smp_processor_id(), boot_cpu_id, delta, rt); -+ smp_processor_id(), master, delta, rt); - } - - static void __cpuinit tsc_sync_wait(void) - { - if (notscsync || !cpu_has_tsc) - return; -- printk(KERN_INFO "CPU %d: Syncing TSC to CPU %u.\n", smp_processor_id(), -- boot_cpu_id); -- sync_tsc(); -+ sync_tsc(0); - } - - static __init int notscsync_setup(char *s) -diff --git a/drivers/acpi/pci_irq.c b/drivers/acpi/pci_irq.c ---- a/drivers/acpi/pci_irq.c -+++ b/drivers/acpi/pci_irq.c -@@ -433,8 +433,9 @@ acpi_pci_irq_enable ( - printk(KERN_WARNING PREFIX "PCI Interrupt %s[%c]: no GSI", - pci_name(dev), ('A' + pin)); - /* Interrupt Line values above 0xF are forbidden */ -- if (dev->irq >= 0 && (dev->irq <= 0xF)) { -+ if (dev->irq > 0 && (dev->irq <= 0xF)) { - printk(" - using IRQ %d\n", dev->irq); -+ acpi_register_gsi(dev->irq, ACPI_LEVEL_SENSITIVE, ACPI_ACTIVE_LOW); - return_VALUE(0); - } - else { -diff --git a/drivers/char/rocket.c b/drivers/char/rocket.c ---- a/drivers/char/rocket.c -+++ b/drivers/char/rocket.c -@@ -277,7 +277,7 @@ static void rp_do_receive(struct r_port - ToRecv = space; - - if (ToRecv <= 0) -- return; -+ goto done; - - /* - * if status indicates there are errored characters in the -@@ -359,6 +359,7 @@ static void rp_do_receive(struct r_port - } - /* Push the data up to the tty layer */ - ld->receive_buf(tty, tty->flip.char_buf, tty->flip.flag_buf, count); -+done: - tty_ldisc_deref(ld); - } - -diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c ---- a/drivers/char/tpm/tpm.c -+++ b/drivers/char/tpm/tpm.c -@@ -32,12 +32,6 @@ - - #define TPM_BUFSIZE 2048 - --/* PCI configuration addresses */ --#define PCI_GEN_PMCON_1 0xA0 --#define PCI_GEN1_DEC 0xE4 --#define PCI_LPC_EN 0xE6 --#define PCI_GEN2_DEC 0xEC -- - static LIST_HEAD(tpm_chip_list); - static DEFINE_SPINLOCK(driver_lock); - static int dev_mask[32]; -@@ -61,72 +55,6 @@ void tpm_time_expired(unsigned long ptr) - EXPORT_SYMBOL_GPL(tpm_time_expired); - - /* -- * Initialize the LPC bus and enable the TPM ports -- */ --int tpm_lpc_bus_init(struct pci_dev *pci_dev, u16 base) --{ -- u32 lpcenable, tmp; -- int is_lpcm = 0; -- -- switch (pci_dev->vendor) { -- case PCI_VENDOR_ID_INTEL: -- switch (pci_dev->device) { -- case PCI_DEVICE_ID_INTEL_82801CA_12: -- case PCI_DEVICE_ID_INTEL_82801DB_12: -- is_lpcm = 1; -- break; -- } -- /* init ICH (enable LPC) */ -- pci_read_config_dword(pci_dev, PCI_GEN1_DEC, &lpcenable); -- lpcenable |= 0x20000000; -- pci_write_config_dword(pci_dev, PCI_GEN1_DEC, lpcenable); -- -- if (is_lpcm) { -- pci_read_config_dword(pci_dev, PCI_GEN1_DEC, -- &lpcenable); -- if ((lpcenable & 0x20000000) == 0) { -- dev_err(&pci_dev->dev, -- "cannot enable LPC\n"); -- return -ENODEV; -- } -- } -- -- /* initialize TPM registers */ -- pci_read_config_dword(pci_dev, PCI_GEN2_DEC, &tmp); -- -- if (!is_lpcm) -- tmp = (tmp & 0xFFFF0000) | (base & 0xFFF0); -- else -- tmp = -- (tmp & 0xFFFF0000) | (base & 0xFFF0) | -- 0x00000001; -- -- pci_write_config_dword(pci_dev, PCI_GEN2_DEC, tmp); -- -- if (is_lpcm) { -- pci_read_config_dword(pci_dev, PCI_GEN_PMCON_1, -- &tmp); -- tmp |= 0x00000004; /* enable CLKRUN */ -- pci_write_config_dword(pci_dev, PCI_GEN_PMCON_1, -- tmp); -- } -- tpm_write_index(0x0D, 0x55); /* unlock 4F */ -- tpm_write_index(0x0A, 0x00); /* int disable */ -- tpm_write_index(0x08, base); /* base addr lo */ -- tpm_write_index(0x09, (base & 0xFF00) >> 8); /* base addr hi */ -- tpm_write_index(0x0D, 0xAA); /* lock 4F */ -- break; -- case PCI_VENDOR_ID_AMD: -- /* nothing yet */ -- break; -- } -- -- return 0; --} -- --EXPORT_SYMBOL_GPL(tpm_lpc_bus_init); -- --/* - * Internal kernel interface to transmit TPM commands - */ - static ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf, -@@ -590,10 +518,6 @@ int tpm_pm_resume(struct pci_dev *pci_de - if (chip == NULL) - return -ENODEV; - -- spin_lock(&driver_lock); -- tpm_lpc_bus_init(pci_dev, chip->vendor->base); -- spin_unlock(&driver_lock); -- - return 0; - } - -diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h ---- a/drivers/char/tpm/tpm.h -+++ b/drivers/char/tpm/tpm.h -@@ -79,8 +79,6 @@ static inline void tpm_write_index(int i - } - - extern void tpm_time_expired(unsigned long); --extern int tpm_lpc_bus_init(struct pci_dev *, u16); -- - extern int tpm_register_hardware(struct pci_dev *, - struct tpm_vendor_specific *); - extern int tpm_open(struct inode *, struct file *); -diff --git a/drivers/char/tpm/tpm_atmel.c b/drivers/char/tpm/tpm_atmel.c ---- a/drivers/char/tpm/tpm_atmel.c -+++ b/drivers/char/tpm/tpm_atmel.c -@@ -22,7 +22,10 @@ - #include "tpm.h" - - /* Atmel definitions */ --#define TPM_ATML_BASE 0x400 -+enum tpm_atmel_addr { -+ TPM_ATMEL_BASE_ADDR_LO = 0x08, -+ TPM_ATMEL_BASE_ADDR_HI = 0x09 -+}; - - /* write status bits */ - #define ATML_STATUS_ABORT 0x01 -@@ -127,7 +130,6 @@ static struct tpm_vendor_specific tpm_at - .cancel = tpm_atml_cancel, - .req_complete_mask = ATML_STATUS_BUSY | ATML_STATUS_DATA_AVAIL, - .req_complete_val = ATML_STATUS_DATA_AVAIL, -- .base = TPM_ATML_BASE, - .miscdev = { .fops = &atmel_ops, }, - }; - -@@ -136,14 +138,16 @@ static int __devinit tpm_atml_init(struc - { - u8 version[4]; - int rc = 0; -+ int lo, hi; - - if (pci_enable_device(pci_dev)) - return -EIO; - -- if (tpm_lpc_bus_init(pci_dev, TPM_ATML_BASE)) { -- rc = -ENODEV; -- goto out_err; -- } -+ lo = tpm_read_index( TPM_ATMEL_BASE_ADDR_LO ); -+ hi = tpm_read_index( TPM_ATMEL_BASE_ADDR_HI ); -+ -+ tpm_atmel.base = (hi<<8)|lo; -+ dev_dbg( &pci_dev->dev, "Operating with base: 0x%x\n", tpm_atmel.base); - - /* verify that it is an Atmel part */ - if (tpm_read_index(4) != 'A' || tpm_read_index(5) != 'T' -diff --git a/drivers/char/tpm/tpm_nsc.c b/drivers/char/tpm/tpm_nsc.c ---- a/drivers/char/tpm/tpm_nsc.c -+++ b/drivers/char/tpm/tpm_nsc.c -@@ -24,6 +24,10 @@ - /* National definitions */ - #define TPM_NSC_BASE 0x360 - #define TPM_NSC_IRQ 0x07 -+#define TPM_NSC_BASE0_HI 0x60 -+#define TPM_NSC_BASE0_LO 0x61 -+#define TPM_NSC_BASE1_HI 0x62 -+#define TPM_NSC_BASE1_LO 0x63 - - #define NSC_LDN_INDEX 0x07 - #define NSC_SID_INDEX 0x20 -@@ -234,7 +238,6 @@ static struct tpm_vendor_specific tpm_ns - .cancel = tpm_nsc_cancel, - .req_complete_mask = NSC_STATUS_OBF, - .req_complete_val = NSC_STATUS_OBF, -- .base = TPM_NSC_BASE, - .miscdev = { .fops = &nsc_ops, }, - - }; -@@ -243,15 +246,16 @@ static int __devinit tpm_nsc_init(struct - const struct pci_device_id *pci_id) - { - int rc = 0; -+ int lo, hi; -+ -+ hi = tpm_read_index(TPM_NSC_BASE0_HI); -+ lo = tpm_read_index(TPM_NSC_BASE0_LO); -+ -+ tpm_nsc.base = (hi<<8) | lo; - - if (pci_enable_device(pci_dev)) - return -EIO; - -- if (tpm_lpc_bus_init(pci_dev, TPM_NSC_BASE)) { -- rc = -ENODEV; -- goto out_err; -- } -- - /* verify that it is a National part (SID) */ - if (tpm_read_index(NSC_SID_INDEX) != 0xEF) { - rc = -ENODEV; -diff --git a/drivers/char/tty_ioctl.c b/drivers/char/tty_ioctl.c ---- a/drivers/char/tty_ioctl.c -+++ b/drivers/char/tty_ioctl.c -@@ -476,11 +476,11 @@ int n_tty_ioctl(struct tty_struct * tty, - ld = tty_ldisc_ref(tty); - switch (arg) { - case TCIFLUSH: -- if (ld->flush_buffer) -+ if (ld && ld->flush_buffer) - ld->flush_buffer(tty); - break; - case TCIOFLUSH: -- if (ld->flush_buffer) -+ if (ld && ld->flush_buffer) - ld->flush_buffer(tty); - /* fall through */ - case TCOFLUSH: -diff --git a/drivers/media/video/cx88/cx88-video.c b/drivers/media/video/cx88/cx88-video.c ---- a/drivers/media/video/cx88/cx88-video.c -+++ b/drivers/media/video/cx88/cx88-video.c -@@ -261,7 +261,7 @@ static struct cx88_ctrl cx8800_ctls[] = - .default_value = 0, - .type = V4L2_CTRL_TYPE_INTEGER, - }, -- .off = 0, -+ .off = 128, - .reg = MO_HUE, - .mask = 0x00ff, - .shift = 0, -diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c ---- a/drivers/net/e1000/e1000_main.c -+++ b/drivers/net/e1000/e1000_main.c -@@ -2307,6 +2307,7 @@ e1000_xmit_frame(struct sk_buff *skb, st - tso = e1000_tso(adapter, skb); - if (tso < 0) { - dev_kfree_skb_any(skb); -+ spin_unlock_irqrestore(&adapter->tx_lock, flags); - return NETDEV_TX_OK; - } - -diff --git a/drivers/net/hamradio/Kconfig b/drivers/net/hamradio/Kconfig ---- a/drivers/net/hamradio/Kconfig -+++ b/drivers/net/hamradio/Kconfig -@@ -17,7 +17,7 @@ config MKISS - - config 6PACK - tristate "Serial port 6PACK driver" -- depends on AX25 && BROKEN_ON_SMP -+ depends on AX25 - ---help--- - 6pack is a transmission protocol for the data exchange between your - PC and your TNC (the Terminal Node Controller acts as a kind of -diff --git a/drivers/net/shaper.c b/drivers/net/shaper.c ---- a/drivers/net/shaper.c -+++ b/drivers/net/shaper.c -@@ -135,10 +135,8 @@ static int shaper_start_xmit(struct sk_b - { - struct shaper *shaper = dev->priv; - struct sk_buff *ptr; -- -- if (down_trylock(&shaper->sem)) -- return -1; - -+ spin_lock(&shaper->lock); - ptr=shaper->sendq.prev; - - /* -@@ -232,7 +230,7 @@ static int shaper_start_xmit(struct sk_b - shaper->stats.collisions++; - } - shaper_kick(shaper); -- up(&shaper->sem); -+ spin_unlock(&shaper->lock); - return 0; - } - -@@ -271,11 +269,9 @@ static void shaper_timer(unsigned long d - { - struct shaper *shaper = (struct shaper *)data; - -- if (!down_trylock(&shaper->sem)) { -- shaper_kick(shaper); -- up(&shaper->sem); -- } else -- mod_timer(&shaper->timer, jiffies); -+ spin_lock(&shaper->lock); -+ shaper_kick(shaper); -+ spin_unlock(&shaper->lock); - } - - /* -@@ -332,21 +328,6 @@ static void shaper_kick(struct shaper *s - - - /* -- * Flush the shaper queues on a closedown -- */ -- --static void shaper_flush(struct shaper *shaper) --{ -- struct sk_buff *skb; -- -- down(&shaper->sem); -- while((skb=skb_dequeue(&shaper->sendq))!=NULL) -- dev_kfree_skb(skb); -- shaper_kick(shaper); -- up(&shaper->sem); --} -- --/* - * Bring the interface up. We just disallow this until a - * bind. - */ -@@ -375,7 +356,15 @@ static int shaper_open(struct net_device - static int shaper_close(struct net_device *dev) - { - struct shaper *shaper=dev->priv; -- shaper_flush(shaper); -+ struct sk_buff *skb; -+ -+ while ((skb = skb_dequeue(&shaper->sendq)) != NULL) -+ dev_kfree_skb(skb); -+ -+ spin_lock_bh(&shaper->lock); -+ shaper_kick(shaper); -+ spin_unlock_bh(&shaper->lock); -+ - del_timer_sync(&shaper->timer); - return 0; - } -@@ -576,6 +565,7 @@ static void shaper_init_priv(struct net_ - init_timer(&sh->timer); - sh->timer.function=shaper_timer; - sh->timer.data=(unsigned long)sh; -+ spin_lock_init(&sh->lock); - } - - /* -diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c ---- a/drivers/pci/pci-driver.c -+++ b/drivers/pci/pci-driver.c -@@ -396,7 +396,7 @@ int pci_register_driver(struct pci_drive - /* FIXME, once all of the existing PCI drivers have been fixed to set - * the pci shutdown function, this test can go away. */ - if (!drv->driver.shutdown) -- drv->driver.shutdown = pci_device_shutdown, -+ drv->driver.shutdown = pci_device_shutdown; - drv->driver.owner = drv->owner; - drv->driver.kobj.ktype = &pci_driver_kobj_type; - pci_init_dynids(&drv->dynids); -diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c ---- a/drivers/scsi/qla2xxx/qla_init.c -+++ b/drivers/scsi/qla2xxx/qla_init.c -@@ -1914,9 +1914,11 @@ qla2x00_reg_remote_port(scsi_qla_host_t - rport_ids.roles |= FC_RPORT_ROLE_FCP_TARGET; - - fcport->rport = rport = fc_remote_port_add(ha->host, 0, &rport_ids); -- if (!rport) -+ if (!rport) { - qla_printk(KERN_WARNING, ha, - "Unable to allocate fc remote port!\n"); -+ return; -+ } - - if (rport->scsi_target_id != -1 && rport->scsi_target_id < MAX_TARGETS) - fcport->os_target_id = rport->scsi_target_id; -diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c ---- a/drivers/scsi/qla2xxx/qla_os.c -+++ b/drivers/scsi/qla2xxx/qla_os.c -@@ -1150,7 +1150,7 @@ iospace_error_exit: - */ - int qla2x00_probe_one(struct pci_dev *pdev, struct qla_board_info *brd_info) - { -- int ret; -+ int ret = -ENODEV; - device_reg_t __iomem *reg; - struct Scsi_Host *host; - scsi_qla_host_t *ha; -@@ -1161,7 +1161,7 @@ int qla2x00_probe_one(struct pci_dev *pd - fc_port_t *fcport; - - if (pci_enable_device(pdev)) -- return -1; -+ goto probe_out; - - host = scsi_host_alloc(&qla2x00_driver_template, - sizeof(scsi_qla_host_t)); -@@ -1183,9 +1183,8 @@ int qla2x00_probe_one(struct pci_dev *pd - - /* Configure PCI I/O space */ - ret = qla2x00_iospace_config(ha); -- if (ret != 0) { -- goto probe_alloc_failed; -- } -+ if (ret) -+ goto probe_failed; - - /* Sanitize the information from PCI BIOS. */ - host->irq = pdev->irq; -@@ -1258,23 +1257,10 @@ int qla2x00_probe_one(struct pci_dev *pd - qla_printk(KERN_WARNING, ha, - "[ERROR] Failed to allocate memory for adapter\n"); - -- goto probe_alloc_failed; -+ ret = -ENOMEM; -+ goto probe_failed; - } - -- pci_set_drvdata(pdev, ha); -- host->this_id = 255; -- host->cmd_per_lun = 3; -- host->unique_id = ha->instance; -- host->max_cmd_len = MAX_CMDSZ; -- host->max_channel = ha->ports - 1; -- host->max_id = ha->max_targets; -- host->max_lun = ha->max_luns; -- host->transportt = qla2xxx_transport_template; -- if (scsi_add_host(host, &pdev->dev)) -- goto probe_alloc_failed; -- -- qla2x00_alloc_sysfs_attr(ha); -- - if (qla2x00_initialize_adapter(ha) && - !(ha->device_flags & DFLG_NO_CABLE)) { - -@@ -1285,11 +1271,10 @@ int qla2x00_probe_one(struct pci_dev *pd - "Adapter flags %x.\n", - ha->host_no, ha->device_flags)); - -+ ret = -ENODEV; - goto probe_failed; - } - -- qla2x00_init_host_attr(ha); -- - /* - * Startup the kernel thread for this host adapter - */ -@@ -1299,17 +1284,26 @@ int qla2x00_probe_one(struct pci_dev *pd - qla_printk(KERN_WARNING, ha, - "Unable to start DPC thread!\n"); - -+ ret = -ENODEV; - goto probe_failed; - } - wait_for_completion(&ha->dpc_inited); - -+ host->this_id = 255; -+ host->cmd_per_lun = 3; -+ host->unique_id = ha->instance; -+ host->max_cmd_len = MAX_CMDSZ; -+ host->max_channel = ha->ports - 1; -+ host->max_lun = MAX_LUNS; -+ host->transportt = qla2xxx_transport_template; -+ - if (IS_QLA2100(ha) || IS_QLA2200(ha)) - ret = request_irq(host->irq, qla2100_intr_handler, - SA_INTERRUPT|SA_SHIRQ, ha->brd_info->drv_name, ha); - else - ret = request_irq(host->irq, qla2300_intr_handler, - SA_INTERRUPT|SA_SHIRQ, ha->brd_info->drv_name, ha); -- if (ret != 0) { -+ if (ret) { - qla_printk(KERN_WARNING, ha, - "Failed to reserve interrupt %d already in use.\n", - host->irq); -@@ -1363,9 +1357,18 @@ int qla2x00_probe_one(struct pci_dev *pd - msleep(10); - } - -+ pci_set_drvdata(pdev, ha); - ha->flags.init_done = 1; - num_hosts++; - -+ ret = scsi_add_host(host, &pdev->dev); -+ if (ret) -+ goto probe_failed; -+ -+ qla2x00_alloc_sysfs_attr(ha); -+ -+ qla2x00_init_host_attr(ha); -+ - qla_printk(KERN_INFO, ha, "\n" - " QLogic Fibre Channel HBA Driver: %s\n" - " QLogic %s - %s\n" -@@ -1384,9 +1387,6 @@ int qla2x00_probe_one(struct pci_dev *pd - probe_failed: - fc_remove_host(ha->host); - -- scsi_remove_host(host); -- --probe_alloc_failed: - qla2x00_free_device(ha); - - scsi_host_put(host); -@@ -1394,7 +1394,8 @@ probe_alloc_failed: - probe_disable_device: - pci_disable_device(pdev); - -- return -1; -+probe_out: -+ return ret; - } - EXPORT_SYMBOL_GPL(qla2x00_probe_one); - -diff --git a/fs/bio.c b/fs/bio.c ---- a/fs/bio.c -+++ b/fs/bio.c -@@ -261,6 +261,7 @@ inline void __bio_clone(struct bio *bio, - */ - bio->bi_vcnt = bio_src->bi_vcnt; - bio->bi_size = bio_src->bi_size; -+ bio->bi_idx = bio_src->bi_idx; - bio_phys_segments(q, bio); - bio_hw_segments(q, bio); - } -diff --git a/fs/char_dev.c b/fs/char_dev.c ---- a/fs/char_dev.c -+++ b/fs/char_dev.c -@@ -139,7 +139,7 @@ __unregister_chrdev_region(unsigned majo - struct char_device_struct *cd = NULL, **cp; - int i = major_to_index(major); - -- up(&chrdevs_lock); -+ down(&chrdevs_lock); - for (cp = &chrdevs[i]; *cp; cp = &(*cp)->next) - if ((*cp)->major == major && - (*cp)->baseminor == baseminor && -diff --git a/fs/exec.c b/fs/exec.c ---- a/fs/exec.c -+++ b/fs/exec.c -@@ -649,6 +649,7 @@ static inline int de_thread(struct task_ - } - sig->group_exit_task = NULL; - sig->notify_count = 0; -+ sig->real_timer.data = (unsigned long)current; - spin_unlock_irq(lock); - - /* -diff --git a/fs/isofs/compress.c b/fs/isofs/compress.c ---- a/fs/isofs/compress.c -+++ b/fs/isofs/compress.c -@@ -129,8 +129,14 @@ static int zisofs_readpage(struct file * - cend = le32_to_cpu(*(__le32 *)(bh->b_data + (blockendptr & bufmask))); - brelse(bh); - -+ if (cstart > cend) -+ goto eio; -+ - csize = cend-cstart; - -+ if (csize > deflateBound(1UL << zisofs_block_shift)) -+ goto eio; -+ - /* Now page[] contains an array of pages, any of which can be NULL, - and the locks on which we hold. We should now read the data and - release the pages. If the pages are NULL the decompressed data -diff --git a/include/asm-i386/string.h b/include/asm-i386/string.h ---- a/include/asm-i386/string.h -+++ b/include/asm-i386/string.h -@@ -116,7 +116,8 @@ __asm__ __volatile__( - "orb $1,%%al\n" - "3:" - :"=a" (__res), "=&S" (d0), "=&D" (d1) -- :"1" (cs),"2" (ct)); -+ :"1" (cs),"2" (ct) -+ :"memory"); - return __res; - } - -@@ -138,8 +139,9 @@ __asm__ __volatile__( - "3:\tsbbl %%eax,%%eax\n\t" - "orb $1,%%al\n" - "4:" -- :"=a" (__res), "=&S" (d0), "=&D" (d1), "=&c" (d2) -- :"1" (cs),"2" (ct),"3" (count)); -+ :"=a" (__res), "=&S" (d0), "=&D" (d1), "=&c" (d2) -+ :"1" (cs),"2" (ct),"3" (count) -+ :"memory"); - return __res; - } - -@@ -158,7 +160,9 @@ __asm__ __volatile__( - "movl $1,%1\n" - "2:\tmovl %1,%0\n\t" - "decl %0" -- :"=a" (__res), "=&S" (d0) : "1" (s),"0" (c)); -+ :"=a" (__res), "=&S" (d0) -+ :"1" (s),"0" (c) -+ :"memory"); - return __res; - } - -@@ -175,7 +179,9 @@ __asm__ __volatile__( - "leal -1(%%esi),%0\n" - "2:\ttestb %%al,%%al\n\t" - "jne 1b" -- :"=g" (__res), "=&S" (d0), "=&a" (d1) :"0" (0),"1" (s),"2" (c)); -+ :"=g" (__res), "=&S" (d0), "=&a" (d1) -+ :"0" (0),"1" (s),"2" (c) -+ :"memory"); - return __res; - } - -@@ -189,7 +195,9 @@ __asm__ __volatile__( - "scasb\n\t" - "notl %0\n\t" - "decl %0" -- :"=c" (__res), "=&D" (d0) :"1" (s),"a" (0), "0" (0xffffffffu)); -+ :"=c" (__res), "=&D" (d0) -+ :"1" (s),"a" (0), "0" (0xffffffffu) -+ :"memory"); - return __res; - } - -@@ -333,7 +341,9 @@ __asm__ __volatile__( - "je 1f\n\t" - "movl $1,%0\n" - "1:\tdecl %0" -- :"=D" (__res), "=&c" (d0) : "a" (c),"0" (cs),"1" (count)); -+ :"=D" (__res), "=&c" (d0) -+ :"a" (c),"0" (cs),"1" (count) -+ :"memory"); - return __res; - } - -@@ -369,7 +379,7 @@ __asm__ __volatile__( - "je 2f\n\t" - "stosb\n" - "2:" -- : "=&c" (d0), "=&D" (d1) -+ :"=&c" (d0), "=&D" (d1) - :"a" (c), "q" (count), "0" (count/4), "1" ((long) s) - :"memory"); - return (s); -@@ -392,7 +402,8 @@ __asm__ __volatile__( - "jne 1b\n" - "3:\tsubl %2,%0" - :"=a" (__res), "=&d" (d0) -- :"c" (s),"1" (count)); -+ :"c" (s),"1" (count) -+ :"memory"); - return __res; - } - /* end of additional stuff */ -@@ -473,7 +484,8 @@ static inline void * memscan(void * addr - "dec %%edi\n" - "1:" - : "=D" (addr), "=c" (size) -- : "0" (addr), "1" (size), "a" (c)); -+ : "0" (addr), "1" (size), "a" (c) -+ : "memory"); - return addr; - } - -diff --git a/include/asm-x86_64/smp.h b/include/asm-x86_64/smp.h ---- a/include/asm-x86_64/smp.h -+++ b/include/asm-x86_64/smp.h -@@ -46,6 +46,8 @@ extern int pic_mode; - extern int smp_num_siblings; - extern void smp_flush_tlb(void); - extern void smp_message_irq(int cpl, void *dev_id, struct pt_regs *regs); -+extern int smp_call_function_single (int cpuid, void (*func) (void *info), void *info, -+ int retry, int wait); - extern void smp_send_reschedule(int cpu); - extern void smp_invalidate_rcv(void); /* Process an NMI */ - extern void zap_low_mappings(void); -diff --git a/include/linux/if_shaper.h b/include/linux/if_shaper.h ---- a/include/linux/if_shaper.h -+++ b/include/linux/if_shaper.h -@@ -23,7 +23,7 @@ struct shaper - __u32 shapeclock; - unsigned long recovery; /* Time we can next clock a packet out on - an empty queue */ -- struct semaphore sem; -+ spinlock_t lock; - struct net_device_stats stats; - struct net_device *dev; - int (*hard_start_xmit) (struct sk_buff *skb, -diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h ---- a/include/linux/skbuff.h -+++ b/include/linux/skbuff.h -@@ -1192,7 +1192,7 @@ static inline void *skb_header_pointer(c - { - int hlen = skb_headlen(skb); - -- if (offset + len <= hlen) -+ if (hlen - offset >= len) - return skb->data + offset; - - if (skb_copy_bits(skb, offset, buffer, len) < 0) -diff --git a/include/linux/zlib.h b/include/linux/zlib.h ---- a/include/linux/zlib.h -+++ b/include/linux/zlib.h -@@ -506,6 +506,11 @@ extern int zlib_deflateReset (z_streamp - stream state was inconsistent (such as zalloc or state being NULL). - */ - -+static inline unsigned long deflateBound(unsigned long s) -+{ -+ return s + ((s + 7) >> 3) + ((s + 63) >> 6) + 11; -+} -+ - extern int zlib_deflateParams (z_streamp strm, int level, int strategy); - /* - Dynamically update the compression level and compression strategy. The -diff --git a/kernel/module.c b/kernel/module.c ---- a/kernel/module.c -+++ b/kernel/module.c -@@ -249,13 +249,18 @@ static inline unsigned int block_size(in - /* Created by linker magic */ - extern char __per_cpu_start[], __per_cpu_end[]; - --static void *percpu_modalloc(unsigned long size, unsigned long align) -+static void *percpu_modalloc(unsigned long size, unsigned long align, -+ const char *name) - { - unsigned long extra; - unsigned int i; - void *ptr; - -- BUG_ON(align > SMP_CACHE_BYTES); -+ if (align > SMP_CACHE_BYTES) { -+ printk(KERN_WARNING "%s: per-cpu alignment %li > %i\n", -+ name, align, SMP_CACHE_BYTES); -+ align = SMP_CACHE_BYTES; -+ } - - ptr = __per_cpu_start; - for (i = 0; i < pcpu_num_used; ptr += block_size(pcpu_size[i]), i++) { -@@ -347,7 +352,8 @@ static int percpu_modinit(void) - } - __initcall(percpu_modinit); - #else /* ... !CONFIG_SMP */ --static inline void *percpu_modalloc(unsigned long size, unsigned long align) -+static inline void *percpu_modalloc(unsigned long size, unsigned long align, -+ const char *name) - { - return NULL; - } -@@ -1554,7 +1560,8 @@ static struct module *load_module(void _ - if (pcpuindex) { - /* We have a special allocation for this section. */ - percpu = percpu_modalloc(sechdrs[pcpuindex].sh_size, -- sechdrs[pcpuindex].sh_addralign); -+ sechdrs[pcpuindex].sh_addralign, -+ mod->name); - if (!percpu) { - err = -ENOMEM; - goto free_mod; -diff --git a/lib/inflate.c b/lib/inflate.c ---- a/lib/inflate.c -+++ b/lib/inflate.c -@@ -326,7 +326,7 @@ DEBG("huft1 "); - { - *t = (struct huft *)NULL; - *m = 0; -- return 0; -+ return 2; - } - - DEBG("huft2 "); -@@ -374,6 +374,7 @@ DEBG("huft5 "); - if ((j = *p++) != 0) - v[x[j]++] = i; - } while (++i < n); -+ n = x[g]; /* set n to length of v */ - - DEBG("h6 "); - -@@ -410,12 +411,13 @@ DEBG1("1 "); - DEBG1("2 "); - f -= a + 1; /* deduct codes from patterns left */ - xp = c + k; -- while (++j < z) /* try smaller tables up to z bits */ -- { -- if ((f <<= 1) <= *++xp) -- break; /* enough codes to use up j bits */ -- f -= *xp; /* else deduct codes from patterns */ -- } -+ if (j < z) -+ while (++j < z) /* try smaller tables up to z bits */ -+ { -+ if ((f <<= 1) <= *++xp) -+ break; /* enough codes to use up j bits */ -+ f -= *xp; /* else deduct codes from patterns */ -+ } - } - DEBG1("3 "); - z = 1 << j; /* table entries for j-bit table */ -diff --git a/lib/zlib_inflate/inftrees.c b/lib/zlib_inflate/inftrees.c ---- a/lib/zlib_inflate/inftrees.c -+++ b/lib/zlib_inflate/inftrees.c -@@ -141,7 +141,7 @@ static int huft_build( - { - *t = NULL; - *m = 0; -- return Z_OK; -+ return Z_DATA_ERROR; - } - - -diff --git a/mm/memory.c b/mm/memory.c ---- a/mm/memory.c -+++ b/mm/memory.c -@@ -1164,7 +1164,7 @@ int remap_pfn_range(struct vm_area_struc - { - pgd_t *pgd; - unsigned long next; -- unsigned long end = addr + size; -+ unsigned long end = addr + PAGE_ALIGN(size); - struct mm_struct *mm = vma->vm_mm; - int err; - -diff --git a/mm/mempolicy.c b/mm/mempolicy.c ---- a/mm/mempolicy.c -+++ b/mm/mempolicy.c -@@ -409,7 +409,7 @@ asmlinkage long sys_set_mempolicy(int mo - struct mempolicy *new; - DECLARE_BITMAP(nodes, MAX_NUMNODES); - -- if (mode > MPOL_MAX) -+ if (mode < 0 || mode > MPOL_MAX) - return -EINVAL; - err = get_nodes(nodes, nmask, maxnode, mode); - if (err) -diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c ---- a/net/8021q/vlan.c -+++ b/net/8021q/vlan.c -@@ -578,6 +578,14 @@ static int vlan_device_event(struct noti - if (!vlandev) - continue; - -+ if (netif_carrier_ok(dev)) { -+ if (!netif_carrier_ok(vlandev)) -+ netif_carrier_on(vlandev); -+ } else { -+ if (netif_carrier_ok(vlandev)) -+ netif_carrier_off(vlandev); -+ } -+ - if ((vlandev->state & VLAN_LINK_STATE_MASK) != flgs) { - vlandev->state = (vlandev->state &~ VLAN_LINK_STATE_MASK) - | flgs; -diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c ---- a/net/ipv4/ip_output.c -+++ b/net/ipv4/ip_output.c -@@ -111,7 +111,6 @@ static int ip_dev_loopback_xmit(struct s - #ifdef CONFIG_NETFILTER_DEBUG - nf_debug_ip_loopback_xmit(newskb); - #endif -- nf_reset(newskb); - netif_rx(newskb); - return 0; - } -@@ -196,8 +195,6 @@ static inline int ip_finish_output2(stru - nf_debug_ip_finish_output2(skb); - #endif /*CONFIG_NETFILTER_DEBUG*/ - -- nf_reset(skb); -- - if (hh) { - int hh_alen; - -diff --git a/net/ipv4/netfilter/ip_conntrack_core.c b/net/ipv4/netfilter/ip_conntrack_core.c ---- a/net/ipv4/netfilter/ip_conntrack_core.c -+++ b/net/ipv4/netfilter/ip_conntrack_core.c -@@ -1124,6 +1124,9 @@ void ip_conntrack_cleanup(void) - schedule(); - goto i_see_dead_people; - } -+ /* wait until all references to ip_conntrack_untracked are dropped */ -+ while (atomic_read(&ip_conntrack_untracked.ct_general.use) > 1) -+ schedule(); - - kmem_cache_destroy(ip_conntrack_cachep); - kmem_cache_destroy(ip_conntrack_expect_cachep); -diff --git a/net/ipv4/netfilter/ip_conntrack_standalone.c b/net/ipv4/netfilter/ip_conntrack_standalone.c ---- a/net/ipv4/netfilter/ip_conntrack_standalone.c -+++ b/net/ipv4/netfilter/ip_conntrack_standalone.c -@@ -432,6 +432,13 @@ static unsigned int ip_conntrack_defrag( - const struct net_device *out, - int (*okfn)(struct sk_buff *)) - { -+#if !defined(CONFIG_IP_NF_NAT) && !defined(CONFIG_IP_NF_NAT_MODULE) -+ /* Previously seen (loopback)? Ignore. Do this before -+ fragment check. */ -+ if ((*pskb)->nfct) -+ return NF_ACCEPT; -+#endif -+ - /* Gather fragments. */ - if ((*pskb)->nh.iph->frag_off & htons(IP_MF|IP_OFFSET)) { - *pskb = ip_ct_gather_frags(*pskb, -diff --git a/net/ipv4/netfilter/ip_nat_proto_tcp.c b/net/ipv4/netfilter/ip_nat_proto_tcp.c ---- a/net/ipv4/netfilter/ip_nat_proto_tcp.c -+++ b/net/ipv4/netfilter/ip_nat_proto_tcp.c -@@ -40,7 +40,8 @@ tcp_unique_tuple(struct ip_conntrack_tup - enum ip_nat_manip_type maniptype, - const struct ip_conntrack *conntrack) - { -- static u_int16_t port, *portptr; -+ static u_int16_t port; -+ u_int16_t *portptr; - unsigned int range_size, min, i; - - if (maniptype == IP_NAT_MANIP_SRC) -diff --git a/net/ipv4/netfilter/ip_nat_proto_udp.c b/net/ipv4/netfilter/ip_nat_proto_udp.c ---- a/net/ipv4/netfilter/ip_nat_proto_udp.c -+++ b/net/ipv4/netfilter/ip_nat_proto_udp.c -@@ -41,7 +41,8 @@ udp_unique_tuple(struct ip_conntrack_tup - enum ip_nat_manip_type maniptype, - const struct ip_conntrack *conntrack) - { -- static u_int16_t port, *portptr; -+ static u_int16_t port; -+ u_int16_t *portptr; - unsigned int range_size, min, i; - - if (maniptype == IP_NAT_MANIP_SRC) -diff --git a/net/ipv6/netfilter/ip6_queue.c b/net/ipv6/netfilter/ip6_queue.c ---- a/net/ipv6/netfilter/ip6_queue.c -+++ b/net/ipv6/netfilter/ip6_queue.c -@@ -76,7 +76,9 @@ static DECLARE_MUTEX(ipqnl_sem); - static void - ipq_issue_verdict(struct ipq_queue_entry *entry, int verdict) - { -+ local_bh_disable(); - nf_reinject(entry->skb, entry->info, verdict); -+ local_bh_enable(); - kfree(entry); - } - -diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c ---- a/net/netlink/af_netlink.c -+++ b/net/netlink/af_netlink.c -@@ -315,8 +315,8 @@ err: - static void netlink_remove(struct sock *sk) - { - netlink_table_grab(); -- nl_table[sk->sk_protocol].hash.entries--; -- sk_del_node_init(sk); -+ if (sk_del_node_init(sk)) -+ nl_table[sk->sk_protocol].hash.entries--; - if (nlk_sk(sk)->groups) - __sk_del_bind_node(sk); - netlink_table_ungrab(); -@@ -429,7 +429,12 @@ retry: - err = netlink_insert(sk, pid); - if (err == -EADDRINUSE) - goto retry; -- return 0; -+ -+ /* If 2 threads race to autobind, that is fine. */ -+ if (err == -EBUSY) -+ err = 0; -+ -+ return err; - } - - static inline int netlink_capable(struct socket *sock, unsigned int flag) -diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c ---- a/net/packet/af_packet.c -+++ b/net/packet/af_packet.c -@@ -274,6 +274,9 @@ static int packet_rcv_spkt(struct sk_buf - dst_release(skb->dst); - skb->dst = NULL; - -+ /* drop conntrack reference */ -+ nf_reset(skb); -+ - spkt = (struct sockaddr_pkt*)skb->cb; - - skb_push(skb, skb->data-skb->mac.raw); -@@ -517,6 +520,9 @@ static int packet_rcv(struct sk_buff *sk - dst_release(skb->dst); - skb->dst = NULL; - -+ /* drop conntrack reference */ -+ nf_reset(skb); -+ - spin_lock(&sk->sk_receive_queue.lock); - po->stats.tp_packets++; - __skb_queue_tail(&sk->sk_receive_queue, skb); -diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c ---- a/net/xfrm/xfrm_user.c -+++ b/net/xfrm/xfrm_user.c -@@ -1180,6 +1180,9 @@ static struct xfrm_policy *xfrm_compile_ - if (nr > XFRM_MAX_DEPTH) - return NULL; - -+ if (p->dir > XFRM_POLICY_OUT) -+ return NULL; -+ - xp = xfrm_policy_alloc(GFP_KERNEL); - if (xp == NULL) { - *dir = -ENOBUFS; -diff --git a/security/keys/keyring.c b/security/keys/keyring.c ---- a/security/keys/keyring.c -+++ b/security/keys/keyring.c -@@ -188,7 +188,11 @@ static void keyring_destroy(struct key * - - if (keyring->description) { - write_lock(&keyring_name_lock); -- list_del(&keyring->type_data.link); -+ -+ if (keyring->type_data.link.next != NULL && -+ !list_empty(&keyring->type_data.link)) -+ list_del(&keyring->type_data.link); -+ - write_unlock(&keyring_name_lock); - } - -diff --git a/security/keys/process_keys.c b/security/keys/process_keys.c ---- a/security/keys/process_keys.c -+++ b/security/keys/process_keys.c -@@ -641,7 +641,7 @@ long join_session_keyring(const char *na - keyring = keyring_alloc(name, tsk->uid, tsk->gid, 0, NULL); - if (IS_ERR(keyring)) { - ret = PTR_ERR(keyring); -- goto error; -+ goto error2; - } - } - else if (IS_ERR(keyring)) { _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |