Sun bug 6589829: include zoneid of shm segment in access policy for MIT-SHM
<http://bugs.opensolaris.org/bugdatabase/view_bug.do?bug_id=6589829> <http://www.opensolaris.org/os/community/arc/caselog/2007/500/>
This commit is contained in:
parent
49c8285e38
commit
fdef7be5c8
98
Xext/shm.c
98
Xext/shm.c
|
@ -62,6 +62,33 @@ in this Software without prior written authorization from The Open Group.
|
||||||
#include <X11/extensions/shmstr.h>
|
#include <X11/extensions/shmstr.h>
|
||||||
#include <X11/Xfuncproto.h>
|
#include <X11/Xfuncproto.h>
|
||||||
|
|
||||||
|
/* Needed for Solaris cross-zone shared memory extension */
|
||||||
|
#ifdef HAVE_SHMCTL64
|
||||||
|
#include <sys/ipc_impl.h>
|
||||||
|
#define SHMSTAT(id, buf) shmctl64(id, IPC_STAT64, buf)
|
||||||
|
#define SHMSTAT_TYPE struct shmid_ds64
|
||||||
|
#define SHMPERM_TYPE struct ipc_perm64
|
||||||
|
#define SHM_PERM(buf) buf.shmx_perm
|
||||||
|
#define SHM_SEGSZ(buf) buf.shmx_segsz
|
||||||
|
#define SHMPERM_UID(p) p->ipcx_uid
|
||||||
|
#define SHMPERM_CUID(p) p->ipcx_cuid
|
||||||
|
#define SHMPERM_GID(p) p->ipcx_gid
|
||||||
|
#define SHMPERM_CGID(p) p->ipcx_cgid
|
||||||
|
#define SHMPERM_MODE(p) p->ipcx_mode
|
||||||
|
#define SHMPERM_ZONEID(p) p->ipcx_zoneid
|
||||||
|
#else
|
||||||
|
#define SHMSTAT(id, buf) shmctl(id, IPC_STAT, buf)
|
||||||
|
#define SHMSTAT_TYPE struct shmid_ds
|
||||||
|
#define SHMPERM_TYPE struct ipc_perm
|
||||||
|
#define SHM_PERM(buf) buf.shm_perm
|
||||||
|
#define SHM_SEGSZ(buf) buf.shm_segsz
|
||||||
|
#define SHMPERM_UID(p) p->uid
|
||||||
|
#define SHMPERM_CUID(p) p->cuid
|
||||||
|
#define SHMPERM_GID(p) p->gid
|
||||||
|
#define SHMPERM_CGID(p) p->cgid
|
||||||
|
#define SHMPERM_MODE(p) p->mode
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef PANORAMIX
|
#ifdef PANORAMIX
|
||||||
#include "panoramiX.h"
|
#include "panoramiX.h"
|
||||||
#include "panoramiXsrv.h"
|
#include "panoramiXsrv.h"
|
||||||
|
@ -348,32 +375,57 @@ ProcShmQueryVersion(client)
|
||||||
* using the credentials from the client if available
|
* using the credentials from the client if available
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
shm_access(ClientPtr client, struct ipc_perm *perm, int readonly)
|
shm_access(ClientPtr client, SHMPERM_TYPE *perm, int readonly)
|
||||||
{
|
{
|
||||||
int uid, gid;
|
int uid, gid;
|
||||||
mode_t mask;
|
mode_t mask;
|
||||||
|
int uidset = 0, gidset = 0;
|
||||||
|
LocalClientCredRec *lcc;
|
||||||
|
|
||||||
if (LocalClientCred(client, &uid, &gid) != -1) {
|
if (GetLocalClientCreds(client, &lcc) != -1) {
|
||||||
|
|
||||||
/* User id 0 always gets access */
|
if (lcc->fieldsSet & LCC_UID_SET) {
|
||||||
if (uid == 0) {
|
uid = lcc->euid;
|
||||||
return 0;
|
uidset = 1;
|
||||||
}
|
}
|
||||||
/* Check the owner */
|
if (lcc->fieldsSet & LCC_GID_SET) {
|
||||||
if (perm->uid == uid || perm->cuid == uid) {
|
gid = lcc->egid;
|
||||||
mask = S_IRUSR;
|
gidset = 1;
|
||||||
if (!readonly) {
|
|
||||||
mask |= S_IWUSR;
|
|
||||||
}
|
|
||||||
return (perm->mode & mask) == mask ? 0 : -1;
|
|
||||||
}
|
}
|
||||||
/* Check the group */
|
|
||||||
if (perm->gid == gid || perm->cgid == gid) {
|
#if defined(HAVE_GETZONEID) && defined(SHMPERM_ZONEID)
|
||||||
mask = S_IRGRP;
|
if ( ((lcc->fieldsSet & LCC_ZID_SET) == 0) || (lcc->zoneid == -1)
|
||||||
if (!readonly) {
|
|| (lcc->zoneid != SHMPERM_ZONEID(perm))) {
|
||||||
mask |= S_IWGRP;
|
uidset = 0;
|
||||||
|
gidset = 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
FreeLocalClientCreds(lcc);
|
||||||
|
|
||||||
|
if (uidset) {
|
||||||
|
/* User id 0 always gets access */
|
||||||
|
if (uid == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/* Check the owner */
|
||||||
|
if (SHMPERM_UID(perm) == uid || SHMPERM_CUID(perm) == uid) {
|
||||||
|
mask = S_IRUSR;
|
||||||
|
if (!readonly) {
|
||||||
|
mask |= S_IWUSR;
|
||||||
|
}
|
||||||
|
return (SHMPERM_MODE(perm) & mask) == mask ? 0 : -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gidset) {
|
||||||
|
/* Check the group */
|
||||||
|
if (SHMPERM_GID(perm) == gid || SHMPERM_CGID(perm) == gid) {
|
||||||
|
mask = S_IRGRP;
|
||||||
|
if (!readonly) {
|
||||||
|
mask |= S_IWGRP;
|
||||||
|
}
|
||||||
|
return (SHMPERM_MODE(perm) & mask) == mask ? 0 : -1;
|
||||||
}
|
}
|
||||||
return (perm->mode & mask) == mask ? 0 : -1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Otherwise, check everyone else */
|
/* Otherwise, check everyone else */
|
||||||
|
@ -381,14 +433,14 @@ shm_access(ClientPtr client, struct ipc_perm *perm, int readonly)
|
||||||
if (!readonly) {
|
if (!readonly) {
|
||||||
mask |= S_IWOTH;
|
mask |= S_IWOTH;
|
||||||
}
|
}
|
||||||
return (perm->mode & mask) == mask ? 0 : -1;
|
return (SHMPERM_MODE(perm) & mask) == mask ? 0 : -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
ProcShmAttach(client)
|
ProcShmAttach(client)
|
||||||
register ClientPtr client;
|
register ClientPtr client;
|
||||||
{
|
{
|
||||||
struct shmid_ds buf;
|
SHMSTAT_TYPE buf;
|
||||||
ShmDescPtr shmdesc;
|
ShmDescPtr shmdesc;
|
||||||
REQUEST(xShmAttachReq);
|
REQUEST(xShmAttachReq);
|
||||||
|
|
||||||
|
@ -417,7 +469,7 @@ ProcShmAttach(client)
|
||||||
shmdesc->addr = shmat(stuff->shmid, 0,
|
shmdesc->addr = shmat(stuff->shmid, 0,
|
||||||
stuff->readOnly ? SHM_RDONLY : 0);
|
stuff->readOnly ? SHM_RDONLY : 0);
|
||||||
if ((shmdesc->addr == ((char *)-1)) ||
|
if ((shmdesc->addr == ((char *)-1)) ||
|
||||||
shmctl(stuff->shmid, IPC_STAT, &buf))
|
SHMSTAT(stuff->shmid, &buf))
|
||||||
{
|
{
|
||||||
xfree(shmdesc);
|
xfree(shmdesc);
|
||||||
return BadAccess;
|
return BadAccess;
|
||||||
|
@ -427,7 +479,7 @@ ProcShmAttach(client)
|
||||||
* do manual checking of access rights for the credentials
|
* do manual checking of access rights for the credentials
|
||||||
* of the client */
|
* of the client */
|
||||||
|
|
||||||
if (shm_access(client, &(buf.shm_perm), stuff->readOnly) == -1) {
|
if (shm_access(client, &(SHM_PERM(buf)), stuff->readOnly) == -1) {
|
||||||
shmdt(shmdesc->addr);
|
shmdt(shmdesc->addr);
|
||||||
xfree(shmdesc);
|
xfree(shmdesc);
|
||||||
return BadAccess;
|
return BadAccess;
|
||||||
|
@ -436,7 +488,7 @@ ProcShmAttach(client)
|
||||||
shmdesc->shmid = stuff->shmid;
|
shmdesc->shmid = stuff->shmid;
|
||||||
shmdesc->refcnt = 1;
|
shmdesc->refcnt = 1;
|
||||||
shmdesc->writable = !stuff->readOnly;
|
shmdesc->writable = !stuff->readOnly;
|
||||||
shmdesc->size = buf.shm_segsz;
|
shmdesc->size = SHM_SEGSZ(buf);
|
||||||
shmdesc->next = Shmsegs;
|
shmdesc->next = Shmsegs;
|
||||||
Shmsegs = shmdesc;
|
Shmsegs = shmdesc;
|
||||||
}
|
}
|
||||||
|
|
|
@ -179,7 +179,7 @@ dnl Checks for library functions.
|
||||||
AC_FUNC_VPRINTF
|
AC_FUNC_VPRINTF
|
||||||
AC_CHECK_FUNCS([geteuid getuid link memmove memset mkstemp strchr strrchr \
|
AC_CHECK_FUNCS([geteuid getuid link memmove memset mkstemp strchr strrchr \
|
||||||
strtol getopt getopt_long vsnprintf walkcontext backtrace \
|
strtol getopt getopt_long vsnprintf walkcontext backtrace \
|
||||||
getisax getzoneid])
|
getisax getzoneid shmctl64])
|
||||||
AC_FUNC_ALLOCA
|
AC_FUNC_ALLOCA
|
||||||
dnl Old HAS_* names used in os/*.c.
|
dnl Old HAS_* names used in os/*.c.
|
||||||
AC_CHECK_FUNC([getdtablesize],
|
AC_CHECK_FUNC([getdtablesize],
|
||||||
|
|
|
@ -184,6 +184,9 @@
|
||||||
/* Define to 1 if you have the <rpcsvc/dbm.h> header file. */
|
/* Define to 1 if you have the <rpcsvc/dbm.h> header file. */
|
||||||
#undef HAVE_RPCSVC_DBM_H
|
#undef HAVE_RPCSVC_DBM_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `shmctl64' function. */
|
||||||
|
#undef HAVE_SHMCTL64
|
||||||
|
|
||||||
/* Define to 1 if you have the <stdint.h> header file. */
|
/* Define to 1 if you have the <stdint.h> header file. */
|
||||||
#undef HAVE_STDINT_H
|
#undef HAVE_STDINT_H
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue