- fix rcapparmor stop. Have it dump the loaded profile list to a file before

removing profiles, as the list is unstable after additions or removals.
- Add the ability to loaded precompiled policy by specifying the -B
  option, which can be combined with --add or --replace
This commit is contained in:
John Johansen 2008-06-09 10:00:28 +00:00
parent 0c95606e03
commit 8f13e0d60d
4 changed files with 108 additions and 6 deletions

View file

@ -266,6 +266,8 @@ typedef struct __sdserialize sd_serialize;
extern int load_codomain(int option, struct codomain *cod);
extern int sd_serialize_profile(sd_serialize *p, struct codomain *cod,
int flatten);
extern int sd_load_buffer(int option, char *buffer, int size);
/* parser_policy.c */
extern void add_to_list(struct codomain *codomain);

View file

@ -886,3 +886,44 @@ int sd_serialize_codomain(int option, struct codomain *cod)
exit:
return error;
}
int sd_load_buffer(int option, char *buffer, int size)
{
int fd;
int error = 0, wsize;
char *filename = NULL;
switch (option) {
case OPTION_ADD:
asprintf(&filename, "%s/.load", subdomainbase);
fd = open(filename, O_WRONLY);
break;
case OPTION_REPLACE:
asprintf(&filename, "%s/.replace", subdomainbase);
fd = open(filename, O_WRONLY);
break;
default:
error = -EINVAL;
goto exit;
break;
}
if (fd < 0) {
PERROR(_("Unable to open %s - %s\n"), filename,
strerror(errno));
error = -errno;
goto exit;
}
wsize = write(fd, buffer, size);
if (wsize < 0) {
error = -errno;
} else if (wsize < size) {
PERROR(_("%s: Unable to write entire profile entry\n"),
progname);
}
close(fd);
exit:
free(filename);
return error;
}

View file

@ -59,6 +59,7 @@ const char *parser_copyright = "Copyright (C) 1999, 2000, 2003, 2004, 2005, 2006
char *progname;
int option = OPTION_ADD;
int force_complain = 0;
int binary_input = 0;
int names_only = 0;
int dump_vars = 0;
int dump_expanded_vars = 0;
@ -73,6 +74,7 @@ extern int current_lineno;
struct option long_options[] = {
{"add", 0, 0, 'a'},
{"binary", 0, 0, 'B'},
{"base", 1, 0, 'b'},
{"debug", 0, 0, 'd'},
{"subdomainfs", 0, 0, 'f'},
@ -120,6 +122,7 @@ static void display_usage(char *command)
"-b n, --base n Set base dir and cwd\n"
"-f n, --subdomainfs n Set location of apparmor filesystem\n"
"-S, --stdout Write output to stdout\n"
"-B, --binary Input is precompiled profile\n"
"-m n, --match-string n Use only match features n\n"
"-n n, --namespace n Set Namespace for the profile\n"
"-q, --quiet Don't emit warnings\n", command);
@ -152,7 +155,7 @@ static int process_args(int argc, char *argv[])
int count = 0;
option = OPTION_ADD;
while ((c = getopt_long(argc, argv, "adf:hrRvpI:b:CNSm:qn:", long_options, &o)) != -1)
while ((c = getopt_long(argc, argv, "adf:hrRvpI:b:BCNSm:qn:", long_options, &o)) != -1)
{
switch (c) {
case 0:
@ -193,6 +196,9 @@ static int process_args(int argc, char *argv[])
case 'b':
set_base_dir(optarg);
break;
case 'B':
binary_input =1;
break;
case 'C':
force_complain = 1;
break;
@ -395,6 +401,52 @@ static int regex_support(void) {
return 0;
}
int process_binary(int option, char *profilename)
{
char *buffer = NULL;
int retval = 0, size = 0, asize = 0, rsize;
int chunksize = 1 << 14;
int fd;
if (profilename) {
fd = open(profilename, O_RDONLY);
if (fd == -1) {
PERROR(_("Error: Could not read profile %s: %s.\n"),
profilename, strerror(errno));
exit(errno);
}
} else {
fd = dup(0);
}
do {
if (asize - size == 0) {
buffer = realloc(buffer, chunksize);
asize = chunksize;
chunksize <<= 1;
if (!buffer) {
PERROR(_("Memory allocation error."));
exit(errno);
}
}
rsize = read(fd, buffer + size, asize - size);
if (rsize)
size += rsize;
} while (rsize > 0);
close(fd);
if (rsize == 0)
retval = sd_load_buffer(option, buffer, size);
else
retval = rsize;
free(buffer);
return retval;
}
int process_profile(int option, char *profilename)
{
int retval = 0;
@ -478,10 +530,12 @@ int main(int argc, char *argv[])
return retval;
}
parse_default_paths();
retval = process_profile(option, profilename);
if (retval != 0)
return retval;
if (binary_input) {
retval = process_binary(option, profilename);
} else {
parse_default_paths();
retval = process_profile(option, profilename);
}
return retval;
}

View file

@ -373,13 +373,18 @@ remove_profiles() {
fi
retval=0
sed -e "s/ (\(enforce\|complain\))$//" "$SFS_MOUNTPOINT/profiles" | while read profile ; do
#the list of profiles isn't stable once we start adding or removing
#them so stor to tmp first
MODULE_PLIST=$(mktemp ${APPARMOR_TMPDIR}/tmp.XXXXXXXX)
sed -e "s/ (\(enforce\|complain\))$//" "$SFS_MOUNTPOINT/profiles" | sort >"$MODULE_PLIST"
cat "$MODULE_PLIST" | while read profile ; do
echo -n "$profile" > "$SFS_MOUNTPOINT/.remove"
rc=$?
if [ ${rc} -ne 0 ] ; then
retval=${rc}
fi
done
rm "$MODULE_PLIST"
if [ ${retval} -eq 0 ] ; then
aa_log_success_msg
else