Merge branch 'master' of jbrindle@oss.tresys.com:/home/git/selinux

This commit is contained in:
Joshua Brindle 2009-07-07 10:02:12 -04:00
commit f85eec0551
6 changed files with 80 additions and 113 deletions

View File

@ -1,3 +1,7 @@
2.0.83 2009-07-07
* Check /proc/filesystems before /proc/mounts for selinuxfs from Eric
Paris.
2.0.82 2009-06-19
* Fix improper use of thread local storage from Tomas Mraz <tmraz@redhat.com>.
* Label substitution support from Dan Walsh.

View File

@ -1 +1 @@
2.0.82
2.0.83

View File

@ -1,3 +1,6 @@
2.0.66 2009-07-07
* setfiles converted to fts from Thomas Liu.
2.0.65 2009-06-24
* Remove gui from po/Makefile and po/POTFILES and regenerate po files

View File

@ -1 +1 @@
2.0.65
2.0.66

View File

@ -3,11 +3,10 @@ PREFIX ?= ${DESTDIR}/usr
SBINDIR ?= $(DESTDIR)/sbin
MANDIR = $(PREFIX)/share/man
LIBDIR ?= $(PREFIX)/lib
AUDITH = $(shell ls /usr/include/libaudit.h 2>/dev/null)
CFLAGS = -Werror -Wall -W
override CFLAGS += -D_FILE_OFFSET_BITS=64 -I$(PREFIX)/include
override CFLAGS += -I$(PREFIX)/include
LDLIBS = -lselinux -lsepol -L$(LIBDIR)
ifeq (${AUDITH}, /usr/include/libaudit.h)

View File

@ -12,7 +12,9 @@
#include <regex.h>
#include <sys/vfs.h>
#define __USE_XOPEN_EXTENDED 1 /* nftw */
#include <ftw.h>
#define SKIP -2
#define ERR -1
#include <fts.h>
#include <limits.h>
#include <sepol/sepol.h>
#include <selinux/selinux.h>
@ -34,7 +36,6 @@ static int mass_relabel_errs;
static FILE *outfile = NULL;
static int force = 0;
#define STAT_BLOCK_SIZE 1
static int pipe_fds[2] = { -1, -1 };
static int progress = 0;
static unsigned long long count = 0;
@ -73,7 +74,7 @@ static int iamrestorecon;
static int expand_realpath; /* Expand paths via realpath. */
static int abort_on_error; /* Abort the file tree walk upon an error. */
static int add_assoc; /* Track inode associations for conflict detection. */
static int nftw_flags; /* Flags to nftw, e.g. follow links, follow mounts */
static int fts_flags; /* Flags to fts, e.g. follow links, follow mounts */
static int ctx_validate; /* Validate contexts */
static const char *altpath; /* Alternate path to file_contexts */
@ -292,23 +293,8 @@ static int exclude(const char *file)
int match(const char *name, struct stat *sb, char **con)
{
int ret;
char path[PATH_MAX + 1];
if (excludeCtr > 0) {
if (exclude(name)) {
return -1;
}
}
ret = lstat(name, sb);
if (ret) {
if (ignore_enoent && errno == ENOENT)
return 0;
fprintf(stderr, "%s: unable to stat file %s: %s\n", progname,
name, strerror(errno));
return -1;
}
if (expand_realpath) {
if (S_ISLNK(sb->st_mode)) {
if (verbose > 1)
@ -425,22 +411,14 @@ static int only_changed_user(const char *a, const char *b)
return (strcmp(rest_a, rest_b) == 0);
}
static int restore(const char *file)
static int restore(FTSENT *ftsent)
{
char *my_file = strdupa(file);
struct stat my_sb;
char *my_file = strdupa(ftsent->fts_path);
int ret;
char *context, *newcon;
int user_only_changed = 0;
size_t len = strlen(my_file);
/* Skip the extra slashes at the beginning and end, if present. */
if (file[0] == '/' && file[1] == '/')
my_file++;
if (len > 1 && my_file[len - 1] == '/')
my_file[len - 1] = 0;
if (match(my_file, &my_sb, &newcon) < 0)
if (match(my_file, ftsent->fts_statp, &newcon) < 0)
/* Check for no matching specification. */
return (errno == ENOENT) ? 0 : -1;
@ -463,7 +441,7 @@ static int restore(const char *file)
* then use the last matching specification.
*/
if (add_assoc) {
ret = filespec_add(my_sb.st_ino, newcon, my_file);
ret = filespec_add(ftsent->fts_statp->st_ino, newcon, my_file);
if (ret < 0)
goto err;
@ -477,7 +455,7 @@ static int restore(const char *file)
}
/* Get the current context of the file. */
ret = lgetfilecon_raw(my_file, &context);
ret = lgetfilecon_raw(ftsent->fts_accpath, &context);
if (ret < 0) {
if (errno == ENODATA) {
context = NULL;
@ -545,46 +523,42 @@ static int restore(const char *file)
/*
* Relabel the file to the specified context.
*/
ret = lsetfilecon(my_file, newcon);
ret = lsetfilecon(ftsent->fts_accpath, newcon);
if (ret) {
fprintf(stderr, "%s set context %s->%s failed:'%s'\n",
progname, my_file, newcon, strerror(errno));
goto out;
goto skip;
}
out:
out:
freecon(newcon);
return 0;
err:
skip:
freecon(newcon);
return -1;
return SKIP;
err:
freecon(newcon);
return ERR;
}
/*
* Apply the last matching specification to a file.
* This function is called by nftw on each file during
* This function is called by fts on each file during
* the directory traversal.
*/
static int apply_spec(const char *file,
const struct stat *sb_unused __attribute__ ((unused)),
int flag, struct FTW *s_unused __attribute__ ((unused)))
static int apply_spec(FTSENT *ftsent)
{
char buf[STAT_BLOCK_SIZE];
if (pipe_fds[0] != -1
&& read(pipe_fds[0], buf, STAT_BLOCK_SIZE) != STAT_BLOCK_SIZE) {
fprintf(stderr, "Read error on pipe.\n");
pipe_fds[0] = -1;
}
if (flag == FTW_DNR) {
if (ftsent->fts_info == FTS_DNR) {
fprintf(stderr, "%s: unable to read directory %s\n",
progname, file);
return 0;
progname, ftsent->fts_path);
return SKIP;
}
errors |= restore(file);
if (abort_on_error && errors)
return -1;
return 0;
int rc = restore(ftsent);
if (rc == ERR) {
if (!abort_on_error)
return SKIP;
}
return rc;
}
void set_rootpath(const char *arg)
@ -626,69 +600,55 @@ int canoncon(char **contextp)
return rc;
}
static int pre_stat(const char *file_unused __attribute__ ((unused)),
const struct stat *sb_unused __attribute__ ((unused)),
int flag_unused __attribute__ ((unused)),
struct FTW *s_unused __attribute__ ((unused)))
{
char buf[STAT_BLOCK_SIZE];
if (write(pipe_fds[1], buf, STAT_BLOCK_SIZE) != STAT_BLOCK_SIZE) {
fprintf(stderr, "Error writing to stat pipe, child exiting.\n");
exit(1);
}
return 0;
}
static int process_one(char *name)
{
struct stat sb;
int rc;
int rc = 0;
const char *namelist[2] = {name, NULL};
dev_t dev_num = 0;
FTS *fts_handle;
FTSENT *ftsent;
if (!strcmp(name, "/"))
mass_relabel = 1;
rc = lstat(name, &sb);
if (rc < 0) {
if (ignore_enoent && errno == ENOENT)
return 0;
fprintf(stderr, "%s: stat error on %s: %s\n",
progname, name, strerror(errno));
fts_handle = fts_open((char **)namelist, fts_flags, NULL);
if (fts_handle == NULL) {
fprintf(stderr,
"%s: error while labeling %s: %s\n",
progname, namelist[0], strerror(errno));
goto err;
}
if (S_ISDIR(sb.st_mode) && recurse) {
if (pipe(pipe_fds) < 0) {
fprintf(stderr, "%s: pipe error on %s: %s\n",
progname, name, strerror(errno));
goto err;
}
rc = fork();
if (rc < 0) {
fprintf(stderr, "%s: fork error on %s: %s\n",
progname, name, strerror(errno));
goto err;
}
if (rc == 0) {
/* Child: pre-stat the files. */
close(pipe_fds[0]);
nftw(name, pre_stat, 1024, nftw_flags);
exit(0);
}
/* Parent: Check and label the files. */
rc = 0;
close(pipe_fds[1]);
if (nftw(name, apply_spec, 1024, nftw_flags)) {
fprintf(stderr,
"%s: error while labeling %s: %s\n",
progname, name, strerror(errno));
goto err;
}
} else {
rc = restore(name);
if (rc)
goto err;
ftsent = fts_read(fts_handle);
if (ftsent != NULL) {
/* Keep the inode of the first one. */
dev_num = ftsent->fts_statp->st_dev;
}
do {
/* Skip the post order nodes. */
if (ftsent->fts_info == FTS_DP)
continue;
/* If the XDEV flag is set and the device is different */
if (ftsent->fts_statp->st_dev != dev_num &&
FTS_XDEV == (fts_flags & FTS_XDEV))
continue;
if (excludeCtr > 0) {
if (exclude(ftsent->fts_path)) {
fts_set(fts_handle, ftsent, FTS_SKIP);
continue;
}
}
int rc = apply_spec(ftsent);
if (rc == SKIP)
fts_set(fts_handle, ftsent, FTS_SKIP);
if (rc == ERR)
goto err;
if (!recurse)
break;
} while ((ftsent = fts_read(fts_handle)) != NULL);
if (!strcmp(name, "/"))
mass_relabel_errs = 0;
@ -698,7 +658,8 @@ out:
filespec_eval();
filespec_destroy();
}
if (fts_handle)
fts_close(fts_handle);
return rc;
err:
@ -777,7 +738,7 @@ int main(int argc, char **argv)
expand_realpath = 0;
abort_on_error = 1;
add_assoc = 1;
nftw_flags = FTW_PHYS | FTW_MOUNT;
fts_flags = FTS_PHYSICAL | FTS_XDEV;
ctx_validate = 1;
} else {
/*
@ -796,7 +757,7 @@ int main(int argc, char **argv)
expand_realpath = 1;
abort_on_error = 0;
add_assoc = 0;
nftw_flags = FTW_PHYS;
fts_flags = FTS_PHYSICAL;
ctx_validate = 0;
/* restorecon only: silent exit if no SELinux.