[apparmor] [PATCH v2 10/42] Add fns to handle profile removal to the kernel interface
Tyler Hicks
tyhicks at canonical.com
Tue Mar 24 20:42:19 UTC 2015
On 2015-03-06 15:48:26, Tyler Hicks wrote:
> From: John Johansen <john.johansen at canonical.com>
>
> Signed-off-by: John Johansen <john.johansen at canonical.com>
> [tyhicks: Forward ported patch to trunk]
> [tyhicks: remove commented out code]
> Signed-off-by: Tyler Hicks <tyhicks at canonical.com>
> ---
Re-reviewed this one and it still looks good with the exception of one
minor issue noted below.
> parser/kernel_interface.c | 23 +++++++++++++++++++++++
> parser/kernel_interface.h | 1 +
> parser/parser_interface.c | 46 +++-------------------------------------------
> parser/parser_variable.c | 4 +---
> parser/parser_yacc.y | 9 ++++++++-
> parser/profile.h | 35 ++++++++++++++++++++++-------------
> 6 files changed, 58 insertions(+), 60 deletions(-)
>
> diff --git a/parser/kernel_interface.c b/parser/kernel_interface.c
> index 5585249..a33a6be 100644
> --- a/parser/kernel_interface.c
> +++ b/parser/kernel_interface.c
> @@ -204,3 +204,26 @@ int aa_load_buffer(int option, char *buffer, int size)
>
> return write_policy_buffer(fd, kernel_supports_setload, buffer, size);
> }
> +
> +/**
> + * aa_remove_profile - remove a profile from the kernel
> + * @fqname: the fully qualified name of the profile to remove
> + *
> + * Returns: 0 on success, -1 on error with errno set
> + */
> +int aa_remove_profile(const char *fqname)
> +{
> + autoclose int dirfd = -1;
> + autoclose int fd = -1;
> +
> + dirfd = open_iface_dir();
> + if (dirfd == -1)
> + return -1;
> +
> + fd = open_option_iface(dirfd, OPTION_REMOVE);
> + if (fd == -1)
> + return -1;
> +
> + /* include trailing \0 in buffer write */
> + return write_buffer(fd, fqname, strlen(fqname) + 1, 0);
> +}
> diff --git a/parser/kernel_interface.h b/parser/kernel_interface.h
> index 13e5996..3d53238 100644
> --- a/parser/kernel_interface.h
> +++ b/parser/kernel_interface.h
> @@ -21,5 +21,6 @@
>
> int aa_find_iface_dir(char **dir);
> int aa_load_buffer(int option, char *buffer, int size);
> +int aa_remove_profile(const char *fqname);
>
> #endif /* __AA_KERNEL_INTERFACE_H */
> diff --git a/parser/parser_interface.c b/parser/parser_interface.c
> index 895b2bc..6a9c918 100644
> --- a/parser/parser_interface.c
> +++ b/parser/parser_interface.c
> @@ -29,6 +29,7 @@
> #include <sstream>
>
> #include "lib.h"
> +#include "kernel_interface.h"
> #include "parser.h"
> #include "profile.h"
> #include "libapparmor_re/apparmor_re.h"
> @@ -467,9 +468,7 @@ void sd_serialize_top_profile(std::ostringstream &buf, Profile *profile)
> sd_write_name(buf, "version");
> sd_write_uint32(buf, version);
>
> - if (profile_ns) {
> - sd_write_string(buf, profile_ns, "namespace");
> - } else if (profile->ns) {
> + if (profile->ns) {
> sd_write_string(buf, profile->ns, "namespace");
> }
>
> @@ -523,49 +522,10 @@ int __sd_serialize_profile(int option, Profile *prof)
> error = 0;
>
> if (option == OPTION_REMOVE) {
> - char *name, *ns = NULL;
> - int len = 0;
> -
> - if (profile_ns) {
> - len += strlen(profile_ns) + 2;
> - ns = profile_ns;
> - } else if (prof->ns) {
> - len += strlen(prof->ns) + 2;
> - ns = prof->ns;
> - }
> - if (prof->parent) {
> - name = (char *) malloc(strlen(prof->name) + 3 +
> - strlen(prof->parent->name) + len);
> - if (!name) {
> - PERROR(_("Memory Allocation Error: Unable to remove ^%s\n"), prof->name);
> - error = -errno;
> - goto exit;
> - }
> - if (ns)
> - sprintf(name, ":%s:%s//%s", ns,
> - prof->parent->name, prof->name);
> - else
> - sprintf(name, "%s//%s", prof->parent->name,
> - prof->name);
> - } else if (ns) {
> - name = (char *) malloc(len + strlen(prof->name) + 1);
> - if (!name) {
> - PERROR(_("Memory Allocation Error: Unable to remove %s:%s."), ns, prof->name);
> - error = -errno;
> - goto exit;
> - }
> - sprintf(name, ":%s:%s", ns, prof->name);
> - } else {
> - name = prof->name;
> - }
> - size = strlen(name) + 1;
> if (kernel_load) {
> - wsize = write(fd, name, size);
> - if (wsize < 0)
> + if (aa_remove_profile(prof->fqname().c_str()) == -1)
> error = -errno;
> }
> - if (prof->parent || ns)
> - free(name);
> } else {
> sd_serialize_top_profile(work_area, prof);
>
> diff --git a/parser/parser_variable.c b/parser/parser_variable.c
> index 00807b7..e1f6543 100644
> --- a/parser/parser_variable.c
> +++ b/parser/parser_variable.c
> @@ -274,10 +274,8 @@ static int process_variables_in_rules(Profile &prof)
> int process_profile_variables(Profile *prof)
> {
> int error = 0, rc;
> - std::string *buf = prof->get_name(true);
>
> - error = new_set_var(PROFILE_NAME_VARIABLE, buf->c_str());
> - delete buf;
> + error = new_set_var(PROFILE_NAME_VARIABLE, prof->get_name(true).c_str());
>
> if (!error)
> error = process_variables_in_entries(prof->entries);
> diff --git a/parser/parser_yacc.y b/parser/parser_yacc.y
> index bec68ca..634e200 100644
> --- a/parser/parser_yacc.y
> +++ b/parser/parser_yacc.y
> @@ -347,7 +347,14 @@ profile: opt_profile_flag opt_ns profile_base
> if ($3->name[0] != '/' && !($1 || $2))
> yyerror(_("Profile names must begin with a '/', namespace or keyword 'profile' or 'hat'."));
>
> - prof->ns = $2;
> + if ($2 && profile_ns) {
> + free($2);
> + pwarn("%s: -n %s overriding policy specified namespace :%s:\n", progname, profile_ns, $2);
There's a use after free here. I'll just make the change in my local
branch instead of sending out another patch.
Tyler
> + prof->ns = strdup(profile_ns);
> + if (!prof->ns)
> + yyerror(_("Memory allocation error."));
> + } else
> + prof->ns = $2;
> if ($1 == 2)
> prof->flags.hat = 1;
> $$ = prof;
> diff --git a/parser/profile.h b/parser/profile.h
> index 063ab17..5adbbcf 100644
> --- a/parser/profile.h
> +++ b/parser/profile.h
> @@ -213,25 +213,34 @@ public:
>
> bool alloc_net_table();
>
> - std::string* get_name(bool fqp)
> + std::string hname(void)
> {
> - std::string *buf;
> - if (fqp && parent) {
> - buf = parent->get_name(fqp);
> - buf->append("//");
> - buf->append(name);
> - } else {
> - return new std::string(name);
> - }
> + if (!parent)
> + return name;
> +
> + return parent->hname() + "//" + name;
> + }
>
> - return buf;
> + /* assumes ns is set as part of profile creation */
> + std::string fqname(void)
> + {
> + if (parent)
> + return parent->fqname() + "://" + name;
> + else if (!ns)
> + return hname();
> + return ":" + std::string(ns) + "://" + hname();
> + }
> +
> + std::string get_name(bool fqp)
> + {
> + if (fqp)
> + return fqname();
> + return hname();
> }
>
> void dump_name(bool fqp)
> {
> - std::string *buf = get_name(fqp);;
> - cout << *buf;
> - delete buf;
> + cout << get_name(fqp);;
> }
> };
>
> --
> 2.1.4
>
>
> --
> AppArmor mailing list
> AppArmor at lists.ubuntu.com
> Modify settings or unsubscribe at: https://lists.ubuntu.com/mailman/listinfo/apparmor
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <https://lists.ubuntu.com/archives/apparmor/attachments/20150324/760fcb21/attachment.pgp>
More information about the AppArmor
mailing list