Smack: Improve access check performance
[kernel/linux-3.0.git] / security / smack / smack.h
index 2d0573b..d65e9b0 100644 (file)
 #define SMK_LONGLABEL  256
 
 /*
+ * This is the repository for labels seen so that it is
+ * not necessary to keep allocating tiny chuncks of memory
+ * and so that they can be shared.
+ *
+ * Labels are never modified in place. Anytime a label
+ * is imported (e.g. xattrset on a file) the list is checked
+ * for it and it is added if it doesn't exist. The address
+ * is passed out in either case. Entries are added, but
+ * never deleted.
+ *
+ * Since labels are hanging around anyway it doesn't
+ * hurt to maintain a secid for those awkward situations
+ * where kernel components that ought to use LSM independent
+ * interfaces don't. The secid should go away when all of
+ * these components have been repaired.
+ *
+ * The cipso value associated with the label gets stored here, too.
+ *
+ * Keep the access rules for this subject label here so that
+ * the entire set of rules does not need to be examined every
+ * time.
+ */
+struct smack_known {
+       struct list_head                list;
+       char                            *smk_known;
+       u32                             smk_secid;
+       struct netlbl_lsm_secattr       smk_netlabel;   /* on wire labels */
+       struct list_head                smk_rules;      /* access rules */
+       struct mutex                    smk_rules_lock; /* lock for rules */
+};
+
+/*
  * Maximum number of bytes for the levels in a CIPSO IP option.
  * Why 23? CIPSO is constrained to 30, so a 32 byte buffer is
  * bigger than can be used, and 24 is the next lower multiple
@@ -46,25 +78,25 @@ struct superblock_smack {
 };
 
 struct socket_smack {
-       char            *smk_out;       /* outbound label */
-       char            *smk_in;        /* inbound label */
-       char            *smk_packet;    /* TCP peer label */
+       struct smack_known      *smk_out;       /* outbound label */
+       char                    *smk_in;        /* inbound label */
+       char                    *smk_packet;    /* TCP peer label */
 };
 
 /*
  * Inode smack data
  */
 struct inode_smack {
-       char            *smk_inode;     /* label of the fso */
-       char            *smk_task;      /* label of the task */
-       char            *smk_mmap;      /* label of the mmap domain */
-       struct mutex    smk_lock;       /* initialization lock */
-       int             smk_flags;      /* smack inode flags */
+       char                    *smk_inode;     /* label of the fso */
+       struct smack_known      *smk_task;      /* label of the task */
+       struct smack_known      *smk_mmap;      /* label of the mmap domain */
+       struct mutex            smk_lock;       /* initialization lock */
+       int                     smk_flags;      /* smack inode flags */
 };
 
 struct task_smack {
-       char                    *smk_task;      /* label for access control */
-       char                    *smk_forked;    /* label when forked */
+       struct smack_known      *smk_task;      /* label for access control */
+       struct smack_known      *smk_forked;    /* label when forked */
        struct list_head        smk_rules;      /* per task access rules */
        struct mutex            smk_rules_lock; /* lock for the rules */
 };
@@ -78,7 +110,7 @@ struct task_smack {
  */
 struct smack_rule {
        struct list_head        list;
-       char                    *smk_subject;
+       struct smack_known      *smk_subject;
        char                    *smk_object;
        int                     smk_access;
 };
@@ -101,39 +133,7 @@ struct smk_port_label {
        struct sock             *smk_sock;      /* socket initialized on */
        unsigned short          smk_port;       /* the port number */
        char                    *smk_in;        /* incoming label */
-       char                    *smk_out;       /* outgoing label */
-};
-
-/*
- * This is the repository for labels seen so that it is
- * not necessary to keep allocating tiny chuncks of memory
- * and so that they can be shared.
- *
- * Labels are never modified in place. Anytime a label
- * is imported (e.g. xattrset on a file) the list is checked
- * for it and it is added if it doesn't exist. The address
- * is passed out in either case. Entries are added, but
- * never deleted.
- *
- * Since labels are hanging around anyway it doesn't
- * hurt to maintain a secid for those awkward situations
- * where kernel components that ought to use LSM independent
- * interfaces don't. The secid should go away when all of
- * these components have been repaired.
- *
- * The cipso value associated with the label gets stored here, too.
- *
- * Keep the access rules for this subject label here so that
- * the entire set of rules does not need to be examined every
- * time.
- */
-struct smack_known {
-       struct list_head                list;
-       char                            *smk_known;
-       u32                             smk_secid;
-       struct netlbl_lsm_secattr       smk_netlabel;   /* on wire labels */
-       struct list_head                smk_rules;      /* access rules */
-       struct mutex                    smk_rules_lock; /* lock for rules */
+       struct smack_known      *smk_out;       /* outgoing label */
 };
 
 /*
@@ -209,9 +209,9 @@ struct inode_smack *new_inode_smack(char *);
  * These functions are in smack_access.c
  */
 int smk_access_entry(char *, char *, struct list_head *);
-int smk_access(char *, char *, int, struct smk_audit_info *);
+int smk_access(struct smack_known *, char *, int, struct smk_audit_info *);
 int smk_curacc(char *, u32, struct smk_audit_info *);
-char *smack_from_secid(const u32);
+struct smack_known *smack_from_secid(const u32);
 char *smk_parse_smack(const char *string, int len);
 int smk_netlbl_mls(int, char *, struct netlbl_lsm_secattr *, int);
 char *smk_import(const char *, int);
@@ -224,7 +224,7 @@ u32 smack_to_secid(const char *);
  */
 extern int smack_cipso_direct;
 extern int smack_cipso_mapped;
-extern char *smack_net_ambient;
+extern struct smack_known *smack_net_ambient;
 extern char *smack_onlycap;
 extern const char *smack_cipso_option;
 
@@ -260,17 +260,17 @@ static inline char *smk_of_inode(const struct inode *isp)
 }
 
 /*
- * Present a pointer to the smack label in an task blob.
+ * Present a pointer to the smack label entry in an task blob.
  */
-static inline char *smk_of_task(const struct task_smack *tsp)
+static inline struct smack_known *smk_of_task(const struct task_smack *tsp)
 {
        return tsp->smk_task;
 }
 
 /*
- * Present a pointer to the forked smack label in an task blob.
+ * Present a pointer to the forked smack label entry in an task blob.
  */
-static inline char *smk_of_forked(const struct task_smack *tsp)
+static inline struct smack_known *smk_of_forked(const struct task_smack *tsp)
 {
        return tsp->smk_forked;
 }
@@ -278,7 +278,7 @@ static inline char *smk_of_forked(const struct task_smack *tsp)
 /*
  * Present a pointer to the smack label in the current task blob.
  */
-static inline char *smk_of_current(void)
+static inline struct smack_known *smk_of_current(void)
 {
        return smk_of_task(current_security());
 }
@@ -289,9 +289,11 @@ static inline char *smk_of_current(void)
  */
 static inline int smack_privileged(int cap)
 {
+       struct smack_known *skp = smk_of_current();
+
        if (!capable(cap))
                return 0;
-       if (smack_onlycap == NULL || smack_onlycap == smk_of_current())
+       if (smack_onlycap == NULL || smack_onlycap == skp->smk_known)
                return 1;
        return 0;
 }