Add combine rules methods 35/178935/9
authorseolheui kim <s414.kim@samsung.com>
Tue, 15 May 2018 02:41:20 +0000 (11:41 +0900)
committerseolheui kim <s414.kim@samsung.com>
Tue, 29 May 2018 04:17:31 +0000 (13:17 +0900)
Change-Id: Ic446c41786619e5fbac7d726ac6c746bc2bf3a83
Signed-off-by: seolheui kim <s414.kim@samsung.com>
lib/audit-rule/field.h
lib/audit-rule/rule.cpp
lib/audit-rule/rule.h
lib/audit-trail/rule.cpp

index e37070af81b493b0b608da3efc32395645fa3dec..e723a11cc404c264160b39fcd20f86421c02ebf4 100644 (file)
@@ -101,7 +101,17 @@ enum class Operator : unsigned int {
 
 class FieldBase {
 public:
+       enum {
+               RelSeparate = -1,
+               RelKeep,
+               RelSwap,
+               RelRemove,
+       };
+
        virtual void emit(std::vector<char> &rule) const = 0;
+       virtual bool compare(std::shared_ptr<FieldBase> field) = 0;
+       virtual int getRelation(std::shared_ptr<FieldBase> field) = 0;
+
        virtual FieldType type() const = 0;
        virtual Operator op() const = 0;
 
@@ -189,6 +199,19 @@ public:
                emitValue(rule, _value);
        }
 
+       bool compare(std::shared_ptr<FieldBase> field)
+       {
+               auto f = reinterpret_cast<Field<T>*>(field.get());
+               if (f == nullptr)
+                       return false;
+
+               return (_type == field->type()) &&
+                       (_op == field->op()) &&
+                       (_value == f->value());
+       }
+
+       inline int getRelation(std::shared_ptr<FieldBase> field);
+
 private:
        Field create(T value, Operator op) {
                _op = op;
@@ -213,12 +236,43 @@ private:
                r->buflen += r->values[r->field_count++];
        }
 
-protected:
        FieldType _type;
        Operator _op;
        T _value;
 };
 
+template <typename T>
+int Field<T>::getRelation(std::shared_ptr<FieldBase> field)
+{
+       int ret = FieldBase::RelSeparate;
+       auto f = reinterpret_cast<Field<T>*>(field.get());
+
+       if (f == nullptr)
+               return FieldBase::RelKeep;
+
+       if (_op == f->op()) {
+               if (_op == Operator::Equal && _value != f->value())
+                       return FieldBase::RelSeparate;
+               else if (_op == Operator::NotEqual && _value != f->value())
+                       return FieldBase::RelRemove;
+       }
+
+       if (_op == Operator::Equal && f->op() == Operator::NotEqual) {
+               if (_value != f->value())
+                       return FieldBase::RelSwap;
+               else
+                       return FieldBase::RelRemove;
+       }
+
+       if (_op == Operator::NotEqual && f->op() == Operator::Equal) {
+               if (_value != f->value())
+                       return FieldBase::RelSwap;
+               else
+                       return FieldBase::RelRemove;
+       }
+       return ret;
+}
+
 INT_FIELD(Pid)
 INT_FIELD(Uid)
 INT_FIELD(EUid)
index 2f39454ffb83c6f8dcb174852d2ea1627c6617ad..ecff286e262b402b7cb2f9d6d856e3776e353532 100644 (file)
  */
 #include "rule.h"
 
+bool Rule::combine(Rule &r1, Rule &r2)
+{
+       int result = 0;
+       if (!r1.compareFieldType(r2) && !r2.compareFieldType(r1))
+               return false;
+
+       for (auto &c : r1.condition) {
+               if (r2.condition.find(c.first) != r2.condition.end()) {
+                       int ret = c.second->getRelation(r2.condition[c.first]);
+                       if (ret == FieldBase::RelSeparate)
+                               return false;
+                       if (ret != FieldBase::RelKeep)
+                               result = 1;
+                       if (ret == FieldBase::RelRemove)
+                               r2.unsetCondition(c.first);
+               } else {
+                       result = 1;
+               }
+       }
+
+       if (result == 0) {
+               for (auto m : r1.getMask()) {
+                       r2.unsetMask(m);
+               }
+       } else if (result == 1) {
+               for (auto m : r2.getMask()) {
+                       r1.unsetMask(m);
+               }
+       }
+       return true;
+}
+
 Rule::Rule(Action action, Filter filter)
        : buf(sizeof(RuleData))
 {
@@ -29,9 +61,8 @@ Rule::Rule(const std::vector<char> &rule)
 }
 
 Rule::Rule(const Rule &rule)
-       : buf(sizeof(RuleData))
+       : condition(rule.condition), buf(sizeof(RuleData))
 {
-       conditions.insert(rule.conditions.begin(), rule.conditions.end());
        setComponents(rule.buf);
 }
 
@@ -43,13 +74,34 @@ std::vector<char> Rule::data() const
 {
        std::vector<char> ret(buf);
 
-       for (auto &c : conditions) {
+       for (auto &c : condition) {
                if (c.second)
                        c.second->emit(ret);
        }
        return ret;
 }
 
+bool Rule::compareFieldType(const Rule &rule)
+{
+       int ret = true;
+       for (auto c : rule.condition) {
+               if (condition.find(c.first) == condition.end())
+                       return false;
+       }
+       return ret;
+}
+
+bool Rule::compareCondition(Rule &rule)
+{
+       for (auto c : condition) {
+               if (rule.condition.find(c.first) == rule.condition.end()
+                               || !c.second->compare(rule.condition[c.first])) {
+                       return false;
+               }
+       }
+       return true;
+}
+
 void Rule::set(Action action)
 {
        ruleData()->action = static_cast<unsigned int>(action);
@@ -122,12 +174,12 @@ void Rule::setComponents(const std::vector<char> &rule)
        for (unsigned int i = 0; i < r->field_count; i++) {
                if (FieldBase::isString(FieldType(r->fields[i]))) {
                        std::string value(ruleBuf, ruleBuf + r->values[i]);
-                       conditions[FieldType(r->fields[i])].reset(
+                       condition[FieldType(r->fields[i])].reset(
                                        new(std::nothrow) Field<std::string>(
                                                FieldType(r->fields[i]), Operator(r->fieldflags[i]), value));
                        ruleBuf += r->values[i];
                } else {
-                       conditions[FieldType(r->fields[i])].reset(
+                       condition[FieldType(r->fields[i])].reset(
                                        new(std::nothrow) Field<int>(
                                                FieldType(r->fields[i]), Operator(r->fieldflags[i]), r->values[i]));
                }
index 9ed8340f2e2254dd1e3c326de4af1e507322f141..f41bc64b66b4069d69c0386d5af6e27cc7c84bfb 100644 (file)
@@ -47,7 +47,9 @@ public:
                x = AUDIT_PERM_EXEC,
                a = AUDIT_PERM_ATTR,
        };
+
        using RuleData = struct audit_rule_data;
+       using Condition = std::map<FieldType, std::shared_ptr<FieldBase>>;
 
        Rule(Action action = Action::Always, Filter filter = Filter::Exit);
        virtual ~Rule();
@@ -55,7 +57,7 @@ public:
        Rule(Rule &&) = delete;
        Rule(const std::vector<char> &rule);
        Rule(const Rule &rule);
-
+       Rule &operator = (const Rule &rule) = default;
        template <typename T>
        Rule &operator << (const Field<T> &field)
        {
@@ -74,14 +76,15 @@ public:
                return (data() == rule.data());
        }
 
+       static bool combine(Rule &r1, Rule &r2);
        std::vector<char> data() const;
 
        template <typename T>
        void setCondition(const Field<T> &field);
-       template <typename T>
-       void unsetCondition(const Field<T> &field);
+       inline void unsetCondition(FieldType type);
        template <typename T>
        void getConditionValue(FieldType type, T &ret);
+       bool compareCondition(Rule &rule);
 
        void setMask();
        void setMask(unsigned int syscall);
@@ -94,47 +97,46 @@ protected:
        void set(Action action);
        void set(Filter filter);
 
-protected:
-       std::map<FieldType, std::shared_ptr<FieldBase>> conditions;
-
 private:
        RuleData *ruleData()
        {
                return reinterpret_cast<RuleData*>(buf.data());
        }
        void setComponents(const std::vector<char> &rule);
+       bool compareFieldType(const Rule &rule);
+
 private:
+       Condition condition;
        std::vector<char> buf;
 };
 
 template <typename T>
 void Rule::setCondition(const Field<T> &field)
 {
-       conditions[field.type()].reset(new(std::nothrow) Field<T>(field));
+       condition[field.type()].reset(new(std::nothrow) Field<T>(field));
 }
 
-template <typename T>
-void Rule::unsetCondition(const Field<T> &field)
+void Rule::unsetCondition(FieldType type)
 {
-       if (conditions.find(field.type()) != conditions.end())
-               conditions.erase(field.type());
+       auto c = condition.find(type);
+       if (c != condition.end()) {
+               c->second.reset();
+               condition.erase(c);
+       }
 }
 
 template <typename T>
 void Rule::getConditionValue(FieldType type, T &ret)
 {
-       auto condition = conditions[type].get();
-       if (condition == nullptr) {
-               //INFO("Condition isn't exist");
+       auto c = condition[type];
+       if (c == nullptr)
                return;
-       }
 
        if (!FieldBase::isString(type)
-                       && std::is_same<std::string, T>::value) {
-               //INFO("Invalid field value type");
+                       && std::is_same<std::string, T>::value)
                return;
-       }
-       Field<T> *field = reinterpret_cast<Field<T>*>(condition);
+
+       auto field = reinterpret_cast<Field<T>*>(c.get());
        ret = field->value();
 }
 
index 85586e4c02ccc540ee8d54b33ac501a893f9713e..1fb25168d301ed871ffd300ed664efe68951f978 100644 (file)
@@ -115,14 +115,12 @@ int audit_rule_remove_condition(audit_rule_h handle, unsigned int field,
        RET_ON_FAILURE(handle, AUDIT_TRAIL_ERROR_INVALID_PARAMETER);
 
        try {
-               GetAuditRule(handle).unsetCondition(
-                               Field<int>{FieldType(field), Operator(op), (int)(intptr_t)value});
+               GetAuditRule(handle).unsetCondition(FieldType(field));
                return AUDIT_TRAIL_ERROR_NONE;
        } catch (std::exception &e) {}
 
        try {
-               GetAuditRule(handle).unsetCondition(
-                               Field<std::string>{FieldType(field), Operator(op), (char *)value});
+               GetAuditRule(handle).unsetCondition(FieldType(field));
                return AUDIT_TRAIL_ERROR_NONE;
        } catch (std::exception &e) {}