Mercurial > illumos > illumos-gate
changeset 12326:7a0184667fca
6946518 There is no way to validate that audit flags are valid
6946529 getauditflagschar and getauclassnam may not operate properly with maximum size class names
6927607 getauditflags.c:getauditflagsbin() needs boundary checking.
author | gww <gww@eng.sun.com> |
---|---|
date | Thu, 06 May 2010 16:36:08 -0700 |
parents | 8a132ae95aa2 |
children | 4256c66fb5bf |
files | usr/src/lib/libbsm/common/audit_class.c usr/src/lib/libbsm/common/getauditflags.c usr/src/lib/libbsm/common/libbsm.h usr/src/lib/libbsm/common/mapfile-vers |
diffstat | 4 files changed, 153 insertions(+), 147 deletions(-) [+] |
line wrap: on
line diff
--- a/usr/src/lib/libbsm/common/audit_class.c Thu May 06 19:01:43 2010 -0400 +++ b/usr/src/lib/libbsm/common/audit_class.c Thu May 06 16:36:08 2010 -0700 @@ -20,8 +20,7 @@ */ /* - * Copyright 2010 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright (c) 1992, 2010, Oracle and/or its affiliates. All rights reserved. */ /* @@ -183,7 +182,7 @@ getauclassnam_r(au_class_ent_t *e, char *name) { while (getauclassent_r(e) != NULL) { - if (strcmp(e->ac_name, name) == 0) { + if (strncmp(e->ac_name, name, AU_CLASS_NAME_MAX) == 0) { return (e); } } @@ -287,7 +286,8 @@ *result = class_tbl[invalid]; if (flags & AU_CACHE_NAME) { for (i = 0; i < lines; i++) { - if (strcmp(class_name, class_tbl[i]->ac_name) == 0) { + if (strncmp(class_name, class_tbl[i]->ac_name, + AU_CLASS_NAME_MAX) == 0) { *result = class_tbl[i]; hit = 1; break;
--- a/usr/src/lib/libbsm/common/getauditflags.c Thu May 06 19:01:43 2010 -0400 +++ b/usr/src/lib/libbsm/common/getauditflags.c Thu May 06 16:36:08 2010 -0700 @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,50 +19,46 @@ * CDDL HEADER END */ /* - * Copyright 2003 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright (c) 1992, 2010, Oracle and/or its affiliates. All rights reserved. */ -#pragma ident "%Z%%M% %I% %E% SMI" /* * get audit preselection mask values */ +#include <ctype.h> #include <stdio.h> #include <string.h> -#include <syslog.h> + +#include <sys/errno.h> #include <sys/types.h> #include <bsm/audit.h> #include <bsm/libbsm.h> -#define ON 1 -#define OK 0 -#define OFF -1 -#define COMMA ',' +#include <adt_xlate.h> /* adt_write_syslog */ -#define MAXFLDLEN 25 - -int getauditflagsbin(); +#define SUCCESS 0x1 /* '+' success mask */ +#define FAILURE 0x2 /* '-' failure mask */ +#define INVERSE 0x4 /* '^' invert the mask */ static int -match_class(s, prefix, m, v) -char *s; -char *prefix; -unsigned int m; -int v; +match_class(char *s, char *prefix, uint_t m, int v) { au_class_ent_t *p_class; (void) strcat(s, prefix); if (cacheauclass(&p_class, m) == 1) { - (void) strcat(s, v ? p_class->ac_desc : p_class->ac_name); + if (v == 0) { + (void) strncat(s, p_class->ac_name, AU_CLASS_NAME_MAX); + } else { + (void) strncat(s, p_class->ac_desc, AU_CLASS_DESC_MAX); + } (void) strcat(s, ","); return (0); } return (-1); } - /* * getauditflagschar() - convert bit flag to character string * @@ -78,10 +73,7 @@ */ int -getauditflagschar(auditstring, masks, verbose) -char *auditstring; -au_mask_t *masks; -int verbose; +getauditflagschar(char *auditstring, au_mask_t *masks, int verbose) { char *prefix; /* +, -, or null */ unsigned int m; /* for masking with masks */ @@ -98,7 +90,7 @@ return (-1); /* kludge to get rid of trailing comma */ l = strlen(auditstring) - 1; - if (auditstring[l] == COMMA) + if (auditstring[l] == ',') auditstring[l] = '\0'; return (0); } @@ -125,140 +117,153 @@ prefix = "+"; else if (m & masks->am_failure) prefix = "-"; - else + else continue; if (match_class(auditstring, prefix, m, verbose) != 0) return (-1); } - if (*(prefix = auditstring + strlen(auditstring) - 1) == COMMA) + if (*(prefix = auditstring + strlen(auditstring) - 1) == ',') *prefix = '\0'; return (0); } /* + * Audit flags: + * + * [+ | - | ^ | ^+ | ^-]<classname>{,[+ | - | ^ | ^+ | ^-]<classname>}* + * + * <classname>, add class mask to success and failure mask. + * +<classname>, add class mask only to success mask. + * -<classname>, add class mask only to failure mask. + * ^<classname>, remove class mask from success and failure mask. + * ^+<classname>, remove class mask from success mask. + * ^-<classname>, remove class mask from failure mask. + */ + +/* + * __chkflags - check if the audit flags are valid for this system + * + * Entry flags = audit flags string. + * cont = B_TRUE, continue parsing even if error. + * B_FALSE, return failure on error. + * + * Exit mask = audit mask as defined by flags. + * + * Return B_TRUE if no errors, or continue == B_TRUE. + * B_FALSE and if error != NULL, flags in error. + */ + +boolean_t +__chkflags(char *flags, au_mask_t *mask, boolean_t cont, char **error) +{ + uint32_t prefix; + au_class_ent_t *class; + char name[AU_CLASS_NAME_MAX+1]; + int i; + + if (flags == NULL || mask == NULL) { + return (B_FALSE); + } + + mask->am_success = 0; + mask->am_failure = 0; + + while (*flags != '\0') { + prefix = (SUCCESS | FAILURE); + + /* skip white space */ + while (isspace(*flags)) { + flags++; + } + + if (flags == '\0') { + break; + } + if (error != NULL) { + /* save error pointer */ + *error = flags; + } + + /* get the prefix */ + if (*flags == '+') { + flags++; + prefix ^= FAILURE; + } else if (*flags == '-') { + flags++; + prefix ^= SUCCESS; + } else if (*flags == '^') { + flags++; + prefix |= INVERSE; + if (*flags == '+') { + flags++; + prefix ^= FAILURE; + } else if (*flags == '-') { + flags++; + prefix ^= SUCCESS; + } + } + + /* get class name */ + + for (i = 0; (i < sizeof (name) - 1) && + !(*flags == '\0' || *flags == ','); i++) { + name[i] = *flags++; + } + name[i++] = '\0'; + if (*flags == ',') { + /* skip comma (',') */ + flags++; + } + if (cacheauclassnam(&class, name) != 1) { + if (!cont) { + return (B_FALSE); + } else { + char msg[512]; + + (void) snprintf(msg, sizeof (msg), "invalid " + "audit flag %s", name); + adt_write_syslog(msg, EINVAL); + } + } else { + /* add class mask */ + + if ((prefix & (INVERSE | SUCCESS)) == SUCCESS) { + mask->am_success |= class->ac_class; + } else if ((prefix & (INVERSE | SUCCESS)) == + (INVERSE | SUCCESS)) { + mask->am_success &= ~(class->ac_class); + } + if ((prefix & (INVERSE | FAILURE)) == FAILURE) { + mask->am_failure |= class->ac_class; + } else if ((prefix & (INVERSE | FAILURE)) == + (INVERSE | FAILURE)) { + mask->am_failure &= ~(class->ac_class); + } + } + } + + return (B_TRUE); +} + +/* * getauditflagsbin() - converts character string to success and * failure bit masks * * input: auditstring - audit string - * cnt - number of elements in the masks array * * output: masks->am_success - audit on success * masks->am_failure - audit on failure * * returns: 0 - ok - * -1 - error - string contains characters which do - * not match event flag names or invalid pointers - * passed in. + * -1 - error - string or mask NULL. */ int -getauditflagsbin(auditstring, masks) -char *auditstring; -au_mask_t *masks; +getauditflagsbin(char *auditstring, au_mask_t *masks) { - int gotone, done = 0, invert = 0, tryagain; - int retstat = 0, succ_event, fail_event; - char *ptr, tmp_buff[MAXFLDLEN]; - au_class_ent_t *p_class; - - if ((masks == NULL) || (auditstring == NULL)) - return (-1); - - masks->am_success = masks->am_failure = 0; - - /* process character string */ - do { - gotone = 0; - /* read through string storing chars. until a comma */ - for (ptr = tmp_buff; !gotone; /* */) { - if (*auditstring != COMMA && *auditstring != '\0' && - *auditstring != '\n' && *auditstring != ' ' && - *auditstring != '\t') - *ptr++ = *auditstring++; - else if (*auditstring == ' ' || *auditstring == '\t') - auditstring++; - else { - if (*auditstring == '\0' || - *auditstring == '\n') { - done = 1; - if (ptr == tmp_buff) - done = 2; - } - gotone = 1; - } - } - /* * process audit state */ - if (gotone && done != 2) { - if (!done) - auditstring++; - *ptr++ = '\0'; - ptr = tmp_buff; - gotone = 0; - succ_event = ON; - fail_event = ON; - tryagain = 1; - invert = 0; - - /* get flags */ - do { - switch (*ptr++) { - case '^': - invert = 1; - succ_event = OFF; - fail_event = OFF; - break; - case '+': - if (invert) - fail_event = OK; - else { - succ_event = ON; - fail_event = OK; - } - break; - case '-': - if (invert) - succ_event = OK; - else { - fail_event = ON; - succ_event = OK; - } - break; - default: - tryagain = 0; - ptr--; - break; - } - } while (tryagain); - - /* add audit state to mask */ - - - if (cacheauclassnam(&p_class, ptr) == 1) { - if (succ_event == ON) - masks->am_success |= p_class->ac_class; - else if (succ_event == OFF) - masks->am_success &= - ~(p_class->ac_class); - if (fail_event == ON) - masks->am_failure |= p_class->ac_class; - else if (fail_event == OFF) - masks->am_failure &= - ~(p_class->ac_class); - gotone = 1; - } else { /* Bug 4330887 */ - syslog(LOG_CRIT, - "auditflags have invalid flag %s", - ptr); - continue; - } - if (!gotone) { - retstat = -1; - done = 1; - } - } - } while (!done); - - - return (retstat); + if (__chkflags(auditstring, masks, B_TRUE, NULL)) { + return (0); + } + return (-1); }
--- a/usr/src/lib/libbsm/common/libbsm.h Thu May 06 19:01:43 2010 -0400 +++ b/usr/src/lib/libbsm/common/libbsm.h Thu May 06 16:36:08 2010 -0700 @@ -19,14 +19,14 @@ * CDDL HEADER END */ /* - * Copyright 2010 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright (c) 1992, 2010, Oracle and/or its affiliates. All rights reserved. */ #ifndef _BSM_LIBBSM_H #define _BSM_LIBBSM_H +#include <ctype.h> #include <secdb.h> #include <stdio.h> #include <errno.h> @@ -223,6 +223,7 @@ extern int getauditflagsbin(char *, au_mask_t *); extern int getauditflagschar(char *, au_mask_t *, int); extern int getfauditflags(au_mask_t *, au_mask_t *, au_mask_t *); +extern boolean_t __chkflags(char *, au_mask_t *, boolean_t, char **); /* * Functions that do system calls
--- a/usr/src/lib/libbsm/common/mapfile-vers Thu May 06 19:01:43 2010 -0400 +++ b/usr/src/lib/libbsm/common/mapfile-vers Thu May 06 16:36:08 2010 -0700 @@ -19,8 +19,7 @@ # CDDL HEADER END # # -# Copyright 2010 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. +# Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. # # @@ -291,6 +290,7 @@ cacheauclassnam; cacheauevent; cannot_audit; + __chkflags; da_add_list; da_check_logindevperm; da_is_on;