aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--security/smack/smack.h1
-rw-r--r--security/smack/smack_access.c10
-rw-r--r--security/smack/smackfs.c92
3 files changed, 102 insertions, 1 deletions
diff --git a/security/smack/smack.h b/security/smack/smack.h
index 4a4477f5afdc..31dce559595a 100644
--- a/security/smack/smack.h
+++ b/security/smack/smack.h
@@ -178,6 +178,7 @@ u32 smack_to_secid(const char *);
178extern int smack_cipso_direct; 178extern int smack_cipso_direct;
179extern int smack_net_nltype; 179extern int smack_net_nltype;
180extern char *smack_net_ambient; 180extern char *smack_net_ambient;
181extern char *smack_onlycap;
181 182
182extern struct smack_known *smack_known; 183extern struct smack_known *smack_known;
183extern struct smack_known smack_known_floor; 184extern struct smack_known smack_known_floor;
diff --git a/security/smack/smack_access.c b/security/smack/smack_access.c
index f6b5f6eed6dd..79ff21ed4c3b 100644
--- a/security/smack/smack_access.c
+++ b/security/smack/smack_access.c
@@ -157,7 +157,7 @@ int smk_access(char *subject_label, char *object_label, int request)
157 * 157 *
158 * This function checks the current subject label/object label pair 158 * This function checks the current subject label/object label pair
159 * in the access rule list and returns 0 if the access is permitted, 159 * in the access rule list and returns 0 if the access is permitted,
160 * non zero otherwise. It allows that current my have the capability 160 * non zero otherwise. It allows that current may have the capability
161 * to override the rules. 161 * to override the rules.
162 */ 162 */
163int smk_curacc(char *obj_label, u32 mode) 163int smk_curacc(char *obj_label, u32 mode)
@@ -168,6 +168,14 @@ int smk_curacc(char *obj_label, u32 mode)
168 if (rc == 0) 168 if (rc == 0)
169 return 0; 169 return 0;
170 170
171 /*
172 * Return if a specific label has been designated as the
173 * only one that gets privilege and current does not
174 * have that label.
175 */
176 if (smack_onlycap != NULL && smack_onlycap != current->security)
177 return rc;
178
171 if (capable(CAP_MAC_OVERRIDE)) 179 if (capable(CAP_MAC_OVERRIDE))
172 return 0; 180 return 0;
173 181
diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c
index 271a835fbbe3..e7c642458ec9 100644
--- a/security/smack/smackfs.c
+++ b/security/smack/smackfs.c
@@ -39,6 +39,7 @@ enum smk_inos {
39 SMK_DIRECT = 6, /* CIPSO level indicating direct label */ 39 SMK_DIRECT = 6, /* CIPSO level indicating direct label */
40 SMK_AMBIENT = 7, /* internet ambient label */ 40 SMK_AMBIENT = 7, /* internet ambient label */
41 SMK_NLTYPE = 8, /* label scheme to use by default */ 41 SMK_NLTYPE = 8, /* label scheme to use by default */
42 SMK_ONLYCAP = 9, /* the only "capable" label */
42}; 43};
43 44
44/* 45/*
@@ -68,6 +69,16 @@ int smack_net_nltype = NETLBL_NLTYPE_CIPSOV4;
68 */ 69 */
69int smack_cipso_direct = SMACK_CIPSO_DIRECT_DEFAULT; 70int smack_cipso_direct = SMACK_CIPSO_DIRECT_DEFAULT;
70 71
72/*
73 * Unless a process is running with this label even
74 * having CAP_MAC_OVERRIDE isn't enough to grant
75 * privilege to violate MAC policy. If no label is
76 * designated (the NULL case) capabilities apply to
77 * everyone. It is expected that the hat (^) label
78 * will be used if any label is used.
79 */
80char *smack_onlycap;
81
71static int smk_cipso_doi_value = SMACK_CIPSO_DOI_DEFAULT; 82static int smk_cipso_doi_value = SMACK_CIPSO_DOI_DEFAULT;
72struct smk_list_entry *smack_list; 83struct smk_list_entry *smack_list;
73 84
@@ -787,6 +798,85 @@ static const struct file_operations smk_ambient_ops = {
787 .write = smk_write_ambient, 798 .write = smk_write_ambient,
788}; 799};
789 800
801/**
802 * smk_read_onlycap - read() for /smack/onlycap
803 * @filp: file pointer, not actually used
804 * @buf: where to put the result
805 * @cn: maximum to send along
806 * @ppos: where to start
807 *
808 * Returns number of bytes read or error code, as appropriate
809 */
810static ssize_t smk_read_onlycap(struct file *filp, char __user *buf,
811 size_t cn, loff_t *ppos)
812{
813 char *smack = "";
814 ssize_t rc = -EINVAL;
815 int asize;
816
817 if (*ppos != 0)
818 return 0;
819
820 if (smack_onlycap != NULL)
821 smack = smack_onlycap;
822
823 asize = strlen(smack) + 1;
824
825 if (cn >= asize)
826 rc = simple_read_from_buffer(buf, cn, ppos, smack, asize);
827
828 return rc;
829}
830
831/**
832 * smk_write_onlycap - write() for /smack/onlycap
833 * @filp: file pointer, not actually used
834 * @buf: where to get the data from
835 * @count: bytes sent
836 * @ppos: where to start
837 *
838 * Returns number of bytes written or error code, as appropriate
839 */
840static ssize_t smk_write_onlycap(struct file *file, const char __user *buf,
841 size_t count, loff_t *ppos)
842{
843 char in[SMK_LABELLEN];
844 char *sp = current->security;
845
846 if (!capable(CAP_MAC_ADMIN))
847 return -EPERM;
848
849 /*
850 * This can be done using smk_access() but is done
851 * explicitly for clarity. The smk_access() implementation
852 * would use smk_access(smack_onlycap, MAY_WRITE)
853 */
854 if (smack_onlycap != NULL && smack_onlycap != sp)
855 return -EPERM;
856
857 if (count >= SMK_LABELLEN)
858 return -EINVAL;
859
860 if (copy_from_user(in, buf, count) != 0)
861 return -EFAULT;
862
863 /*
864 * Should the null string be passed in unset the onlycap value.
865 * This seems like something to be careful with as usually
866 * smk_import only expects to return NULL for errors. It
867 * is usually the case that a nullstring or "\n" would be
868 * bad to pass to smk_import but in fact this is useful here.
869 */
870 smack_onlycap = smk_import(in, count);
871
872 return count;
873}
874
875static const struct file_operations smk_onlycap_ops = {
876 .read = smk_read_onlycap,
877 .write = smk_write_onlycap,
878};
879
790struct option_names { 880struct option_names {
791 int o_number; 881 int o_number;
792 char *o_name; 882 char *o_name;
@@ -919,6 +1009,8 @@ static int smk_fill_super(struct super_block *sb, void *data, int silent)
919 {"ambient", &smk_ambient_ops, S_IRUGO|S_IWUSR}, 1009 {"ambient", &smk_ambient_ops, S_IRUGO|S_IWUSR},
920 [SMK_NLTYPE] = 1010 [SMK_NLTYPE] =
921 {"nltype", &smk_nltype_ops, S_IRUGO|S_IWUSR}, 1011 {"nltype", &smk_nltype_ops, S_IRUGO|S_IWUSR},
1012 [SMK_ONLYCAP] =
1013 {"onlycap", &smk_onlycap_ops, S_IRUGO|S_IWUSR},
922 /* last one */ {""} 1014 /* last one */ {""}
923 }; 1015 };
924 1016