#include "debug.h"
+/*@access regex_t @*/
+
/*@unchecked@*/
int _rpmsx_debug = 0;
case '{':
sxp->hasMetaChars = 1;
return;
- break;
+ /*@notreached@*/ /*@switchbreak@*/ break;
case '\\': /* skip the next character */
s++;
- break;
+ /*@switchbreak@*/ break;
default:
- break;
+ /*@switchbreak@*/ break;
}
s++;
static size_t rpmsxsPStem(const char * const buf)
/*@*/
{
+ /*@observer@*/
static const char * const regex_chars = ".^$?*+|[({";
const char * tmp = strchr(buf + 1, '/');
const char * ind;
}
sxs = sx->sxs + sx->nsxs;
sxs->len = stem_len;
- sxs->stem = strndup(*bpp, stem_len);
+/*@i@*/ sxs->stem = strndup(*bpp, stem_len);
sx->nsxs++;
*bpp += stem_len;
return sx->nsxs - 1;
sxs = sx->sxs + i;
if (stem_len != sxs->len)
continue;
- if (strncmp(*bpp, sxs->stem, stem_len))
+/*@i@*/ if (strncmp(*bpp, sxs->stem, stem_len))
continue;
*bpp += stem_len;
return i;
sxp->pattern = _free(sxp->pattern);
sxp->type = _free(sxp->type);
sxp->context = _free(sxp->context);
- regfree(sxp->preg);
- sxp->preg = _free(sxp->preg);
+/*@i@*/ regfree(sxp->preg);
+/*@i@*/ sxp->preg = _free(sxp->preg);
}
sx->sxp = _free(sx->sxp);
(void) rpmsxUnlink(sx, __func__);
/*@-refcounttrans -usereleased@*/
-/*@-bounsxwrite@*/
+/*@-boundswrite@*/
memset(sx, 0, sizeof(*sx)); /* XXX trash and burn */
-/*@=bounsxwrite@*/
+/*@=boundswrite@*/
sx = _free(sx);
/*@=refcounttrans =usereleased@*/
return NULL;
/* Check if same RE string */
if (strcmp(sxpj->pattern, sxpi->pattern))
- continue;
+ /*@innercontinue@*/ continue;
if (sxpj->fmode && sxpi->fmode && sxpj->fmode != sxpi->fmode)
- continue;
+ /*@innercontinue@*/ continue;
/* Same RE string found */
if (strcmp(sxpj->context, sxpi->context)) {
/* If different contexts, give warning */
+/*@-modfilesys@*/
fprintf(stderr,
"ERROR: Multiple different specifications for %s (%s and %s).\n",
sxpi->pattern, sxpj->context, sxpi->context);
+/*@=modfilesys@*/
rc = -1;
} else {
/* If same contexts give warning */
+/*@-modfilesys@*/
fprintf(stderr,
"WARNING: Multiple same specifications for %s.\n",
sxpi->pattern);
+/*@=modfilesys@*/
}
}
}
return rc;
}
-static int nerr;
-#define inc_err() nerr++
-
int rpmsxParse(rpmsx sx, const char * fn)
{
FILE * fp;
int lineno;
int pass;
int regerr;
+ int nerr = 0;
+#define inc_err() nerr++
+/*@-branchstate@*/
if (fn == NULL)
fn = "/etc/security/selinux/src/policy/file_contexts/file_contexts";
+/*@=branchstate@*/
if ((fp = fopen(fn, "r")) == NULL) {
perror(fn);
return -1;
}
- nerr = 0;
-
/*
* Perform two passes over the specification file.
* The first pass counts the number of specifications and
* The second pass performs detailed validation of the input
* and fills in the spec array.
*/
+/*@-branchstate@*/
for (pass = 0; pass < 2; pass++) {
rpmsxp sxp;
_("%s: no newline on line number %d (only read %s)\n"),
fn, lineno, buf);
inc_err();
- continue;
+ /*@innercontinue@*/ continue;
}
buf[len - 1] = 0;
bp = buf;
bp++;
/* Skip comment lines and empty lines. */
if (*bp == '#' || *bp == 0)
- continue;
+ /*@innercontinue@*/ continue;
+/*@-formatcode@*/
items = sscanf(buf, "%as %as %as", ®ex, &type, &context);
+/*@=formatcode@*/
if (items < 2) {
fprintf(stderr,
_("%s: line number %d is missing fields (only read %s)\n"),
inc_err();
if (items == 1)
free(regex);
- continue;
+ /*@innercontinue@*/ continue;
} else if (items == 2) {
/* The type field is optional. */
free(context);
sprintf(anchored_regex, "^%s$", reg_buf);
/* Compile the regular expression. */
- sxp->preg = xcalloc(1, sizeof(*sxp->preg));
+/*@i@*/ sxp->preg = xcalloc(1, sizeof(*sxp->preg));
regerr = regcomp(sxp->preg, anchored_regex,
REG_EXTENDED | REG_NOSUB);
if (regerr < 0) {
- regerror(regerr, sxp->preg, errbuf, sizeof errbuf);
+ (void) regerror(regerr, sxp->preg, errbuf, sizeof errbuf);
fprintf(stderr,
_("%s: unable to compile regular expression %s on line number %d: %s\n"),
fn, regex, lineno,
goto skip_type;
}
switch (type[1]) {
- case 'b': sxp->fmode = S_IFBLK; break;
- case 'c': sxp->fmode = S_IFCHR; break;
- case 'd': sxp->fmode = S_IFDIR; break;
- case 'p': sxp->fmode = S_IFIFO; break;
- case 'l': sxp->fmode = S_IFLNK; break;
- case 's': sxp->fmode = S_IFSOCK; break;
- case '-': sxp->fmode = S_IFREG; break;
+ case 'b': sxp->fmode = S_IFBLK; /*@switchbreak@*/ break;
+ case 'c': sxp->fmode = S_IFCHR; /*@switchbreak@*/ break;
+ case 'd': sxp->fmode = S_IFDIR; /*@switchbreak@*/ break;
+ case 'p': sxp->fmode = S_IFIFO; /*@switchbreak@*/ break;
+ case 'l': sxp->fmode = S_IFLNK; /*@switchbreak@*/ break;
+/*@i@*/ case 's': sxp->fmode = S_IFSOCK; /*@switchbreak@*/ break;
+ case '-': sxp->fmode = S_IFREG; /*@switchbreak@*/ break;
default:
fprintf(stderr,
_("%s: invalid type specifier %s on line number %d\n"),
fn, type, lineno);
inc_err();
+ /*@switchbreak@*/ break;
}
skip_type:
sx->Count++;
if (pass == 0) {
+/*@-kepttrans@*/
free(regex);
if (type)
free(type);
free(context);
+/*@=kepttrans@*/
}
}
rewind(fp);
}
}
- fclose(fp);
+/*@=branchstate@*/
+ (void) fclose(fp);
/* Sort the specifications with most general first */
rpmsxSort(sx);
{
const char * context = NULL;
const char * myfn = fn;
+/*@-mods@*/
int fstem = rpmsxFind(sx, &myfn);
+/*@=mods@*/
int i;
sx = rpmsxInit(sx, 1);
switch (ret) {
case REG_NOMATCH:
continue;
- /*@notreaached@*/ break;
+ /*@notreached@*/ /*@switchbreak@*/ break;
case 0:
context = rpmsxContext(sx);
- break;
+ /*@switchbreak@*/ break;
default:
{ static char errbuf[255 + 1];
- regerror(ret, preg, errbuf, sizeof errbuf);
+ (void) regerror(ret, preg, errbuf, sizeof errbuf);
+/*@-modfilesys -nullpass @*/
fprintf(stderr, "unable to match %s against %s: %s\n",
fn, rpmsxPattern(sx), errbuf);
- } break;
+/*@=modfilesys =nullpass @*/
+ } /*@switchbreak@*/ break;
}
break;
}
*/
#include <regex.h>
+
#include "selinux.h"
+#if defined(__LCLINT__)
+/*@-incondefs@*/
+extern void freecon(/*@only@*/ security_context_t con)
+ /*@modifies con @*/;
+
+extern int getfilecon(const char *path, /*@out@*/ security_context_t *con)
+ /*@modifies *con @*/;
+extern int lgetfilecon(const char *path, /*@out@*/ security_context_t *con)
+ /*@modifies *con @*/;
+extern int fgetfilecon(int fd, /*@out@*/ security_context_t *con)
+ /*@modifies *con @*/;
+
+extern int setfilecon(const char *path, security_context_t con)
+ /*@globals fileSystem @*/
+ /*@modifies fileSystem @*/;
+extern int lsetfilecon(const char *path, security_context_t con)
+ /*@globals fileSystem @*/
+ /*@modifies fileSystem @*/;
+extern int fsetfilecon(int fd, security_context_t con)
+ /*@globals fileSystem @*/
+ /*@modifies fileSystem @*/;
+
+extern int security_check_context(security_context_t con)
+ /*@globals fileSystem @*/
+ /*@modifies fileSystem @*/;
+/*@=incondefs@*/
+#endif
+
/**
*/
/*@-exportlocal@*/
extern int _rpmsx_nopromote;
/*@=exportlocal@*/
-typedef struct rpmsx_s * rpmsx;
+typedef /*@abstract@*/ /*@refcounted@*/ struct rpmsx_s * rpmsx;
typedef struct rpmsxp_s * rpmsxp;
typedef struct rpmsxs_s * rpmsxs;
* File security context regex pattern.
*/
struct rpmsxp_s {
-/*@only@*/ /*@null@*/
+/*@only@*/ /*@relnull@*/
const char * pattern; /*!< File path regex pattern. */
-/*@only@*/ /*@null@*/
+/*@only@*/ /*@relnull@*/
const char * type; /*!< File type string. */
-/*@only@*/ /*@null@*/
+/*@only@*/ /*@relnull@*/
const char * context; /*!< Security context. */
-/*@only@*/ /*@null@*/
+/*@only@*/ /*@relnull@*/
regex_t * preg; /*!< Compiled regex. */
mode_t fmode; /*!< File type. */
int matches;
* File/pattern stem.
*/
struct rpmsxs_s {
-/*@only@*/ /*@null@*/
+/*@only@*/ /*@relnull@*/
const char * stem;
int len;
};
* File security context patterns container.
*/
struct rpmsx_s {
-/*@only@*/ /*@null@*/
+/*@only@*/ /*@relnull@*/
rpmsxp sxp; /*!< File context patterns. */
int Count; /*!< No. of file context patterns. */
int i; /*!< Current pattern index. */
+/*@only@*/ /*@relnull@*/
rpmsxs sxs; /*!< File stems. */
int nsxs; /*!< No. of file stems. */
int maxsxs; /*!< No. of allocated file stems. */
* @param msg
* @return new security context patterns reference
*/
+/*@-exportlocal@*/
/*@unused@*/ /*@newref@*/ /*@null@*/
rpmsx rpmsxLink (/*@null@*/ rpmsx sx, /*@null@*/ const char * msg)
/*@modifies sx @*/;
rpmsx XrpmsxLink (/*@null@*/ rpmsx sx, /*@null@*/ const char * msg,
const char * fn, unsigned ln)
/*@modifies sx @*/;
+/*@=exportlocal@*/
#define rpmsxLink(_sx, _msg) XrpmsxLink(_sx, _msg, __FILE__, __LINE__)
/**
* @param sx security context patterns
* @return NULL always
*/
+/*@-exportlocal@*/
/*@null@*/
rpmsx rpmsxFree(/*@killref@*/ /*@only@*/ /*@null@*/ rpmsx sx)
/*@modifies sx@*/;
+/*@=exportlocal@*/
/**
* Parse selinux file security context patterns.
* @param fn file name to parse
* @return 0 on success
*/
+/*@-exportlocal@*/
int rpmsxParse(rpmsx sx, /*@null@*/ const char *fn)
- /*modifies sx @*/;
+ /*@globals fileSystem @*/
+ /*@modifies sx, fileSystem @*/;
+/*@=exportlocal@*/
/**
* Create and load security context patterns.
*/
/*@null@*/
rpmsx rpmsxNew(const char * fn)
- /*@*/;
+ /*@globals fileSystem @*/
+ /*@modifies fileSystem @*/;
/**
* Return security context patterns count.
* @param sx security context patterns
* @return current pattern, NULL on invalid
*/
+/*@-exportlocal@*/
/*@observer@*/ /*@null@*/
extern const char * rpmsxPattern(/*@null@*/ const rpmsx sx)
/*@*/;
+/*@=exportlocal@*/
/**
* Return current type.
* @param sx security context patterns
* @return current type, NULL on invalid/missing
*/
+/*@-exportlocal@*/
/*@observer@*/ /*@null@*/
extern const char * rpmsxType(/*@null@*/ const rpmsx sx)
/*@*/;
+/*@=exportlocal@*/
/**
* Return current context.
* @param sx security context patterns
* @return current context, NULL on invalid
*/
+/*@-exportlocal@*/
/*@observer@*/ /*@null@*/
extern const char * rpmsxContext(/*@null@*/ const rpmsx sx)
/*@*/;
+/*@=exportlocal@*/
/**
* Return current regex.
* @param sx security context patterns
* @return current context, NULL on invalid
*/
+/*@-exportlocal@*/
/*@observer@*/ /*@null@*/
extern regex_t * rpmsxRE(/*@null@*/ const rpmsx sx)
/*@*/;
+/*@=exportlocal@*/
/**
* Return current file mode.
* @param sx security context patterns
* @return current file mode, 0 on invalid
*/
-/*@observer@*/ /*@null@*/
+/*@-exportlocal@*/
extern mode_t rpmsxFMode(/*@null@*/ const rpmsx sx)
/*@*/;
+/*@=exportlocal@*/
/**
* Return current file stem.
* @param sx security context patterns
* @return current file stem, -1 on invalid
*/
-/*@observer@*/ /*@null@*/
+/*@-exportlocal@*/
extern int rpmsxFStem(/*@null@*/ const rpmsx sx)
/*@*/;
+/*@=exportlocal@*/
/**
* Return next security context patterns iterator index.
* @param sx security context patterns
* @return security context patterns iterator index, -1 on termination
*/
+/*@-exportlocal@*/
int rpmsxNext(/*@null@*/ rpmsx sx)
/*@modifies sx @*/;
+/*@=exportlocal@*/
/**
* Initialize security context patterns iterator.
* @param reverse iterate in reverse order?
* @return security context patterns
*/
+/*@-exportlocal@*/
/*@null@*/
rpmsx rpmsxInit(/*@null@*/ rpmsx sx, int reverse)
/*@modifies sx @*/;
+/*@=exportlocal@*/
/**
* Find file security context from path and type.
*/
/*@null@*/
const char * rpmsxFContext(rpmsx sx, const char * fn, mode_t fmode)
- /*@*/;
+ /*@modifies sx @*/;
#ifdef __cplusplus
}