This changes/fixes the encoding for unix socket rules.

the changes look larger than they are because it refactors the code, instead
of duplicating.

The major changes are:
- it changes where the accept perm is stored
- it moves anyone_match_pattern to default_match_pattern
- it fixes the layout of the local addr only being written when local perms
  are present

---

=== modified file 'parser/af_unix.cc'
--- parser/af_unix.cc   2014-08-27 21:38:24 +0000
+++ parser/af_unix.cc   2014-08-29 19:33:32 +0000
@@ -226,13 +226,99 @@
                ((mask & (AA_NET_SETOPT | AA_NET_GETOPT)) >> 5); /* 5 + 
(AA_OTHER_SHIFT - 24) */
 }
 
+void unix_rule::write_to_prot(std::ostringstream &buffer)
+{
+       buffer << "\\x" << std::setfill('0') << std::setw(2) << std::hex << 
AA_CLASS_NET;
+       writeu16(buffer, AF_UNIX);
+       if (sock_type)
+               writeu16(buffer, sock_type_n);
+       else
+               buffer << "..";
+       if (proto)
+               writeu16(buffer, proto_n);
+       else
+               buffer << "..";
+}
+
+bool unix_rule::write_addr(std::ostringstream &buffer, const char *addr)
+{
+       std::string buf;
+       pattern_t ptype;
+
+       if (addr) {
+               int pos;
+               if (strcmp(addr, "none") == 0) {
+                       /* anonymous */
+                       buffer << "\\x01";
+               } else {
+                       /* skip leading @ */
+                       ptype = convert_aaregex_to_pcre(addr + 1, 0, buf, &pos);
+                       if (ptype == ePatternInvalid)
+                               return false;
+                       /* kernel starts abstract with \0 */
+                       buffer << "\\x00";
+                       buffer << buf;
+               }
+       } else
+               /* match any addr or anonymous */
+               buffer << ".*";
+
+       /* todo: change to out of band separator */
+       buffer << "\\x00";
+
+       return true;
+}
+
+bool unix_rule::write_label(std::ostringstream &buffer, const char *label)
+{
+       std::string buf;
+       pattern_t ptype;
+
+       if (label) {
+               int pos;
+               ptype = convert_aaregex_to_pcre(label, 0, buf, &pos);
+               if (ptype == ePatternInvalid)
+                       return false;
+               /* kernel starts abstract with \0 */
+               buffer << buf;
+       } else
+               buffer << default_match_pattern;
+
+       return true;
+}
+
+/* General Layout
+ *
+ * Local socket end point perms
+ * CLASS_NET  AF  TYPE PROTO  local (addr\0label) \0 cmd cmd_option
+ *          ^   ^           ^                       ^              ^
+ *          |   |           |                       |              |
+ *  stub perm   |           |                       |              |
+ *              |           |                       |              |
+ *  sub stub perm           |                       |              |
+ *                          |                       |              |
+ *                create perm                       |              |
+ *                                                  |              |
+ *                                                  |              |
+ *                         bind, accept, get/set attr              |
+ *                                                                 |
+ *                                          listen, set/get opt perm
+ *
+ *
+ * peer socket end point perms
+ * CLASS_NET  AF  TYPE PROTO  local(addr\0label\0) cmd_addr peer(addr\0label )
+ *                                                                          ^
+ *                                                                          |
+ *                                           send/receive connect/accept perm
+ *
+ * NOTE: accept is encoded twice, locally to check if a socket is allowed
+ *       to accept, and then as a pair to test that it can accept the pair.
+ */
 int unix_rule::gen_policy_re(Profile &prof)
 {
        std::ostringstream buffer, tmp;
        std::string buf;
 
-       pattern_t ptype;
-       int pos;
        int mask = mode;
 
        /* always generate a downgraded rule. This doesn't change generated
@@ -253,18 +339,7 @@
                return RULE_NOT_SUPPORTED;
        }
 
-
-       buffer << "\\x" << std::setfill('0') << std::setw(2) << std::hex << 
AA_CLASS_NET;
-       writeu16(buffer, AF_UNIX);
-       if (sock_type)
-               writeu16(buffer, sock_type_n);
-       else
-               buffer << "..";
-       if (proto)
-               writeu16(buffer, proto_n);
-       else
-               buffer << "..";
-
+       write_to_prot(buffer);
        if (mask & AA_NET_CREATE) {
                buf = buffer.str();
                if (!prof.policy.rules->add_rule(buf.c_str(), deny,
@@ -275,35 +350,14 @@
                mask &= ~AA_NET_CREATE;
        }
 
-       /* local addr */
-       if (addr) {
-               if (strcmp(addr, "none") == 0) {
-                       buffer << "\\x01";
-               } else {
-                       /* skip leading @ */
-                       ptype = convert_aaregex_to_pcre(addr + 1, 0, buf, &pos);
-                       if (ptype == ePatternInvalid)
-                               goto fail;
-                       /* kernel starts abstract with \0 */
-                       buffer << "\\x00";
-                       buffer << buf;
-               }
-       } else
-               buffer << ".*";
-
-       /* change to out of band separator */
-       buffer << "\\x00";
-
-       if (mask & AA_LOCAL_NET_PERMS) {
+       if (mask) {
+               /* local addr */
+               if (!write_addr(buffer, addr))
+                       goto fail;
                /* local label option */
-               if (label) {
-                       ptype = convert_aaregex_to_pcre(label, 0, buf, &pos);
-                       if (ptype == ePatternInvalid)
-                               goto fail;
-                       /* kernel starts abstract with \0 */
-                       buffer << buf;
-               } else
-                       tmp << anyone_match_pattern;
+               if (!write_label(buffer, label))
+                       goto fail;
+               /* seperator */
                buffer << "\\x00";
 
                /* create already masked off */
@@ -316,21 +370,10 @@
                                goto fail;
                }
 
-               /* cmd selector - drop accept??? */
-               if (mask & AA_NET_ACCEPT) {
-                       tmp.str(buffer.str());
-                       tmp << "\\x" << std::setfill('0') << std::setw(2) << 
std::hex << CMD_ACCEPT;
-                       buf = tmp.str();
-                       if (!prof.policy.rules->add_rule(buf.c_str(), deny,
-                                                        
map_perms(AA_NET_ACCEPT),
-                                                        map_perms(audit & 
AA_NET_ACCEPT),
-                                                        dfaflags))
-                               goto fail;
-               }
                if (mask & AA_NET_LISTEN) {
                        tmp.str(buffer.str());
                        tmp << "\\x" << std::setfill('0') << std::setw(2) << 
std::hex << CMD_LISTEN;
-                       /* TODO: backlog conditional */
+                       /* TODO: backlog conditional: for now match anything*/
                        tmp << "..";
                        buf = tmp.str();
                        if (!prof.policy.rules->add_rule(buf.c_str(), deny,
@@ -342,7 +385,7 @@
                if (mask & AA_NET_OPT) {
                        tmp.str(buffer.str());
                        tmp << "\\x" << std::setfill('0') << std::setw(2) << 
std::hex << CMD_OPT;
-                       /* TODO: sockopt conditional */
+                       /* TODO: sockopt conditional: for now match anything */
                        tmp << "..";
                        buf = tmp.str();
                        if (!prof.policy.rules->add_rule(buf.c_str(), deny,
@@ -351,38 +394,19 @@
                                                         dfaflags))
                                goto fail;
                }
-               mask &= ~AA_LOCAL_NET_PERMS;
-       }
+               mask &= ~AA_LOCAL_NET_PERMS | AA_NET_ACCEPT;
+       } /* if (mask) */
 
        if (mask & AA_PEER_NET_PERMS) {
                /* cmd selector */
                buffer << "\\x" << std::setfill('0') << std::setw(2) << 
std::hex << CMD_ADDR;
 
-               /* peer addr */
-               if (peer_addr) {
-                       if (strcmp(peer_addr, "none") == 0) {
-                               buffer << "\\x01";
-                       } else {
-                               /* skip leading @ */
-                               ptype = convert_aaregex_to_pcre(peer_addr + 1, 
0, buf, &pos);
-                               if (ptype == ePatternInvalid)
-                                       goto fail;
-                               /* kernel starts abstract with \0 */
-                               buffer << "\\x00";
-                               buffer << buf;
-                       }
-               }
-               /* change to out of band separator */
-               buffer << "\\x00";
-
-               if (peer_label) {
-                       ptype = convert_aaregex_to_pcre(peer_label, 0, buf, 
&pos);
-                       if (ptype == ePatternInvalid)
-                               goto fail;
-                       buffer << buf;
-               } else {
-                       buffer << anyone_match_pattern;
-               }
+               /* local addr */
+               if (!write_addr(buffer, peer_addr))
+                       goto fail;
+               /* local label option */
+               if (!write_label(buffer, peer_label))
+                       goto fail;
 
                buf = buffer.str();
                if (!prof.policy.rules->add_rule(buf.c_str(), deny, 
map_perms(mode & AA_PEER_NET_PERMS), map_perms(audit), dfaflags))

=== modified file 'parser/af_unix.h'
--- parser/af_unix.h    2014-08-26 06:05:14 +0000
+++ parser/af_unix.h    2014-08-29 19:17:06 +0000
@@ -27,6 +27,9 @@
 int parse_unix_mode(const char *str_mode, int *mode, int fail);
 
 class unix_rule: public af_rule {
+       void write_to_prot(std::ostringstream &buffer);
+       bool write_addr(std::ostringstream &buffer, const char *addr);
+       bool write_label(std::ostringstream &buffer, const char *label);
        void move_conditionals(struct cond_entry *conds);
        void move_peer_conditionals(struct cond_entry *conds);
        void downgrade_rule(Profile &prof);

=== modified file 'parser/network.h'
--- parser/network.h    2014-08-26 05:51:50 +0000
+++ parser/network.h    2014-08-29 17:53:45 +0000
@@ -70,8 +70,9 @@
                            AA_NET_GETATTR | AA_NET_BIND | AA_NET_ACCEPT |    \
                            AA_NET_LISTEN | AA_NET_SETOPT | AA_NET_GETOPT)
 #define AA_NET_OPT     (AA_NET_SETOPT | AA_NET_GETOPT)
-#define AA_LOCAL_NET_CMD (AA_NET_ACCEPT | AA_NET_LISTEN | AA_NET_OPT)
-#define AA_PEER_NET_PERMS (AA_VALID_NET_PERMS & ~AA_LOCAL_NET_PERMS)
+#define AA_LOCAL_NET_CMD (AA_NET_LISTEN | AA_NET_OPT)
+#define AA_PEER_NET_PERMS (AA_VALID_NET_PERMS & (~AA_LOCAL_NET_PERMS | \
+                                                AA_NET_ACCEPT))
 
 struct network_tuple {
        const char *family_name;



-- 
AppArmor mailing list
AppArmor@lists.ubuntu.com
Modify settings or unsubscribe at: 
https://lists.ubuntu.com/mailman/listinfo/apparmor

Reply via email to