From owner-trustedbsd-cvs@FreeBSD.ORG Thu Oct 12 19:49:36 2006 Return-Path: X-Original-To: trustedbsd-cvs@freebsd.org Delivered-To: trustedbsd-cvs@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id B4F7F16A47E for ; Thu, 12 Oct 2006 19:49:36 +0000 (UTC) (envelope-from owner-perforce@freebsd.org) Received: from cyrus.watson.org (cyrus.watson.org [209.31.154.42]) by mx1.FreeBSD.org (Postfix) with ESMTP id 29C3143D46 for ; Thu, 12 Oct 2006 19:49:29 +0000 (GMT) (envelope-from owner-perforce@freebsd.org) Received: from mx2.freebsd.org (mx2.freebsd.org [216.136.204.119]) by cyrus.watson.org (Postfix) with ESMTP id 8E63F46CD9 for ; Thu, 12 Oct 2006 15:49:28 -0400 (EDT) Received: from hub.freebsd.org (hub.freebsd.org [216.136.204.18]) by mx2.freebsd.org (Postfix) with ESMTP id 313E957383; Thu, 12 Oct 2006 19:49:26 +0000 (GMT) (envelope-from owner-perforce@freebsd.org) Received: by hub.freebsd.org (Postfix, from userid 32767) id 1E9F216A416; Thu, 12 Oct 2006 19:49:26 +0000 (UTC) X-Original-To: perforce@freebsd.org Delivered-To: perforce@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id D725916A407 for ; Thu, 12 Oct 2006 19:49:25 +0000 (UTC) (envelope-from millert@freebsd.org) Received: from repoman.freebsd.org (repoman.freebsd.org [216.136.204.115]) by mx1.FreeBSD.org (Postfix) with ESMTP id 735BF43D45 for ; Thu, 12 Oct 2006 19:49:25 +0000 (GMT) (envelope-from millert@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.13.6/8.13.6) with ESMTP id k9CJnPVJ077387 for ; Thu, 12 Oct 2006 19:49:25 GMT (envelope-from millert@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.13.6/8.13.4/Submit) id k9CJnO8P077381 for perforce@freebsd.org; Thu, 12 Oct 2006 19:49:24 GMT (envelope-from millert@freebsd.org) Date: Thu, 12 Oct 2006 19:49:24 GMT Message-Id: <200610121949.k9CJnO8P077381@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to millert@freebsd.org using -f From: Todd Miller To: Perforce Change Reviews Cc: Subject: PERFORCE change 107775 for review X-BeenThere: trustedbsd-cvs@FreeBSD.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: TrustedBSD CVS and Perforce commit message list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 12 Oct 2006 19:49:36 -0000 http://perforce.freebsd.org/chv.cgi?CH=107775 Change 107775 by millert@millert_macbook on 2006/10/12 19:48:49 Validate migscs input so we don't crash from corrupt data. Change how the message id to class (migscs) data is stored so we can free it properly when reloading. We now store the array of msgids associated with for each class in the classinfo struct itself. This means that to free the classinfo structs we just apply a function to each datum and free the datum when a reference count hits zero. Affected files ... .. //depot/projects/trustedbsd/sedarwin8/policies/sedarwin/sedarwin/ss/mach_av.c#4 edit Differences ... ==== //depot/projects/trustedbsd/sedarwin8/policies/sedarwin/sedarwin/ss/mach_av.c#4 (text+ko) ==== @@ -46,7 +46,8 @@ struct msgid_classinfo { - int baseid; + int nmsgids; + int *msgids; int nclasses; int classes[0]; /* actually larger */ }; @@ -55,6 +56,16 @@ lck_mtx_t *migscs_load_lock; +static int +msgid_destroy(void *key, void *datum, void *arg) +{ + struct msgid_classinfo *cinfo = datum; + + if (--cinfo->nmsgids == 0) + sebsd_free(cinfo, M_SEBSD); + return (0); +} + /* * Read the table mapping mach message ids to security classes. * The permissions in those classes are expected to be relative to the @@ -63,53 +74,72 @@ int sebsd_load_migscs(void *tdata, size_t tsize) { + struct msgid_classinfo *cinfo; struct hashtab *ht, *oht; - int error, *p, *ep; + int error, entries, i, msgid, nclasses, size; + int *p, *ep; ht = hashtab_create(msgid_hash, msgid_cmp, 31337); if (ht == NULL) return (-1); - printf("security class to subsystem table: %d classes\n", - tsize / sizeof(int)); - + error = 0; p = (int *)tdata; ep = (int *)((char *)tdata + tsize); - while (p < ep) { - int msgid = *p++; - int nclasses = *p++; - int size = *p++; - int i; - struct msgid_classinfo *c; + for (entries = 0; p < ep; entries++) { + if (p + 3 > ep) + goto bad; + msgid = *p++; + nclasses = *p++; + size = *p++; + if (msgid <= 0 || nclasses <= 0 || size <= 0 || + p + nclasses > ep) + goto bad; - c = sebsd_malloc(sizeof(int) * nclasses + sizeof(*c), M_SEBSD, - M_WAITOK); - c->baseid = msgid; - c->nclasses = nclasses; + /* + * We store the key in the data object it references + * so we can free things up with a map operation later. + */ + cinfo = sebsd_malloc(sizeof(*cinfo) + + (nclasses + size) * sizeof(int), M_SEBSD, M_WAITOK); + cinfo->nclasses = nclasses; for (i = 0; i < nclasses; i++) - c->classes[i] = *p++; - for (i = msgid; i < msgid + size; i++) { - int *ip = sebsd_malloc(sizeof(int), M_SEBSD, M_WAITOK); - *ip = i; - error = hashtab_insert(ht, ip, c); - if (error) { - hashtab_destroy(ht); - return (-1); - } + cinfo->classes[i] = *p++; + + cinfo->nmsgids = size; + cinfo->msgids = &cinfo->classes[nclasses]; + for (i = 0; i < size; i++) { + cinfo->msgids[i] = msgid + i; + error = hashtab_insert(ht, &cinfo->msgids[i], cinfo); + if (error) + goto bad; } } + printf("security class to subsystem table: %d classes\n", entries); + /* * Swap the old message id to class mapping with the new one * and free the old. - * XXX - does this leak memory? */ + /* XXX - need rwlock for msgid2class */ lck_mtx_lock(migscs_load_lock); oht = msgid2class; msgid2class = ht; lck_mtx_unlock(migscs_load_lock); - hashtab_destroy(oht); + if (oht != NULL) { + hashtab_map(oht, msgid_destroy, NULL); + hashtab_destroy(oht); + } return (0); +bad: + if (error) + printf("%s: hashtab_insert() error %d\n", __func__, error); + else + printf("%s: migscs data corrupted, ignoring\n", __func__); + hashtab_map(ht, msgid_destroy, NULL); + hashtab_destroy(ht); + return (-1); } void @@ -118,7 +148,6 @@ size_t tsize; void *tdata; - /* XXX - should also lookup & store migscs_path */ if (sebsd_find_data("migscs_data", &tdata, &tsize) != 0 || sebsd_load_migscs(tdata, tsize) != 0) msgid2class = hashtab_create(msgid_hash, msgid_cmp, 3); @@ -137,11 +166,12 @@ * Instead, we probably should make a check against a * new permission to be added to mach_port for this purpose. */ + /* XXX - need rwlock for msgid2class */ mcl = hashtab_search(msgid2class, &msgid); if (mcl == NULL) return 0; - cl = (msgid - mcl->baseid) / (8 * sizeof(u32)); + cl = (msgid - mcl->msgids[0]) / (8 * sizeof(u32)); if (cl >= mcl->nclasses) { /* bad message */ if (selinux_enforcing) @@ -150,6 +180,6 @@ return (0); } - perms = (u32)1 << (msgid - mcl->baseid - (cl * 8 * sizeof(u32))); + perms = (u32)1 << (msgid - mcl->msgids[0] - (cl * 8 * sizeof(u32))); return avc_has_perm(subj, obj, mcl->classes[cl], perms, NULL); }