diff --git a/Makefile.am b/Makefile.am index aa9c8b6f8..c605e87bc 100644 --- a/Makefile.am +++ b/Makefile.am @@ -50,10 +50,12 @@ EXTRA_DIST = xorg-server.pc.in xorg-server.m4 ChangeLog autogen.sh MAINTAINERCLEANFILES=ChangeLog +DISTCLEANFILES = doltlibtool doltcompile + .PHONY: ChangeLog ChangeLog: - (GIT_DIR=$(top_srcdir)/.git git-log > .changelog.tmp && mv .changelog.tmp ChangeLog; rm -f .changelog.tmp) || \ + (GIT_DIR=$(top_srcdir)/.git git log > .changelog.tmp && mv .changelog.tmp ChangeLog; rm -f .changelog.tmp) || \ (touch ChangeLog; echo 'git directory not found: installing possibly empty changelog.' >&2) dist-hook: ChangeLog diff --git a/Xext/xselinux.c b/Xext/xselinux.c index 93ea05b92..226a4b418 100644 --- a/Xext/xselinux.c +++ b/Xext/xselinux.c @@ -186,19 +186,19 @@ SELinuxAtomToSIDLookup(Atom atom, SELinuxObjectRec *obj, int map, int polymap) obj->poly = 1; /* Look in the mappings of names to contexts */ - if (selabel_lookup(label_hnd, &ctx, name, map) == 0) { + if (selabel_lookup_raw(label_hnd, &ctx, name, map) == 0) { obj->poly = 0; } else if (errno != ENOENT) { ErrorF("SELinux: a property label lookup failed!\n"); return BadValue; - } else if (selabel_lookup(label_hnd, &ctx, name, polymap) < 0) { + } else if (selabel_lookup_raw(label_hnd, &ctx, name, polymap) < 0) { ErrorF("SELinux: a property label lookup failed!\n"); return BadValue; } /* Get a SID for context */ - if (avc_context_to_sid(ctx, &obj->sid) < 0) { - ErrorF("SELinux: a context_to_SID call failed!\n"); + if (avc_context_to_sid_raw(ctx, &obj->sid) < 0) { + ErrorF("SELinux: a context_to_SID_raw call failed!\n"); rc = BadAlloc; } @@ -343,7 +343,7 @@ SELinuxEventToSID(unsigned type, security_id_t sid_of_window, SELinuxObjectRec *sid_return) { const char *name = LookupEventName(type); - security_context_t con; + security_context_t ctx; type &= 127; if (type >= numKnownEvents) { @@ -359,16 +359,16 @@ SELinuxEventToSID(unsigned type, security_id_t sid_of_window, if (!knownEvents[type]) { /* Look in the mappings of event names to contexts */ - if (selabel_lookup(label_hnd, &con, name, SELABEL_X_EVENT) < 0) { + if (selabel_lookup_raw(label_hnd, &ctx, name, SELABEL_X_EVENT) < 0) { ErrorF("SELinux: an event label lookup failed!\n"); return BadValue; } /* Get a SID for context */ - if (avc_context_to_sid(con, knownEvents + type) < 0) { - ErrorF("SELinux: a context_to_SID call failed!\n"); + if (avc_context_to_sid_raw(ctx, knownEvents + type) < 0) { + ErrorF("SELinux: a context_to_SID_raw call failed!\n"); return BadAlloc; } - freecon(con); + freecon(ctx); } /* Perform a transition to obtain the final SID */ @@ -474,7 +474,7 @@ SELinuxLabelClient(ClientPtr client) /* Try to get a context from the socket */ if (fd < 0 || getpeercon_raw(fd, &ctx) < 0) { /* Otherwise, fall back to a default context */ - if (selabel_lookup(label_hnd, &ctx, "remote", SELABEL_X_CLIENT) < 0) + if (selabel_lookup_raw(label_hnd, &ctx, "remote", SELABEL_X_CLIENT) < 0) FatalError("SELinux: failed to look up remote-client context\n"); } @@ -509,8 +509,8 @@ SELinuxLabelClient(ClientPtr client) finish: /* Get a SID from the context */ - if (avc_context_to_sid(ctx, &subj->sid) < 0) - FatalError("SELinux: client %d: context_to_sid(%s) failed\n", + if (avc_context_to_sid_raw(ctx, &subj->sid) < 0) + FatalError("SELinux: client %d: context_to_sid_raw(%s) failed\n", client->index, ctx); sidget(obj->sid = subj->sid); @@ -541,7 +541,7 @@ SELinuxLabelInitial(void) FatalError("SELinux: couldn't get context of X server process\n"); /* Get a SID from the context */ - if (avc_context_to_sid(ctx, &subj->sid) < 0) + if (avc_context_to_sid_raw(ctx, &subj->sid) < 0) FatalError("SELinux: serverClient: context_to_sid(%s) failed\n", ctx); sidget(obj->sid = subj->sid); @@ -827,20 +827,20 @@ SELinuxExtension(CallbackListPtr *pcbl, pointer unused, pointer calldata) /* XXX there should be a separate callback for this */ if (obj->sid == unlabeled_sid) { const char *name = rec->ext->name; - security_context_t con; + security_context_t ctx; security_id_t sid; serv = dixLookupPrivate(&serverClient->devPrivates, subjectKey); /* Look in the mappings of extension names to contexts */ - if (selabel_lookup(label_hnd, &con, name, SELABEL_X_EXT) < 0) { + if (selabel_lookup_raw(label_hnd, &ctx, name, SELABEL_X_EXT) < 0) { ErrorF("SELinux: a property label lookup failed!\n"); rec->status = BadValue; return; } /* Get a SID for context */ - if (avc_context_to_sid(con, &sid) < 0) { - ErrorF("SELinux: a context_to_SID call failed!\n"); + if (avc_context_to_sid_raw(ctx, &sid) < 0) { + ErrorF("SELinux: a context_to_SID_raw call failed!\n"); rec->status = BadAlloc; return; } @@ -851,11 +851,11 @@ SELinuxExtension(CallbackListPtr *pcbl, pointer unused, pointer calldata) if (avc_compute_create(serv->sid, sid, SECCLASS_X_EXTENSION, &obj->sid) < 0) { ErrorF("SELinux: a SID transition call failed!\n"); - freecon(con); + freecon(ctx); rec->status = BadValue; return; } - freecon(con); + freecon(ctx); } /* Perform the security check */ @@ -1150,13 +1150,15 @@ SELinuxResourceState(CallbackListPtr *pcbl, pointer unused, pointer calldata) if (rec->type != RT_WINDOW) return; + if (rec->state != ResourceStateAdding) + return; pWin = (WindowPtr)rec->value; subj = dixLookupPrivate(&wClient(pWin)->devPrivates, subjectKey); if (subj->sid) { security_context_t ctx; - int rc = avc_sid_to_context(subj->sid, &ctx); + int rc = avc_sid_to_context_raw(subj->sid, &ctx); if (rc < 0) FatalError("SELinux: Failed to get security context!\n"); rc = dixChangeWindowProperty(serverClient, @@ -1172,7 +1174,7 @@ SELinuxResourceState(CallbackListPtr *pcbl, pointer unused, pointer calldata) if (obj->sid) { security_context_t ctx; - int rc = avc_sid_to_context(obj->sid, &ctx); + int rc = avc_sid_to_context_raw(obj->sid, &ctx); if (rc < 0) FatalError("SELinux: Failed to get security context!\n"); rc = dixChangeWindowProperty(serverClient, @@ -1288,7 +1290,7 @@ SELinuxSendContextReply(ClientPtr client, security_id_t sid) int len = 0; if (sid) { - if (avc_sid_to_context(sid, &ctx) < 0) + if (avc_sid_to_context_raw(sid, &ctx) < 0) return BadValue; len = strlen(ctx) + 1; } @@ -1347,9 +1349,9 @@ ProcSELinuxSetCreateContext(ClientPtr client, unsigned offset) *pSid = NULL; if (stuff->context_len > 0) { - if (security_check_context(ctx) < 0) + if (security_check_context_raw(ctx) < 0) return BadValue; - if (avc_context_to_sid(ctx, pSid) < 0) + if (avc_context_to_sid_raw(ctx, pSid) < 0) return BadValue; } return Success; @@ -1393,9 +1395,9 @@ ProcSELinuxSetDeviceContext(ClientPtr client) if (rc != Success) return rc; - if (security_check_context(ctx) < 0) + if (security_check_context_raw(ctx) < 0) return BadValue; - if (avc_context_to_sid(ctx, &sid) < 0) + if (avc_context_to_sid_raw(ctx, &sid) < 0) return BadValue; subj = dixLookupPrivate(&dev->devPrivates, subjectKey); @@ -1511,9 +1513,9 @@ SELinuxPopulateItem(SELinuxListItemRec *i, PrivateRec **privPtr, CARD32 id, SELinuxObjectRec *obj = dixLookupPrivate(privPtr, objectKey); SELinuxObjectRec *data = dixLookupPrivate(privPtr, dataKey); - if (avc_sid_to_context(obj->sid, &i->octx) < 0) + if (avc_sid_to_context_raw(obj->sid, &i->octx) < 0) return BadValue; - if (avc_sid_to_context(data->sid, &i->dctx) < 0) + if (avc_sid_to_context_raw(data->sid, &i->dctx) < 0) return BadValue; i->id = id; @@ -1887,6 +1889,22 @@ SProcSELinuxDispatch(ClientPtr client) } } +#ifdef HAVE_AVC_NETLINK_ACQUIRE_FD +static int netlink_fd; + +static void +SELinuxBlockHandler(void *data, struct timeval **tv, void *read_mask) +{ +} + +static void +SELinuxWakeupHandler(void *data, int err, void *read_mask) +{ + if (FD_ISSET(netlink_fd, (fd_set *)read_mask)) + avc_netlink_check_nb(); +} +#endif + /* * Extension Setup / Teardown @@ -1917,6 +1935,12 @@ SELinuxResetProc(ExtensionEntry *extEntry) label_hnd = NULL; audit_close(audit_fd); +#ifdef HAVE_AVC_NETLINK_ACQUIRE_FD + avc_netlink_release_fd(); + RemoveBlockAndWakeupHandlers(SELinuxBlockHandler, SELinuxWakeupHandler, + NULL); + RemoveGeneralSocket(netlink_fd); +#endif avc_destroy(); avc_active = 0; @@ -1941,7 +1965,7 @@ SELinuxExtensionInit(INITARGS) ExtensionEntry *extEntry; struct selinux_opt selabel_option = { SELABEL_OPT_VALIDATE, (char *)1 }; struct selinux_opt avc_option = { AVC_OPT_SETENFORCE, (char *)0 }; - security_context_t con; + security_context_t ctx; int ret = TRUE; /* Check SELinux mode on system */ @@ -1988,11 +2012,11 @@ SELinuxExtensionInit(INITARGS) if (!label_hnd) FatalError("SELinux: Failed to open x_contexts mapping in policy\n"); - if (security_get_initial_context("unlabeled", &con) < 0) + if (security_get_initial_context_raw("unlabeled", &ctx) < 0) FatalError("SELinux: Failed to look up unlabeled context\n"); - if (avc_context_to_sid(con, &unlabeled_sid) < 0) + if (avc_context_to_sid_raw(ctx, &unlabeled_sid) < 0) FatalError("SELinux: a context_to_SID call failed!\n"); - freecon(con); + freecon(ctx); /* Prepare for auditing */ audit_fd = audit_open(); @@ -2013,6 +2037,13 @@ SELinuxExtensionInit(INITARGS) if (atom_client_ctx == BAD_RESOURCE) FatalError("SELinux: Failed to create atom\n"); +#ifdef HAVE_AVC_NETLINK_ACQUIRE_FD + netlink_fd = avc_netlink_acquire_fd(); + AddGeneralSocket(netlink_fd); + RegisterBlockAndWakeupHandlers(SELinuxBlockHandler, SELinuxWakeupHandler, + NULL); +#endif + /* Register callbacks */ ret &= dixRegisterPrivateInitFunc(subjectKey, SELinuxSubjectInit, NULL); ret &= dixRegisterPrivateDeleteFunc(subjectKey, SELinuxSubjectFree, NULL); diff --git a/Xi/xiproperty.c b/Xi/xiproperty.c index 01db856bf..26af3fc00 100644 --- a/Xi/xiproperty.c +++ b/Xi/xiproperty.c @@ -32,6 +32,7 @@ #include "dix.h" #include "inputstr.h" #include +#include #include #include "exglobals.h" #include "exevents.h" @@ -48,7 +49,8 @@ static struct dev_properties Atom type; char *name; } dev_properties[] = { - {0, XI_PROP_ENABLED} + {0, XI_PROP_ENABLED}, + {0, XATOM_FLOAT} }; static long XIPropHandlerID = 1; @@ -56,11 +58,17 @@ static long XIPropHandlerID = 1; /** * Return the type assigned to the specified atom or 0 if the atom isn't known * to the DIX. + * + * If name is NULL, None is returned. */ _X_EXPORT Atom XIGetKnownProperty(char *name) { int i; + + if (!name) + return None; + for (i = 0; i < (sizeof(dev_properties)/sizeof(struct dev_properties)); i++) { if (strcmp(name, dev_properties[i].name) == 0) @@ -70,6 +78,125 @@ XIGetKnownProperty(char *name) return 0; } +/** + * Convert the given property's value(s) into @nelem_return integer values and + * store them in @buf_return. If @nelem_return is larger than the number of + * values in the property, @nelem_return is set to the number of values in the + * property. + * + * If *@buf_return is NULL and @nelem_return is 0, memory is allocated + * automatically and must be freed by the caller. + * + * Possible return codes. + * Success ... No error. + * BadMatch ... Wrong atom type, atom is not XA_INTEGER + * BadAlloc ... NULL passed as buffer and allocation failed. + * BadLength ... @buff is NULL but @nelem_return is non-zero. + * + * @param val The property value + * @param nelem_return The maximum number of elements to return. + * @param buf_return Pointer to an array of at least @nelem_return values. + * @return Success or the error code if an error occured. + */ +_X_EXPORT int +XIPropToInt(XIPropertyValuePtr val, int *nelem_return, int **buf_return) +{ + int i; + int *buf; + + if (val->type != XA_INTEGER) + return BadMatch; + if (!*buf_return && *nelem_return) + return BadLength; + + switch(val->format) + { + case 8: + case 16: + case 32: + break; + default: + return BadValue; + } + + buf = *buf_return; + + if (!buf && !(*nelem_return)) + { + buf = xcalloc(val->size, sizeof(int)); + if (!buf) + return BadAlloc; + *buf_return = buf; + *nelem_return = val->size; + } else if (val->size < *nelem_return) + *nelem_return = val->size; + + for (i = 0; i < val->size && i < *nelem_return; i++) + { + switch(val->format) + { + case 8: buf[i] = ((CARD8*)val->data)[i]; break; + case 16: buf[i] = ((CARD16*)val->data)[i]; break; + case 32: buf[i] = ((CARD32*)val->data)[i]; break; + } + } + + return Success; +} + +/** + * Convert the given property's value(s) into @nelem_return float values and + * store them in @buf_return. If @nelem_return is larger than the number of + * values in the property, @nelem_return is set to the number of values in the + * property. + * + * If *@buf_return is NULL and @nelem_return is 0, memory is allocated + * automatically and must be freed by the caller. + * + * Possible errors returned: + * Success + * BadMatch ... Wrong atom type, atom is not XA_FLOAT + * BadValue ... Wrong format, format is not 32 + * BadAlloc ... NULL passed as buffer and allocation failed. + * BadLength ... @buff is NULL but @nelem_return is non-zero. + * + * @param val The property value + * @param nelem_return The maximum number of elements to return. + * @param buf_return Pointer to an array of at least @nelem_return values. + * @return Success or the error code if an error occured. + */ +_X_EXPORT int +XIPropToFloat(XIPropertyValuePtr val, int *nelem_return, float **buf_return) +{ + int i; + float *buf; + + if (!val->type || val->type != XIGetKnownProperty(XATOM_FLOAT)) + return BadMatch; + + if (val->format != 32) + return BadValue; + if (!*buf_return && *nelem_return) + return BadLength; + + buf = *buf_return; + + if (!buf && !(*nelem_return)) + { + buf = xcalloc(val->size, sizeof(float)); + if (!buf) + return BadAlloc; + *buf_return = buf; + *nelem_return = val->size; + } else if (val->size < *nelem_return) + *nelem_return = val->size; + + for (i = 0; i < val->size && i < *nelem_return; i++) + buf[i] = ((float*)val->data)[i]; + + return Success; +} + /** * Init those properties that are allocated by the server and most likely used * by the DIX or the DDX. diff --git a/configure.ac b/configure.ac index a74414d60..767ac94a8 100644 --- a/configure.ac +++ b/configure.ac @@ -921,6 +921,10 @@ if test "x$XSELINUX" = xyes; then AC_CHECK_LIB(selinux, avc_init, [], AC_MSG_ERROR([SELinux library not found])) AC_CHECK_HEADERS([libaudit.h], [], AC_MSG_ERROR([SELinux extension requires audit system headers])) AC_CHECK_LIB(audit, audit_open, [], AC_MSG_ERROR([SELinux extension requires audit system library])) + AC_CHECK_DECL(avc_netlink_acquire_fd, + [AC_DEFINE(HAVE_AVC_NETLINK_ACQUIRE_FD, 1, "Have avc_netlink_acquire_fd")], + [], + [#include ]) AC_DEFINE(XSELINUX, 1, [Build SELinux extension]) SELINUX_LIB="-lselinux -laudit" fi diff --git a/hw/xfree86/modes/xf86Crtc.c b/hw/xfree86/modes/xf86Crtc.c index f09b9b895..1c2ee499e 100644 --- a/hw/xfree86/modes/xf86Crtc.c +++ b/hw/xfree86/modes/xf86Crtc.c @@ -2061,9 +2061,9 @@ xf86TargetPreferred(ScrnInfoPtr scrn, xf86CrtcConfigPtr config, (float)config->output[p]->mm_height; if (aspect) - preferred_match[0] = bestModeForAspect(config, enabled, aspect); + preferred_match[p] = bestModeForAspect(config, enabled, aspect); - if (preferred_match[0]) + if (preferred_match[p]) ret = TRUE; } while (0); diff --git a/include/dix-config.h.in b/include/dix-config.h.in index 2515d8315..db491ed06 100644 --- a/include/dix-config.h.in +++ b/include/dix-config.h.in @@ -434,4 +434,6 @@ #include "dix-config-apple-verbatim.h" #endif +#undef HAVE_AVC_NETLINK_ACQUIRE_FD + #endif /* _DIX_CONFIG_H_ */ diff --git a/include/exevents.h b/include/exevents.h index 7459b5c24..971afc2ea 100644 --- a/include/exevents.h +++ b/include/exevents.h @@ -251,4 +251,16 @@ extern Atom XIGetKnownProperty( extern DeviceIntPtr XIGetDevice(xEvent *ev); +extern _X_EXPORT int XIPropToInt( + XIPropertyValuePtr val, + int *nelem_return, + int **buf_return +); + +extern _X_EXPORT int XIPropToFloat( + XIPropertyValuePtr val, + int *nelem_return, + float **buf_return +); + #endif /* EXEVENTS_H */ diff --git a/include/xserver-properties.h b/include/xserver-properties.h index 4d602b5ab..f8aeab65d 100644 --- a/include/xserver-properties.h +++ b/include/xserver-properties.h @@ -26,6 +26,10 @@ #ifndef _XSERVER_PROPERTIES_H_ #define _XSERVER_PROPERTIES_H_ +/* Type for a 4 byte float. Storage format IEEE 754 in client's default + * byte-ordering. */ +#define XATOM_FLOAT "FLOAT" + /* BOOL. 0 - device disabled, 1 - device enabled */ #define XI_PROP_ENABLED "Device Enabled" diff --git a/xkb/xkbUtils.c b/xkb/xkbUtils.c index aafc1ab0a..71b0f6661 100644 --- a/xkb/xkbUtils.c +++ b/xkb/xkbUtils.c @@ -2016,9 +2016,9 @@ _XkbCopyGeom(XkbDescPtr src, XkbDescPtr dst) strcpy(dst->geom->label_font, src->geom->label_font); i = XkbGeomColorIndex(src->geom, src->geom->label_color); - dst->geom->label_color = &(src->geom->colors[i]); + dst->geom->label_color = &(dst->geom->colors[i]); i = XkbGeomColorIndex(src->geom, src->geom->base_color); - dst->geom->base_color = &(src->geom->colors[i]); + dst->geom->base_color = &(dst->geom->colors[i]); } else { if (dst->geom->label_font) {