diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-06-11 13:01:41 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-06-11 13:01:41 -0400 |
| commit | 3296ca27f50ecbd71db1d808c7a72d311027f919 (patch) | |
| tree | 833eaa58b2013bda86d4bd95faf6efad7a2d5ca4 /security/smack | |
| parent | e893123c7378192c094747dadec326b7c000c190 (diff) | |
| parent | 73fbad283cfbbcf02939bdbda31fc4a30e729cca (diff) | |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/security-testing-2.6
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/security-testing-2.6: (44 commits)
nommu: Provide mmap_min_addr definition.
TOMOYO: Add description of lists and structures.
TOMOYO: Remove unused field.
integrity: ima audit dentry_open failure
TOMOYO: Remove unused parameter.
security: use mmap_min_addr indepedently of security models
TOMOYO: Simplify policy reader.
TOMOYO: Remove redundant markers.
SELinux: define audit permissions for audit tree netlink messages
TOMOYO: Remove unused mutex.
tomoyo: avoid get+put of task_struct
smack: Remove redundant initialization.
integrity: nfsd imbalance bug fix
rootplug: Remove redundant initialization.
smack: do not beyond ARRAY_SIZE of data
integrity: move ima_counts_get
integrity: path_check update
IMA: Add __init notation to ima functions
IMA: Minimal IMA policy and boot param for TCB IMA policy
selinux: remove obsolete read buffer limit from sel_read_bool
...
Diffstat (limited to 'security/smack')
| -rw-r--r-- | security/smack/smack.h | 108 | ||||
| -rw-r--r-- | security/smack/smack_access.c | 143 | ||||
| -rw-r--r-- | security/smack/smack_lsm.c | 405 | ||||
| -rw-r--r-- | security/smack/smackfs.c | 68 |
4 files changed, 598 insertions, 126 deletions
diff --git a/security/smack/smack.h b/security/smack/smack.h index 42ef313f9856..243bec175be0 100644 --- a/security/smack/smack.h +++ b/security/smack/smack.h | |||
| @@ -20,6 +20,7 @@ | |||
| 20 | #include <net/netlabel.h> | 20 | #include <net/netlabel.h> |
| 21 | #include <linux/list.h> | 21 | #include <linux/list.h> |
| 22 | #include <linux/rculist.h> | 22 | #include <linux/rculist.h> |
| 23 | #include <linux/lsm_audit.h> | ||
| 23 | 24 | ||
| 24 | /* | 25 | /* |
| 25 | * Why 23? CIPSO is constrained to 30, so a 32 byte buffer is | 26 | * Why 23? CIPSO is constrained to 30, so a 32 byte buffer is |
| @@ -179,6 +180,20 @@ struct smack_known { | |||
| 179 | #define MAY_NOT 0 | 180 | #define MAY_NOT 0 |
| 180 | 181 | ||
| 181 | /* | 182 | /* |
| 183 | * Number of access types used by Smack (rwxa) | ||
| 184 | */ | ||
| 185 | #define SMK_NUM_ACCESS_TYPE 4 | ||
| 186 | |||
| 187 | /* | ||
| 188 | * Smack audit data; is empty if CONFIG_AUDIT not set | ||
| 189 | * to save some stack | ||
| 190 | */ | ||
| 191 | struct smk_audit_info { | ||
| 192 | #ifdef CONFIG_AUDIT | ||
| 193 | struct common_audit_data a; | ||
| 194 | #endif | ||
| 195 | }; | ||
| 196 | /* | ||
| 182 | * These functions are in smack_lsm.c | 197 | * These functions are in smack_lsm.c |
| 183 | */ | 198 | */ |
| 184 | struct inode_smack *new_inode_smack(char *); | 199 | struct inode_smack *new_inode_smack(char *); |
| @@ -186,8 +201,8 @@ struct inode_smack *new_inode_smack(char *); | |||
| 186 | /* | 201 | /* |
| 187 | * These functions are in smack_access.c | 202 | * These functions are in smack_access.c |
| 188 | */ | 203 | */ |
| 189 | int smk_access(char *, char *, int); | 204 | int smk_access(char *, char *, int, struct smk_audit_info *); |
| 190 | int smk_curacc(char *, u32); | 205 | int smk_curacc(char *, u32, struct smk_audit_info *); |
| 191 | int smack_to_cipso(const char *, struct smack_cipso *); | 206 | int smack_to_cipso(const char *, struct smack_cipso *); |
| 192 | void smack_from_cipso(u32, char *, char *); | 207 | void smack_from_cipso(u32, char *, char *); |
| 193 | char *smack_from_secid(const u32); | 208 | char *smack_from_secid(const u32); |
| @@ -237,4 +252,93 @@ static inline char *smk_of_inode(const struct inode *isp) | |||
| 237 | return sip->smk_inode; | 252 | return sip->smk_inode; |
| 238 | } | 253 | } |
| 239 | 254 | ||
| 255 | /* | ||
| 256 | * logging functions | ||
| 257 | */ | ||
| 258 | #define SMACK_AUDIT_DENIED 0x1 | ||
| 259 | #define SMACK_AUDIT_ACCEPT 0x2 | ||
| 260 | extern int log_policy; | ||
| 261 | |||
| 262 | void smack_log(char *subject_label, char *object_label, | ||
| 263 | int request, | ||
| 264 | int result, struct smk_audit_info *auditdata); | ||
| 265 | |||
| 266 | #ifdef CONFIG_AUDIT | ||
| 267 | |||
| 268 | /* | ||
| 269 | * some inline functions to set up audit data | ||
| 270 | * they do nothing if CONFIG_AUDIT is not set | ||
| 271 | * | ||
| 272 | */ | ||
| 273 | static inline void smk_ad_init(struct smk_audit_info *a, const char *func, | ||
| 274 | char type) | ||
| 275 | { | ||
| 276 | memset(a, 0, sizeof(*a)); | ||
| 277 | a->a.type = type; | ||
| 278 | a->a.function = func; | ||
| 279 | } | ||
| 280 | |||
| 281 | static inline void smk_ad_setfield_u_tsk(struct smk_audit_info *a, | ||
| 282 | struct task_struct *t) | ||
| 283 | { | ||
| 284 | a->a.u.tsk = t; | ||
| 285 | } | ||
| 286 | static inline void smk_ad_setfield_u_fs_path_dentry(struct smk_audit_info *a, | ||
| 287 | struct dentry *d) | ||
| 288 | { | ||
| 289 | a->a.u.fs.path.dentry = d; | ||
| 290 | } | ||
| 291 | static inline void smk_ad_setfield_u_fs_path_mnt(struct smk_audit_info *a, | ||
| 292 | struct vfsmount *m) | ||
| 293 | { | ||
| 294 | a->a.u.fs.path.mnt = m; | ||
| 295 | } | ||
| 296 | static inline void smk_ad_setfield_u_fs_inode(struct smk_audit_info *a, | ||
| 297 | struct inode *i) | ||
| 298 | { | ||
| 299 | a->a.u.fs.inode = i; | ||
| 300 | } | ||
| 301 | static inline void smk_ad_setfield_u_fs_path(struct smk_audit_info *a, | ||
| 302 | struct path p) | ||
| 303 | { | ||
| 304 | a->a.u.fs.path = p; | ||
| 305 | } | ||
| 306 | static inline void smk_ad_setfield_u_net_sk(struct smk_audit_info *a, | ||
| 307 | struct sock *sk) | ||
| 308 | { | ||
| 309 | a->a.u.net.sk = sk; | ||
| 310 | } | ||
| 311 | |||
| 312 | #else /* no AUDIT */ | ||
| 313 | |||
| 314 | static inline void smk_ad_init(struct smk_audit_info *a, const char *func, | ||
| 315 | char type) | ||
| 316 | { | ||
| 317 | } | ||
| 318 | static inline void smk_ad_setfield_u_tsk(struct smk_audit_info *a, | ||
| 319 | struct task_struct *t) | ||
| 320 | { | ||
| 321 | } | ||
| 322 | static inline void smk_ad_setfield_u_fs_path_dentry(struct smk_audit_info *a, | ||
| 323 | struct dentry *d) | ||
| 324 | { | ||
| 325 | } | ||
| 326 | static inline void smk_ad_setfield_u_fs_path_mnt(struct smk_audit_info *a, | ||
| 327 | struct vfsmount *m) | ||
| 328 | { | ||
| 329 | } | ||
| 330 | static inline void smk_ad_setfield_u_fs_inode(struct smk_audit_info *a, | ||
| 331 | struct inode *i) | ||
| 332 | { | ||
| 333 | } | ||
| 334 | static inline void smk_ad_setfield_u_fs_path(struct smk_audit_info *a, | ||
| 335 | struct path p) | ||
| 336 | { | ||
| 337 | } | ||
| 338 | static inline void smk_ad_setfield_u_net_sk(struct smk_audit_info *a, | ||
| 339 | struct sock *sk) | ||
| 340 | { | ||
| 341 | } | ||
| 342 | #endif | ||
| 343 | |||
| 240 | #endif /* _SECURITY_SMACK_H */ | 344 | #endif /* _SECURITY_SMACK_H */ |
diff --git a/security/smack/smack_access.c b/security/smack/smack_access.c index ac0a2707f6d4..513dc1aa16dd 100644 --- a/security/smack/smack_access.c +++ b/security/smack/smack_access.c | |||
| @@ -59,11 +59,18 @@ LIST_HEAD(smack_known_list); | |||
| 59 | */ | 59 | */ |
| 60 | static u32 smack_next_secid = 10; | 60 | static u32 smack_next_secid = 10; |
| 61 | 61 | ||
| 62 | /* | ||
| 63 | * what events do we log | ||
| 64 | * can be overwritten at run-time by /smack/logging | ||
| 65 | */ | ||
| 66 | int log_policy = SMACK_AUDIT_DENIED; | ||
| 67 | |||
| 62 | /** | 68 | /** |
| 63 | * smk_access - determine if a subject has a specific access to an object | 69 | * smk_access - determine if a subject has a specific access to an object |
| 64 | * @subject_label: a pointer to the subject's Smack label | 70 | * @subject_label: a pointer to the subject's Smack label |
| 65 | * @object_label: a pointer to the object's Smack label | 71 | * @object_label: a pointer to the object's Smack label |
| 66 | * @request: the access requested, in "MAY" format | 72 | * @request: the access requested, in "MAY" format |
| 73 | * @a : a pointer to the audit data | ||
| 67 | * | 74 | * |
| 68 | * This function looks up the subject/object pair in the | 75 | * This function looks up the subject/object pair in the |
| 69 | * access rule list and returns 0 if the access is permitted, | 76 | * access rule list and returns 0 if the access is permitted, |
| @@ -78,10 +85,12 @@ static u32 smack_next_secid = 10; | |||
| 78 | * will be on the list, so checking the pointers may be a worthwhile | 85 | * will be on the list, so checking the pointers may be a worthwhile |
| 79 | * optimization. | 86 | * optimization. |
| 80 | */ | 87 | */ |
| 81 | int smk_access(char *subject_label, char *object_label, int request) | 88 | int smk_access(char *subject_label, char *object_label, int request, |
| 89 | struct smk_audit_info *a) | ||
| 82 | { | 90 | { |
| 83 | u32 may = MAY_NOT; | 91 | u32 may = MAY_NOT; |
| 84 | struct smack_rule *srp; | 92 | struct smack_rule *srp; |
| 93 | int rc = 0; | ||
| 85 | 94 | ||
| 86 | /* | 95 | /* |
| 87 | * Hardcoded comparisons. | 96 | * Hardcoded comparisons. |
| @@ -89,8 +98,10 @@ int smk_access(char *subject_label, char *object_label, int request) | |||
| 89 | * A star subject can't access any object. | 98 | * A star subject can't access any object. |
| 90 | */ | 99 | */ |
| 91 | if (subject_label == smack_known_star.smk_known || | 100 | if (subject_label == smack_known_star.smk_known || |
| 92 | strcmp(subject_label, smack_known_star.smk_known) == 0) | 101 | strcmp(subject_label, smack_known_star.smk_known) == 0) { |
| 93 | return -EACCES; | 102 | rc = -EACCES; |
| 103 | goto out_audit; | ||
| 104 | } | ||
| 94 | /* | 105 | /* |
| 95 | * An internet object can be accessed by any subject. | 106 | * An internet object can be accessed by any subject. |
| 96 | * Tasks cannot be assigned the internet label. | 107 | * Tasks cannot be assigned the internet label. |
| @@ -100,20 +111,20 @@ int smk_access(char *subject_label, char *object_label, int request) | |||
| 100 | subject_label == smack_known_web.smk_known || | 111 | subject_label == smack_known_web.smk_known || |
| 101 | strcmp(object_label, smack_known_web.smk_known) == 0 || | 112 | strcmp(object_label, smack_known_web.smk_known) == 0 || |
| 102 | strcmp(subject_label, smack_known_web.smk_known) == 0) | 113 | strcmp(subject_label, smack_known_web.smk_known) == 0) |
| 103 | return 0; | 114 | goto out_audit; |
| 104 | /* | 115 | /* |
| 105 | * A star object can be accessed by any subject. | 116 | * A star object can be accessed by any subject. |
| 106 | */ | 117 | */ |
| 107 | if (object_label == smack_known_star.smk_known || | 118 | if (object_label == smack_known_star.smk_known || |
| 108 | strcmp(object_label, smack_known_star.smk_known) == 0) | 119 | strcmp(object_label, smack_known_star.smk_known) == 0) |
| 109 | return 0; | 120 | goto out_audit; |
| 110 | /* | 121 | /* |
| 111 | * An object can be accessed in any way by a subject | 122 | * An object can be accessed in any way by a subject |
| 112 | * with the same label. | 123 | * with the same label. |
| 113 | */ | 124 | */ |
| 114 | if (subject_label == object_label || | 125 | if (subject_label == object_label || |
| 115 | strcmp(subject_label, object_label) == 0) | 126 | strcmp(subject_label, object_label) == 0) |
| 116 | return 0; | 127 | goto out_audit; |
| 117 | /* | 128 | /* |
| 118 | * A hat subject can read any object. | 129 | * A hat subject can read any object. |
| 119 | * A floor object can be read by any subject. | 130 | * A floor object can be read by any subject. |
| @@ -121,10 +132,10 @@ int smk_access(char *subject_label, char *object_label, int request) | |||
| 121 | if ((request & MAY_ANYREAD) == request) { | 132 | if ((request & MAY_ANYREAD) == request) { |
| 122 | if (object_label == smack_known_floor.smk_known || | 133 | if (object_label == smack_known_floor.smk_known || |
| 123 | strcmp(object_label, smack_known_floor.smk_known) == 0) | 134 | strcmp(object_label, smack_known_floor.smk_known) == 0) |
| 124 | return 0; | 135 | goto out_audit; |
| 125 | if (subject_label == smack_known_hat.smk_known || | 136 | if (subject_label == smack_known_hat.smk_known || |
| 126 | strcmp(subject_label, smack_known_hat.smk_known) == 0) | 137 | strcmp(subject_label, smack_known_hat.smk_known) == 0) |
| 127 | return 0; | 138 | goto out_audit; |
| 128 | } | 139 | } |
| 129 | /* | 140 | /* |
| 130 | * Beyond here an explicit relationship is required. | 141 | * Beyond here an explicit relationship is required. |
| @@ -148,28 +159,36 @@ int smk_access(char *subject_label, char *object_label, int request) | |||
| 148 | * This is a bit map operation. | 159 | * This is a bit map operation. |
| 149 | */ | 160 | */ |
| 150 | if ((request & may) == request) | 161 | if ((request & may) == request) |
| 151 | return 0; | 162 | goto out_audit; |
| 152 | 163 | ||
| 153 | return -EACCES; | 164 | rc = -EACCES; |
| 165 | out_audit: | ||
| 166 | #ifdef CONFIG_AUDIT | ||
| 167 | if (a) | ||
| 168 | smack_log(subject_label, object_label, request, rc, a); | ||
| 169 | #endif | ||
| 170 | return rc; | ||
| 154 | } | 171 | } |
| 155 | 172 | ||
| 156 | /** | 173 | /** |
| 157 | * smk_curacc - determine if current has a specific access to an object | 174 | * smk_curacc - determine if current has a specific access to an object |
| 158 | * @obj_label: a pointer to the object's Smack label | 175 | * @obj_label: a pointer to the object's Smack label |
| 159 | * @mode: the access requested, in "MAY" format | 176 | * @mode: the access requested, in "MAY" format |
| 177 | * @a : common audit data | ||
| 160 | * | 178 | * |
| 161 | * This function checks the current subject label/object label pair | 179 | * This function checks the current subject label/object label pair |
| 162 | * in the access rule list and returns 0 if the access is permitted, | 180 | * in the access rule list and returns 0 if the access is permitted, |
| 163 | * non zero otherwise. It allows that current may have the capability | 181 | * non zero otherwise. It allows that current may have the capability |
| 164 | * to override the rules. | 182 | * to override the rules. |
| 165 | */ | 183 | */ |
| 166 | int smk_curacc(char *obj_label, u32 mode) | 184 | int smk_curacc(char *obj_label, u32 mode, struct smk_audit_info *a) |
| 167 | { | 185 | { |
| 168 | int rc; | 186 | int rc; |
| 187 | char *sp = current_security(); | ||
| 169 | 188 | ||
| 170 | rc = smk_access(current_security(), obj_label, mode); | 189 | rc = smk_access(sp, obj_label, mode, NULL); |
| 171 | if (rc == 0) | 190 | if (rc == 0) |
| 172 | return 0; | 191 | goto out_audit; |
| 173 | 192 | ||
| 174 | /* | 193 | /* |
| 175 | * Return if a specific label has been designated as the | 194 | * Return if a specific label has been designated as the |
| @@ -177,14 +196,105 @@ int smk_curacc(char *obj_label, u32 mode) | |||
| 177 | * have that label. | 196 | * have that label. |
| 178 | */ | 197 | */ |
| 179 | if (smack_onlycap != NULL && smack_onlycap != current->cred->security) | 198 | if (smack_onlycap != NULL && smack_onlycap != current->cred->security) |
| 180 | return rc; | 199 | goto out_audit; |
| 181 | 200 | ||
| 182 | if (capable(CAP_MAC_OVERRIDE)) | 201 | if (capable(CAP_MAC_OVERRIDE)) |
| 183 | return 0; | 202 | return 0; |
| 184 | 203 | ||
| 204 | out_audit: | ||
| 205 | #ifdef CONFIG_AUDIT | ||
| 206 | if (a) | ||
| 207 | smack_log(sp, obj_label, mode, rc, a); | ||
| 208 | #endif | ||
| 185 | return rc; | 209 | return rc; |
| 186 | } | 210 | } |
| 187 | 211 | ||
| 212 | #ifdef CONFIG_AUDIT | ||
| 213 | /** | ||
| 214 | * smack_str_from_perm : helper to transalate an int to a | ||
| 215 | * readable string | ||
| 216 | * @string : the string to fill | ||
| 217 | * @access : the int | ||
| 218 | * | ||
| 219 | */ | ||
| 220 | static inline void smack_str_from_perm(char *string, int access) | ||
| 221 | { | ||
| 222 | int i = 0; | ||
| 223 | if (access & MAY_READ) | ||
| 224 | string[i++] = 'r'; | ||
| 225 | if (access & MAY_WRITE) | ||
| 226 | string[i++] = 'w'; | ||
| 227 | if (access & MAY_EXEC) | ||
| 228 | string[i++] = 'x'; | ||
| 229 | if (access & MAY_APPEND) | ||
| 230 | string[i++] = 'a'; | ||
| 231 | string[i] = '\0'; | ||
| 232 | } | ||
| 233 | /** | ||
| 234 | * smack_log_callback - SMACK specific information | ||
| 235 | * will be called by generic audit code | ||
| 236 | * @ab : the audit_buffer | ||
| 237 | * @a : audit_data | ||
| 238 | * | ||
| 239 | */ | ||
| 240 | static void smack_log_callback(struct audit_buffer *ab, void *a) | ||
| 241 | { | ||
| 242 | struct common_audit_data *ad = a; | ||
| 243 | struct smack_audit_data *sad = &ad->lsm_priv.smack_audit_data; | ||
| 244 | audit_log_format(ab, "lsm=SMACK fn=%s action=%s", ad->function, | ||
| 245 | sad->result ? "denied" : "granted"); | ||
| 246 | audit_log_format(ab, " subject="); | ||
| 247 | audit_log_untrustedstring(ab, sad->subject); | ||
| 248 | audit_log_format(ab, " object="); | ||
| 249 | audit_log_untrustedstring(ab, sad->object); | ||
| 250 | audit_log_format(ab, " requested=%s", sad->request); | ||
| 251 | } | ||
| 252 | |||
| 253 | /** | ||
| 254 | * smack_log - Audit the granting or denial of permissions. | ||
| 255 | * @subject_label : smack label of the requester | ||
| 256 | * @object_label : smack label of the object being accessed | ||
| 257 | * @request: requested permissions | ||
| 258 | * @result: result from smk_access | ||
| 259 | * @a: auxiliary audit data | ||
| 260 | * | ||
| 261 | * Audit the granting or denial of permissions in accordance | ||
| 262 | * with the policy. | ||
| 263 | */ | ||
| 264 | void smack_log(char *subject_label, char *object_label, int request, | ||
| 265 | int result, struct smk_audit_info *ad) | ||
| 266 | { | ||
| 267 | char request_buffer[SMK_NUM_ACCESS_TYPE + 1]; | ||
| 268 | struct smack_audit_data *sad; | ||
| 269 | struct common_audit_data *a = &ad->a; | ||
| 270 | |||
| 271 | /* check if we have to log the current event */ | ||
| 272 | if (result != 0 && (log_policy & SMACK_AUDIT_DENIED) == 0) | ||
| 273 | return; | ||
| 274 | if (result == 0 && (log_policy & SMACK_AUDIT_ACCEPT) == 0) | ||
| 275 | return; | ||
| 276 | |||
| 277 | if (a->function == NULL) | ||
| 278 | a->function = "unknown"; | ||
| 279 | |||
| 280 | /* end preparing the audit data */ | ||
| 281 | sad = &a->lsm_priv.smack_audit_data; | ||
| 282 | smack_str_from_perm(request_buffer, request); | ||
| 283 | sad->subject = subject_label; | ||
| 284 | sad->object = object_label; | ||
| 285 | sad->request = request_buffer; | ||
| 286 | sad->result = result; | ||
| 287 | a->lsm_pre_audit = smack_log_callback; | ||
| 288 | |||
| 289 | common_lsm_audit(a); | ||
| 290 | } | ||
| 291 | #else /* #ifdef CONFIG_AUDIT */ | ||
| 292 | void smack_log(char *subject_label, char *object_label, int request, | ||
| 293 | int result, struct smk_audit_info *ad) | ||
| 294 | { | ||
| 295 | } | ||
| 296 | #endif | ||
| 297 | |||
| 188 | static DEFINE_MUTEX(smack_known_lock); | 298 | static DEFINE_MUTEX(smack_known_lock); |
| 189 | 299 | ||
| 190 | /** | 300 | /** |
| @@ -209,7 +319,8 @@ struct smack_known *smk_import_entry(const char *string, int len) | |||
| 209 | if (found) | 319 | if (found) |
| 210 | smack[i] = '\0'; | 320 | smack[i] = '\0'; |
| 211 | else if (i >= len || string[i] > '~' || string[i] <= ' ' || | 321 | else if (i >= len || string[i] > '~' || string[i] <= ' ' || |
| 212 | string[i] == '/') { | 322 | string[i] == '/' || string[i] == '"' || |
| 323 | string[i] == '\\' || string[i] == '\'') { | ||
| 213 | smack[i] = '\0'; | 324 | smack[i] = '\0'; |
| 214 | found = 1; | 325 | found = 1; |
| 215 | } else | 326 | } else |
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c index 98b3195347ab..0023182078c7 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c | |||
| @@ -30,7 +30,6 @@ | |||
| 30 | #include <net/netlabel.h> | 30 | #include <net/netlabel.h> |
| 31 | #include <net/cipso_ipv4.h> | 31 | #include <net/cipso_ipv4.h> |
| 32 | #include <linux/audit.h> | 32 | #include <linux/audit.h> |
| 33 | |||
| 34 | #include "smack.h" | 33 | #include "smack.h" |
| 35 | 34 | ||
| 36 | #define task_security(task) (task_cred_xxx((task), security)) | 35 | #define task_security(task) (task_cred_xxx((task), security)) |
| @@ -103,14 +102,24 @@ struct inode_smack *new_inode_smack(char *smack) | |||
| 103 | static int smack_ptrace_may_access(struct task_struct *ctp, unsigned int mode) | 102 | static int smack_ptrace_may_access(struct task_struct *ctp, unsigned int mode) |
| 104 | { | 103 | { |
| 105 | int rc; | 104 | int rc; |
| 105 | struct smk_audit_info ad; | ||
| 106 | char *sp, *tsp; | ||
| 106 | 107 | ||
| 107 | rc = cap_ptrace_may_access(ctp, mode); | 108 | rc = cap_ptrace_may_access(ctp, mode); |
| 108 | if (rc != 0) | 109 | if (rc != 0) |
| 109 | return rc; | 110 | return rc; |
| 110 | 111 | ||
| 111 | rc = smk_access(current_security(), task_security(ctp), MAY_READWRITE); | 112 | sp = current_security(); |
| 113 | tsp = task_security(ctp); | ||
| 114 | smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK); | ||
| 115 | smk_ad_setfield_u_tsk(&ad, ctp); | ||
| 116 | |||
| 117 | /* we won't log here, because rc can be overriden */ | ||
| 118 | rc = smk_access(sp, tsp, MAY_READWRITE, NULL); | ||
| 112 | if (rc != 0 && capable(CAP_MAC_OVERRIDE)) | 119 | if (rc != 0 && capable(CAP_MAC_OVERRIDE)) |
| 113 | return 0; | 120 | rc = 0; |
| 121 | |||
| 122 | smack_log(sp, tsp, MAY_READWRITE, rc, &ad); | ||
| 114 | return rc; | 123 | return rc; |
| 115 | } | 124 | } |
| 116 | 125 | ||
| @@ -125,14 +134,24 @@ static int smack_ptrace_may_access(struct task_struct *ctp, unsigned int mode) | |||
| 125 | static int smack_ptrace_traceme(struct task_struct *ptp) | 134 | static int smack_ptrace_traceme(struct task_struct *ptp) |
| 126 | { | 135 | { |
| 127 | int rc; | 136 | int rc; |
| 137 | struct smk_audit_info ad; | ||
| 138 | char *sp, *tsp; | ||
| 128 | 139 | ||
| 129 | rc = cap_ptrace_traceme(ptp); | 140 | rc = cap_ptrace_traceme(ptp); |
| 130 | if (rc != 0) | 141 | if (rc != 0) |
| 131 | return rc; | 142 | return rc; |
| 132 | 143 | ||
| 133 | rc = smk_access(task_security(ptp), current_security(), MAY_READWRITE); | 144 | smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK); |
| 145 | smk_ad_setfield_u_tsk(&ad, ptp); | ||
| 146 | |||
| 147 | sp = current_security(); | ||
| 148 | tsp = task_security(ptp); | ||
| 149 | /* we won't log here, because rc can be overriden */ | ||
| 150 | rc = smk_access(tsp, sp, MAY_READWRITE, NULL); | ||
| 134 | if (rc != 0 && has_capability(ptp, CAP_MAC_OVERRIDE)) | 151 | if (rc != 0 && has_capability(ptp, CAP_MAC_OVERRIDE)) |
| 135 | return 0; | 152 | rc = 0; |
| 153 | |||
| 154 | smack_log(tsp, sp, MAY_READWRITE, rc, &ad); | ||
| 136 | return rc; | 155 | return rc; |
| 137 | } | 156 | } |
| 138 | 157 | ||
| @@ -327,8 +346,14 @@ static int smack_sb_kern_mount(struct super_block *sb, int flags, void *data) | |||
| 327 | static int smack_sb_statfs(struct dentry *dentry) | 346 | static int smack_sb_statfs(struct dentry *dentry) |
| 328 | { | 347 | { |
| 329 | struct superblock_smack *sbp = dentry->d_sb->s_security; | 348 | struct superblock_smack *sbp = dentry->d_sb->s_security; |
| 349 | int rc; | ||
| 350 | struct smk_audit_info ad; | ||
| 351 | |||
| 352 | smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS); | ||
| 353 | smk_ad_setfield_u_fs_path_dentry(&ad, dentry); | ||
| 330 | 354 | ||
| 331 | return smk_curacc(sbp->smk_floor, MAY_READ); | 355 | rc = smk_curacc(sbp->smk_floor, MAY_READ, &ad); |
| 356 | return rc; | ||
| 332 | } | 357 | } |
| 333 | 358 | ||
| 334 | /** | 359 | /** |
| @@ -346,8 +371,12 @@ static int smack_sb_mount(char *dev_name, struct path *path, | |||
| 346 | char *type, unsigned long flags, void *data) | 371 | char *type, unsigned long flags, void *data) |
| 347 | { | 372 | { |
| 348 | struct superblock_smack *sbp = path->mnt->mnt_sb->s_security; | 373 | struct superblock_smack *sbp = path->mnt->mnt_sb->s_security; |
| 374 | struct smk_audit_info ad; | ||
| 375 | |||
| 376 | smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS); | ||
| 377 | smk_ad_setfield_u_fs_path(&ad, *path); | ||
| 349 | 378 | ||
| 350 | return smk_curacc(sbp->smk_floor, MAY_WRITE); | 379 | return smk_curacc(sbp->smk_floor, MAY_WRITE, &ad); |
| 351 | } | 380 | } |
| 352 | 381 | ||
| 353 | /** | 382 | /** |
| @@ -361,10 +390,14 @@ static int smack_sb_mount(char *dev_name, struct path *path, | |||
| 361 | static int smack_sb_umount(struct vfsmount *mnt, int flags) | 390 | static int smack_sb_umount(struct vfsmount *mnt, int flags) |
| 362 | { | 391 | { |
| 363 | struct superblock_smack *sbp; | 392 | struct superblock_smack *sbp; |
| 393 | struct smk_audit_info ad; | ||
| 364 | 394 | ||
| 365 | sbp = mnt->mnt_sb->s_security; | 395 | smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS); |
| 396 | smk_ad_setfield_u_fs_path_dentry(&ad, mnt->mnt_mountpoint); | ||
| 397 | smk_ad_setfield_u_fs_path_mnt(&ad, mnt); | ||
| 366 | 398 | ||
| 367 | return smk_curacc(sbp->smk_floor, MAY_WRITE); | 399 | sbp = mnt->mnt_sb->s_security; |
| 400 | return smk_curacc(sbp->smk_floor, MAY_WRITE, &ad); | ||
| 368 | } | 401 | } |
| 369 | 402 | ||
| 370 | /* | 403 | /* |
| @@ -441,15 +474,20 @@ static int smack_inode_init_security(struct inode *inode, struct inode *dir, | |||
| 441 | static int smack_inode_link(struct dentry *old_dentry, struct inode *dir, | 474 | static int smack_inode_link(struct dentry *old_dentry, struct inode *dir, |
| 442 | struct dentry *new_dentry) | 475 | struct dentry *new_dentry) |
| 443 | { | 476 | { |
| 444 | int rc; | ||
| 445 | char *isp; | 477 | char *isp; |
| 478 | struct smk_audit_info ad; | ||
| 479 | int rc; | ||
| 480 | |||
| 481 | smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS); | ||
| 482 | smk_ad_setfield_u_fs_path_dentry(&ad, old_dentry); | ||
| 446 | 483 | ||
| 447 | isp = smk_of_inode(old_dentry->d_inode); | 484 | isp = smk_of_inode(old_dentry->d_inode); |
| 448 | rc = smk_curacc(isp, MAY_WRITE); | 485 | rc = smk_curacc(isp, MAY_WRITE, &ad); |
| 449 | 486 | ||
| 450 | if (rc == 0 && new_dentry->d_inode != NULL) { | 487 | if (rc == 0 && new_dentry->d_inode != NULL) { |
| 451 | isp = smk_of_inode(new_dentry->d_inode); | 488 | isp = smk_of_inode(new_dentry->d_inode); |
| 452 | rc = smk_curacc(isp, MAY_WRITE); | 489 | smk_ad_setfield_u_fs_path_dentry(&ad, new_dentry); |
| 490 | rc = smk_curacc(isp, MAY_WRITE, &ad); | ||
| 453 | } | 491 | } |
| 454 | 492 | ||
| 455 | return rc; | 493 | return rc; |
| @@ -466,18 +504,24 @@ static int smack_inode_link(struct dentry *old_dentry, struct inode *dir, | |||
| 466 | static int smack_inode_unlink(struct inode *dir, struct dentry *dentry) | 504 | static int smack_inode_unlink(struct inode *dir, struct dentry *dentry) |
| 467 | { | 505 | { |
| 468 | struct inode *ip = dentry->d_inode; | 506 | struct inode *ip = dentry->d_inode; |
| 507 | struct smk_audit_info ad; | ||
| 469 | int rc; | 508 | int rc; |
| 470 | 509 | ||
| 510 | smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS); | ||
| 511 | smk_ad_setfield_u_fs_path_dentry(&ad, dentry); | ||
| 512 | |||
| 471 | /* | 513 | /* |
| 472 | * You need write access to the thing you're unlinking | 514 | * You need write access to the thing you're unlinking |
| 473 | */ | 515 | */ |
| 474 | rc = smk_curacc(smk_of_inode(ip), MAY_WRITE); | 516 | rc = smk_curacc(smk_of_inode(ip), MAY_WRITE, &ad); |
| 475 | if (rc == 0) | 517 | if (rc == 0) { |
| 476 | /* | 518 | /* |
| 477 | * You also need write access to the containing directory | 519 | * You also need write access to the containing directory |
| 478 | */ | 520 | */ |
| 479 | rc = smk_curacc(smk_of_inode(dir), MAY_WRITE); | 521 | smk_ad_setfield_u_fs_path_dentry(&ad, NULL); |
| 480 | 522 | smk_ad_setfield_u_fs_inode(&ad, dir); | |
| 523 | rc = smk_curacc(smk_of_inode(dir), MAY_WRITE, &ad); | ||
| 524 | } | ||
| 481 | return rc; | 525 | return rc; |
| 482 | } | 526 | } |
| 483 | 527 | ||
| @@ -491,17 +535,24 @@ static int smack_inode_unlink(struct inode *dir, struct dentry *dentry) | |||
| 491 | */ | 535 | */ |
| 492 | static int smack_inode_rmdir(struct inode *dir, struct dentry *dentry) | 536 | static int smack_inode_rmdir(struct inode *dir, struct dentry *dentry) |
| 493 | { | 537 | { |
| 538 | struct smk_audit_info ad; | ||
| 494 | int rc; | 539 | int rc; |
| 495 | 540 | ||
| 541 | smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS); | ||
| 542 | smk_ad_setfield_u_fs_path_dentry(&ad, dentry); | ||
| 543 | |||
| 496 | /* | 544 | /* |
| 497 | * You need write access to the thing you're removing | 545 | * You need write access to the thing you're removing |
| 498 | */ | 546 | */ |
| 499 | rc = smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE); | 547 | rc = smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE, &ad); |
| 500 | if (rc == 0) | 548 | if (rc == 0) { |
| 501 | /* | 549 | /* |
| 502 | * You also need write access to the containing directory | 550 | * You also need write access to the containing directory |
| 503 | */ | 551 | */ |
| 504 | rc = smk_curacc(smk_of_inode(dir), MAY_WRITE); | 552 | smk_ad_setfield_u_fs_path_dentry(&ad, NULL); |
| 553 | smk_ad_setfield_u_fs_inode(&ad, dir); | ||
| 554 | rc = smk_curacc(smk_of_inode(dir), MAY_WRITE, &ad); | ||
| 555 | } | ||
| 505 | 556 | ||
| 506 | return rc; | 557 | return rc; |
| 507 | } | 558 | } |
| @@ -525,15 +576,19 @@ static int smack_inode_rename(struct inode *old_inode, | |||
| 525 | { | 576 | { |
| 526 | int rc; | 577 | int rc; |
| 527 | char *isp; | 578 | char *isp; |
| 579 | struct smk_audit_info ad; | ||
| 580 | |||
| 581 | smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS); | ||
| 582 | smk_ad_setfield_u_fs_path_dentry(&ad, old_dentry); | ||
| 528 | 583 | ||
| 529 | isp = smk_of_inode(old_dentry->d_inode); | 584 | isp = smk_of_inode(old_dentry->d_inode); |
| 530 | rc = smk_curacc(isp, MAY_READWRITE); | 585 | rc = smk_curacc(isp, MAY_READWRITE, &ad); |
| 531 | 586 | ||
| 532 | if (rc == 0 && new_dentry->d_inode != NULL) { | 587 | if (rc == 0 && new_dentry->d_inode != NULL) { |
| 533 | isp = smk_of_inode(new_dentry->d_inode); | 588 | isp = smk_of_inode(new_dentry->d_inode); |
| 534 | rc = smk_curacc(isp, MAY_READWRITE); | 589 | smk_ad_setfield_u_fs_path_dentry(&ad, new_dentry); |
| 590 | rc = smk_curacc(isp, MAY_READWRITE, &ad); | ||
| 535 | } | 591 | } |
| 536 | |||
| 537 | return rc; | 592 | return rc; |
| 538 | } | 593 | } |
| 539 | 594 | ||
| @@ -548,13 +603,15 @@ static int smack_inode_rename(struct inode *old_inode, | |||
| 548 | */ | 603 | */ |
| 549 | static int smack_inode_permission(struct inode *inode, int mask) | 604 | static int smack_inode_permission(struct inode *inode, int mask) |
| 550 | { | 605 | { |
| 606 | struct smk_audit_info ad; | ||
| 551 | /* | 607 | /* |
| 552 | * No permission to check. Existence test. Yup, it's there. | 608 | * No permission to check. Existence test. Yup, it's there. |
| 553 | */ | 609 | */ |
| 554 | if (mask == 0) | 610 | if (mask == 0) |
| 555 | return 0; | 611 | return 0; |
| 556 | 612 | smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS); | |
| 557 | return smk_curacc(smk_of_inode(inode), mask); | 613 | smk_ad_setfield_u_fs_inode(&ad, inode); |
| 614 | return smk_curacc(smk_of_inode(inode), mask, &ad); | ||
| 558 | } | 615 | } |
| 559 | 616 | ||
| 560 | /** | 617 | /** |
| @@ -566,13 +623,16 @@ static int smack_inode_permission(struct inode *inode, int mask) | |||
| 566 | */ | 623 | */ |
| 567 | static int smack_inode_setattr(struct dentry *dentry, struct iattr *iattr) | 624 | static int smack_inode_setattr(struct dentry *dentry, struct iattr *iattr) |
| 568 | { | 625 | { |
| 626 | struct smk_audit_info ad; | ||
| 569 | /* | 627 | /* |
| 570 | * Need to allow for clearing the setuid bit. | 628 | * Need to allow for clearing the setuid bit. |
| 571 | */ | 629 | */ |
| 572 | if (iattr->ia_valid & ATTR_FORCE) | 630 | if (iattr->ia_valid & ATTR_FORCE) |
| 573 | return 0; | 631 | return 0; |
| 632 | smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS); | ||
| 633 | smk_ad_setfield_u_fs_path_dentry(&ad, dentry); | ||
| 574 | 634 | ||
| 575 | return smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE); | 635 | return smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE, &ad); |
| 576 | } | 636 | } |
| 577 | 637 | ||
| 578 | /** | 638 | /** |
| @@ -584,7 +644,12 @@ static int smack_inode_setattr(struct dentry *dentry, struct iattr *iattr) | |||
| 584 | */ | 644 | */ |
| 585 | static int smack_inode_getattr(struct vfsmount *mnt, struct dentry *dentry) | 645 | static int smack_inode_getattr(struct vfsmount *mnt, struct dentry *dentry) |
| 586 | { | 646 | { |
| 587 | return smk_curacc(smk_of_inode(dentry->d_inode), MAY_READ); | 647 | struct smk_audit_info ad; |
| 648 | |||
| 649 | smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS); | ||
| 650 | smk_ad_setfield_u_fs_path_dentry(&ad, dentry); | ||
| 651 | smk_ad_setfield_u_fs_path_mnt(&ad, mnt); | ||
| 652 | return smk_curacc(smk_of_inode(dentry->d_inode), MAY_READ, &ad); | ||
| 588 | } | 653 | } |
| 589 | 654 | ||
| 590 | /** | 655 | /** |
| @@ -602,6 +667,7 @@ static int smack_inode_getattr(struct vfsmount *mnt, struct dentry *dentry) | |||
| 602 | static int smack_inode_setxattr(struct dentry *dentry, const char *name, | 667 | static int smack_inode_setxattr(struct dentry *dentry, const char *name, |
| 603 | const void *value, size_t size, int flags) | 668 | const void *value, size_t size, int flags) |
| 604 | { | 669 | { |
| 670 | struct smk_audit_info ad; | ||
| 605 | int rc = 0; | 671 | int rc = 0; |
| 606 | 672 | ||
| 607 | if (strcmp(name, XATTR_NAME_SMACK) == 0 || | 673 | if (strcmp(name, XATTR_NAME_SMACK) == 0 || |
| @@ -619,8 +685,11 @@ static int smack_inode_setxattr(struct dentry *dentry, const char *name, | |||
| 619 | } else | 685 | } else |
| 620 | rc = cap_inode_setxattr(dentry, name, value, size, flags); | 686 | rc = cap_inode_setxattr(dentry, name, value, size, flags); |
| 621 | 687 | ||
| 688 | smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS); | ||
| 689 | smk_ad_setfield_u_fs_path_dentry(&ad, dentry); | ||
| 690 | |||
| 622 | if (rc == 0) | 691 | if (rc == 0) |
| 623 | rc = smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE); | 692 | rc = smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE, &ad); |
| 624 | 693 | ||
| 625 | return rc; | 694 | return rc; |
| 626 | } | 695 | } |
| @@ -672,7 +741,12 @@ static void smack_inode_post_setxattr(struct dentry *dentry, const char *name, | |||
| 672 | */ | 741 | */ |
| 673 | static int smack_inode_getxattr(struct dentry *dentry, const char *name) | 742 | static int smack_inode_getxattr(struct dentry *dentry, const char *name) |
| 674 | { | 743 | { |
| 675 | return smk_curacc(smk_of_inode(dentry->d_inode), MAY_READ); | 744 | struct smk_audit_info ad; |
| 745 | |||
| 746 | smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS); | ||
| 747 | smk_ad_setfield_u_fs_path_dentry(&ad, dentry); | ||
| 748 | |||
| 749 | return smk_curacc(smk_of_inode(dentry->d_inode), MAY_READ, &ad); | ||
| 676 | } | 750 | } |
| 677 | 751 | ||
| 678 | /* | 752 | /* |
| @@ -686,6 +760,7 @@ static int smack_inode_getxattr(struct dentry *dentry, const char *name) | |||
| 686 | */ | 760 | */ |
| 687 | static int smack_inode_removexattr(struct dentry *dentry, const char *name) | 761 | static int smack_inode_removexattr(struct dentry *dentry, const char *name) |
| 688 | { | 762 | { |
| 763 | struct smk_audit_info ad; | ||
| 689 | int rc = 0; | 764 | int rc = 0; |
| 690 | 765 | ||
| 691 | if (strcmp(name, XATTR_NAME_SMACK) == 0 || | 766 | if (strcmp(name, XATTR_NAME_SMACK) == 0 || |
| @@ -696,8 +771,10 @@ static int smack_inode_removexattr(struct dentry *dentry, const char *name) | |||
| 696 | } else | 771 | } else |
| 697 | rc = cap_inode_removexattr(dentry, name); | 772 | rc = cap_inode_removexattr(dentry, name); |
| 698 | 773 | ||
| 774 | smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS); | ||
| 775 | smk_ad_setfield_u_fs_path_dentry(&ad, dentry); | ||
| 699 | if (rc == 0) | 776 | if (rc == 0) |
| 700 | rc = smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE); | 777 | rc = smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE, &ad); |
| 701 | 778 | ||
| 702 | return rc; | 779 | return rc; |
| 703 | } | 780 | } |
| @@ -856,12 +933,16 @@ static int smack_file_ioctl(struct file *file, unsigned int cmd, | |||
| 856 | unsigned long arg) | 933 | unsigned long arg) |
| 857 | { | 934 | { |
| 858 | int rc = 0; | 935 | int rc = 0; |
| 936 | struct smk_audit_info ad; | ||
| 937 | |||
| 938 | smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS); | ||
| 939 | smk_ad_setfield_u_fs_path(&ad, file->f_path); | ||
| 859 | 940 | ||
| 860 | if (_IOC_DIR(cmd) & _IOC_WRITE) | 941 | if (_IOC_DIR(cmd) & _IOC_WRITE) |
| 861 | rc = smk_curacc(file->f_security, MAY_WRITE); | 942 | rc = smk_curacc(file->f_security, MAY_WRITE, &ad); |
| 862 | 943 | ||
| 863 | if (rc == 0 && (_IOC_DIR(cmd) & _IOC_READ)) | 944 | if (rc == 0 && (_IOC_DIR(cmd) & _IOC_READ)) |
| 864 | rc = smk_curacc(file->f_security, MAY_READ); | 945 | rc = smk_curacc(file->f_security, MAY_READ, &ad); |
| 865 | 946 | ||
| 866 | return rc; | 947 | return rc; |
| 867 | } | 948 | } |
| @@ -875,7 +956,11 @@ static int smack_file_ioctl(struct file *file, unsigned int cmd, | |||
| 875 | */ | 956 | */ |
| 876 | static int smack_file_lock(struct file *file, unsigned int cmd) | 957 | static int smack_file_lock(struct file *file, unsigned int cmd) |
| 877 | { | 958 | { |
| 878 | return smk_curacc(file->f_security, MAY_WRITE); | 959 | struct smk_audit_info ad; |
| 960 | |||
| 961 | smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS); | ||
| 962 | smk_ad_setfield_u_fs_path_dentry(&ad, file->f_path.dentry); | ||
| 963 | return smk_curacc(file->f_security, MAY_WRITE, &ad); | ||
| 879 | } | 964 | } |
| 880 | 965 | ||
| 881 | /** | 966 | /** |
| @@ -889,8 +974,12 @@ static int smack_file_lock(struct file *file, unsigned int cmd) | |||
| 889 | static int smack_file_fcntl(struct file *file, unsigned int cmd, | 974 | static int smack_file_fcntl(struct file *file, unsigned int cmd, |
| 890 | unsigned long arg) | 975 | unsigned long arg) |
| 891 | { | 976 | { |
| 977 | struct smk_audit_info ad; | ||
| 892 | int rc; | 978 | int rc; |
| 893 | 979 | ||
| 980 | smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS); | ||
| 981 | smk_ad_setfield_u_fs_path(&ad, file->f_path); | ||
| 982 | |||
| 894 | switch (cmd) { | 983 | switch (cmd) { |
| 895 | case F_DUPFD: | 984 | case F_DUPFD: |
| 896 | case F_GETFD: | 985 | case F_GETFD: |
| @@ -898,7 +987,7 @@ static int smack_file_fcntl(struct file *file, unsigned int cmd, | |||
| 898 | case F_GETLK: | 987 | case F_GETLK: |
| 899 | case F_GETOWN: | 988 | case F_GETOWN: |
| 900 | case F_GETSIG: | 989 | case F_GETSIG: |
| 901 | rc = smk_curacc(file->f_security, MAY_READ); | 990 | rc = smk_curacc(file->f_security, MAY_READ, &ad); |
| 902 | break; | 991 | break; |
| 903 | case F_SETFD: | 992 | case F_SETFD: |
| 904 | case F_SETFL: | 993 | case F_SETFL: |
| @@ -906,10 +995,10 @@ static int smack_file_fcntl(struct file *file, unsigned int cmd, | |||
| 906 | case F_SETLKW: | 995 | case F_SETLKW: |
| 907 | case F_SETOWN: | 996 | case F_SETOWN: |
| 908 | case F_SETSIG: | 997 | case F_SETSIG: |
| 909 | rc = smk_curacc(file->f_security, MAY_WRITE); | 998 | rc = smk_curacc(file->f_security, MAY_WRITE, &ad); |
| 910 | break; | 999 | break; |
| 911 | default: | 1000 | default: |
| 912 | rc = smk_curacc(file->f_security, MAY_READWRITE); | 1001 | rc = smk_curacc(file->f_security, MAY_READWRITE, &ad); |
| 913 | } | 1002 | } |
| 914 | 1003 | ||
| 915 | return rc; | 1004 | return rc; |
| @@ -944,14 +1033,21 @@ static int smack_file_send_sigiotask(struct task_struct *tsk, | |||
| 944 | { | 1033 | { |
| 945 | struct file *file; | 1034 | struct file *file; |
| 946 | int rc; | 1035 | int rc; |
| 1036 | char *tsp = tsk->cred->security; | ||
| 1037 | struct smk_audit_info ad; | ||
| 947 | 1038 | ||
| 948 | /* | 1039 | /* |
| 949 | * struct fown_struct is never outside the context of a struct file | 1040 | * struct fown_struct is never outside the context of a struct file |
| 950 | */ | 1041 | */ |
| 951 | file = container_of(fown, struct file, f_owner); | 1042 | file = container_of(fown, struct file, f_owner); |
| 952 | rc = smk_access(file->f_security, tsk->cred->security, MAY_WRITE); | 1043 | /* we don't log here as rc can be overriden */ |
| 1044 | rc = smk_access(file->f_security, tsp, MAY_WRITE, NULL); | ||
| 953 | if (rc != 0 && has_capability(tsk, CAP_MAC_OVERRIDE)) | 1045 | if (rc != 0 && has_capability(tsk, CAP_MAC_OVERRIDE)) |
| 954 | return 0; | 1046 | rc = 0; |
| 1047 | |||
| 1048 | smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK); | ||
| 1049 | smk_ad_setfield_u_tsk(&ad, tsk); | ||
| 1050 | smack_log(file->f_security, tsp, MAY_WRITE, rc, &ad); | ||
| 955 | return rc; | 1051 | return rc; |
| 956 | } | 1052 | } |
| 957 | 1053 | ||
| @@ -964,7 +1060,10 @@ static int smack_file_send_sigiotask(struct task_struct *tsk, | |||
| 964 | static int smack_file_receive(struct file *file) | 1060 | static int smack_file_receive(struct file *file) |
| 965 | { | 1061 | { |
| 966 | int may = 0; | 1062 | int may = 0; |
| 1063 | struct smk_audit_info ad; | ||
| 967 | 1064 | ||
| 1065 | smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK); | ||
| 1066 | smk_ad_setfield_u_fs_path(&ad, file->f_path); | ||
| 968 | /* | 1067 | /* |
| 969 | * This code relies on bitmasks. | 1068 | * This code relies on bitmasks. |
| 970 | */ | 1069 | */ |
| @@ -973,7 +1072,7 @@ static int smack_file_receive(struct file *file) | |||
| 973 | if (file->f_mode & FMODE_WRITE) | 1072 | if (file->f_mode & FMODE_WRITE) |
| 974 | may |= MAY_WRITE; | 1073 | may |= MAY_WRITE; |
| 975 | 1074 | ||
| 976 | return smk_curacc(file->f_security, may); | 1075 | return smk_curacc(file->f_security, may, &ad); |
| 977 | } | 1076 | } |
| 978 | 1077 | ||
| 979 | /* | 1078 | /* |
| @@ -1053,6 +1152,22 @@ static int smack_kernel_create_files_as(struct cred *new, | |||
| 1053 | } | 1152 | } |
| 1054 | 1153 | ||
| 1055 | /** | 1154 | /** |
| 1155 | * smk_curacc_on_task - helper to log task related access | ||
| 1156 | * @p: the task object | ||
| 1157 | * @access : the access requested | ||
| 1158 | * | ||
| 1159 | * Return 0 if access is permitted | ||
| 1160 | */ | ||
| 1161 | static int smk_curacc_on_task(struct task_struct *p, int access) | ||
| 1162 | { | ||
| 1163 | struct smk_audit_info ad; | ||
| 1164 | |||
| 1165 | smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK); | ||
| 1166 | smk_ad_setfield_u_tsk(&ad, p); | ||
| 1167 | return smk_curacc(task_security(p), access, &ad); | ||
| 1168 | } | ||
| 1169 | |||
| 1170 | /** | ||
| 1056 | * smack_task_setpgid - Smack check on setting pgid | 1171 | * smack_task_setpgid - Smack check on setting pgid |
| 1057 | * @p: the task object | 1172 | * @p: the task object |
| 1058 | * @pgid: unused | 1173 | * @pgid: unused |
| @@ -1061,7 +1176,7 @@ static int smack_kernel_create_files_as(struct cred *new, | |||
| 1061 | */ | 1176 | */ |
| 1062 | static int smack_task_setpgid(struct task_struct *p, pid_t pgid) | 1177 | static int smack_task_setpgid(struct task_struct *p, pid_t pgid) |
| 1063 | { | 1178 | { |
| 1064 | return smk_curacc(task_security(p), MAY_WRITE); | 1179 | return smk_curacc_on_task(p, MAY_WRITE); |
| 1065 | } | 1180 | } |
| 1066 | 1181 | ||
| 1067 | /** | 1182 | /** |
| @@ -1072,7 +1187,7 @@ static int smack_task_setpgid(struct task_struct *p, pid_t pgid) | |||
| 1072 | */ | 1187 | */ |
| 1073 | static int smack_task_getpgid(struct task_struct *p) | 1188 | static int smack_task_getpgid(struct task_struct *p) |
| 1074 | { | 1189 | { |
| 1075 | return smk_curacc(task_security(p), MAY_READ); | 1190 | return smk_curacc_on_task(p, MAY_READ); |
| 1076 | } | 1191 | } |
| 1077 | 1192 | ||
| 1078 | /** | 1193 | /** |
| @@ -1083,7 +1198,7 @@ static int smack_task_getpgid(struct task_struct *p) | |||
| 1083 | */ | 1198 | */ |
| 1084 | static int smack_task_getsid(struct task_struct *p) | 1199 | static int smack_task_getsid(struct task_struct *p) |
| 1085 | { | 1200 | { |
| 1086 | return smk_curacc(task_security(p), MAY_READ); | 1201 | return smk_curacc_on_task(p, MAY_READ); |
| 1087 | } | 1202 | } |
| 1088 | 1203 | ||
| 1089 | /** | 1204 | /** |
| @@ -1111,7 +1226,7 @@ static int smack_task_setnice(struct task_struct *p, int nice) | |||
| 1111 | 1226 | ||
| 1112 | rc = cap_task_setnice(p, nice); | 1227 | rc = cap_task_setnice(p, nice); |
| 1113 | if (rc == 0) | 1228 | if (rc == 0) |
| 1114 | rc = smk_curacc(task_security(p), MAY_WRITE); | 1229 | rc = smk_curacc_on_task(p, MAY_WRITE); |
| 1115 | return rc; | 1230 | return rc; |
| 1116 | } | 1231 | } |
| 1117 | 1232 | ||
| @@ -1128,7 +1243,7 @@ static int smack_task_setioprio(struct task_struct *p, int ioprio) | |||
| 1128 | 1243 | ||
| 1129 | rc = cap_task_setioprio(p, ioprio); | 1244 | rc = cap_task_setioprio(p, ioprio); |
| 1130 | if (rc == 0) | 1245 | if (rc == 0) |
| 1131 | rc = smk_curacc(task_security(p), MAY_WRITE); | 1246 | rc = smk_curacc_on_task(p, MAY_WRITE); |
| 1132 | return rc; | 1247 | return rc; |
| 1133 | } | 1248 | } |
| 1134 | 1249 | ||
| @@ -1140,7 +1255,7 @@ static int smack_task_setioprio(struct task_struct *p, int ioprio) | |||
| 1140 | */ | 1255 | */ |
| 1141 | static int smack_task_getioprio(struct task_struct *p) | 1256 | static int smack_task_getioprio(struct task_struct *p) |
| 1142 | { | 1257 | { |
| 1143 | return smk_curacc(task_security(p), MAY_READ); | 1258 | return smk_curacc_on_task(p, MAY_READ); |
| 1144 | } | 1259 | } |
| 1145 | 1260 | ||
| 1146 | /** | 1261 | /** |
| @@ -1158,7 +1273,7 @@ static int smack_task_setscheduler(struct task_struct *p, int policy, | |||
| 1158 | 1273 | ||
| 1159 | rc = cap_task_setscheduler(p, policy, lp); | 1274 | rc = cap_task_setscheduler(p, policy, lp); |
| 1160 | if (rc == 0) | 1275 | if (rc == 0) |
| 1161 | rc = smk_curacc(task_security(p), MAY_WRITE); | 1276 | rc = smk_curacc_on_task(p, MAY_WRITE); |
| 1162 | return rc; | 1277 | return rc; |
| 1163 | } | 1278 | } |
| 1164 | 1279 | ||
| @@ -1170,7 +1285,7 @@ static int smack_task_setscheduler(struct task_struct *p, int policy, | |||
| 1170 | */ | 1285 | */ |
| 1171 | static int smack_task_getscheduler(struct task_struct *p) | 1286 | static int smack_task_getscheduler(struct task_struct *p) |
| 1172 | { | 1287 | { |
| 1173 | return smk_curacc(task_security(p), MAY_READ); | 1288 | return smk_curacc_on_task(p, MAY_READ); |
| 1174 | } | 1289 | } |
| 1175 | 1290 | ||
| 1176 | /** | 1291 | /** |
| @@ -1181,7 +1296,7 @@ static int smack_task_getscheduler(struct task_struct *p) | |||
| 1181 | */ | 1296 | */ |
| 1182 | static int smack_task_movememory(struct task_struct *p) | 1297 | static int smack_task_movememory(struct task_struct *p) |
| 1183 | { | 1298 | { |
| 1184 | return smk_curacc(task_security(p), MAY_WRITE); | 1299 | return smk_curacc_on_task(p, MAY_WRITE); |
| 1185 | } | 1300 | } |
| 1186 | 1301 | ||
| 1187 | /** | 1302 | /** |
| @@ -1199,18 +1314,23 @@ static int smack_task_movememory(struct task_struct *p) | |||
| 1199 | static int smack_task_kill(struct task_struct *p, struct siginfo *info, | 1314 | static int smack_task_kill(struct task_struct *p, struct siginfo *info, |
| 1200 | int sig, u32 secid) | 1315 | int sig, u32 secid) |
| 1201 | { | 1316 | { |
| 1317 | struct smk_audit_info ad; | ||
| 1318 | |||
| 1319 | smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK); | ||
| 1320 | smk_ad_setfield_u_tsk(&ad, p); | ||
| 1202 | /* | 1321 | /* |
| 1203 | * Sending a signal requires that the sender | 1322 | * Sending a signal requires that the sender |
| 1204 | * can write the receiver. | 1323 | * can write the receiver. |
| 1205 | */ | 1324 | */ |
| 1206 | if (secid == 0) | 1325 | if (secid == 0) |
| 1207 | return smk_curacc(task_security(p), MAY_WRITE); | 1326 | return smk_curacc(task_security(p), MAY_WRITE, &ad); |
| 1208 | /* | 1327 | /* |
| 1209 | * If the secid isn't 0 we're dealing with some USB IO | 1328 | * If the secid isn't 0 we're dealing with some USB IO |
| 1210 | * specific behavior. This is not clean. For one thing | 1329 | * specific behavior. This is not clean. For one thing |
| 1211 | * we can't take privilege into account. | 1330 | * we can't take privilege into account. |
| 1212 | */ | 1331 | */ |
| 1213 | return smk_access(smack_from_secid(secid), task_security(p), MAY_WRITE); | 1332 | return smk_access(smack_from_secid(secid), task_security(p), |
| 1333 | MAY_WRITE, &ad); | ||
| 1214 | } | 1334 | } |
| 1215 | 1335 | ||
| 1216 | /** | 1336 | /** |
| @@ -1221,11 +1341,15 @@ static int smack_task_kill(struct task_struct *p, struct siginfo *info, | |||
| 1221 | */ | 1341 | */ |
| 1222 | static int smack_task_wait(struct task_struct *p) | 1342 | static int smack_task_wait(struct task_struct *p) |
| 1223 | { | 1343 | { |
| 1344 | struct smk_audit_info ad; | ||
| 1345 | char *sp = current_security(); | ||
| 1346 | char *tsp = task_security(p); | ||
| 1224 | int rc; | 1347 | int rc; |
| 1225 | 1348 | ||
| 1226 | rc = smk_access(current_security(), task_security(p), MAY_WRITE); | 1349 | /* we don't log here, we can be overriden */ |
| 1350 | rc = smk_access(sp, tsp, MAY_WRITE, NULL); | ||
| 1227 | if (rc == 0) | 1351 | if (rc == 0) |
| 1228 | return 0; | 1352 | goto out_log; |
| 1229 | 1353 | ||
| 1230 | /* | 1354 | /* |
| 1231 | * Allow the operation to succeed if either task | 1355 | * Allow the operation to succeed if either task |
| @@ -1239,8 +1363,12 @@ static int smack_task_wait(struct task_struct *p) | |||
| 1239 | * the smack value. | 1363 | * the smack value. |
| 1240 | */ | 1364 | */ |
| 1241 | if (capable(CAP_MAC_OVERRIDE) || has_capability(p, CAP_MAC_OVERRIDE)) | 1365 | if (capable(CAP_MAC_OVERRIDE) || has_capability(p, CAP_MAC_OVERRIDE)) |
| 1242 | return 0; | 1366 | rc = 0; |
| 1243 | 1367 | /* we log only if we didn't get overriden */ | |
| 1368 | out_log: | ||
| 1369 | smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK); | ||
| 1370 | smk_ad_setfield_u_tsk(&ad, p); | ||
| 1371 | smack_log(sp, tsp, MAY_WRITE, rc, &ad); | ||
| 1244 | return rc; | 1372 | return rc; |
| 1245 | } | 1373 | } |
| 1246 | 1374 | ||
| @@ -1456,12 +1584,19 @@ static int smack_netlabel_send(struct sock *sk, struct sockaddr_in *sap) | |||
| 1456 | int sk_lbl; | 1584 | int sk_lbl; |
| 1457 | char *hostsp; | 1585 | char *hostsp; |
| 1458 | struct socket_smack *ssp = sk->sk_security; | 1586 | struct socket_smack *ssp = sk->sk_security; |
| 1587 | struct smk_audit_info ad; | ||
| 1459 | 1588 | ||
| 1460 | rcu_read_lock(); | 1589 | rcu_read_lock(); |
| 1461 | hostsp = smack_host_label(sap); | 1590 | hostsp = smack_host_label(sap); |
| 1462 | if (hostsp != NULL) { | 1591 | if (hostsp != NULL) { |
| 1463 | sk_lbl = SMACK_UNLABELED_SOCKET; | 1592 | sk_lbl = SMACK_UNLABELED_SOCKET; |
| 1464 | rc = smk_access(ssp->smk_out, hostsp, MAY_WRITE); | 1593 | #ifdef CONFIG_AUDIT |
| 1594 | smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_NET); | ||
| 1595 | ad.a.u.net.family = sap->sin_family; | ||
| 1596 | ad.a.u.net.dport = sap->sin_port; | ||
| 1597 | ad.a.u.net.v4info.daddr = sap->sin_addr.s_addr; | ||
| 1598 | #endif | ||
| 1599 | rc = smk_access(ssp->smk_out, hostsp, MAY_WRITE, &ad); | ||
| 1465 | } else { | 1600 | } else { |
| 1466 | sk_lbl = SMACK_CIPSO_SOCKET; | 1601 | sk_lbl = SMACK_CIPSO_SOCKET; |
| 1467 | rc = 0; | 1602 | rc = 0; |
| @@ -1657,6 +1792,25 @@ static void smack_shm_free_security(struct shmid_kernel *shp) | |||
| 1657 | } | 1792 | } |
| 1658 | 1793 | ||
| 1659 | /** | 1794 | /** |
| 1795 | * smk_curacc_shm : check if current has access on shm | ||
| 1796 | * @shp : the object | ||
| 1797 | * @access : access requested | ||
| 1798 | * | ||
| 1799 | * Returns 0 if current has the requested access, error code otherwise | ||
| 1800 | */ | ||
| 1801 | static int smk_curacc_shm(struct shmid_kernel *shp, int access) | ||
| 1802 | { | ||
| 1803 | char *ssp = smack_of_shm(shp); | ||
| 1804 | struct smk_audit_info ad; | ||
| 1805 | |||
| 1806 | #ifdef CONFIG_AUDIT | ||
| 1807 | smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_IPC); | ||
| 1808 | ad.a.u.ipc_id = shp->shm_perm.id; | ||
| 1809 | #endif | ||
| 1810 | return smk_curacc(ssp, access, &ad); | ||
| 1811 | } | ||
| 1812 | |||
| 1813 | /** | ||
| 1660 | * smack_shm_associate - Smack access check for shm | 1814 | * smack_shm_associate - Smack access check for shm |
| 1661 | * @shp: the object | 1815 | * @shp: the object |
| 1662 | * @shmflg: access requested | 1816 | * @shmflg: access requested |
| @@ -1665,11 +1819,10 @@ static void smack_shm_free_security(struct shmid_kernel *shp) | |||
| 1665 | */ | 1819 | */ |
| 1666 | static int smack_shm_associate(struct shmid_kernel *shp, int shmflg) | 1820 | static int smack_shm_associate(struct shmid_kernel *shp, int shmflg) |
| 1667 | { | 1821 | { |
| 1668 | char *ssp = smack_of_shm(shp); | ||
| 1669 | int may; | 1822 | int may; |
| 1670 | 1823 | ||
| 1671 | may = smack_flags_to_may(shmflg); | 1824 | may = smack_flags_to_may(shmflg); |
| 1672 | return smk_curacc(ssp, may); | 1825 | return smk_curacc_shm(shp, may); |
| 1673 | } | 1826 | } |
| 1674 | 1827 | ||
| 1675 | /** | 1828 | /** |
| @@ -1681,7 +1834,6 @@ static int smack_shm_associate(struct shmid_kernel *shp, int shmflg) | |||
| 1681 | */ | 1834 | */ |
| 1682 | static int smack_shm_shmctl(struct shmid_kernel *shp, int cmd) | 1835 | static int smack_shm_shmctl(struct shmid_kernel *shp, int cmd) |
| 1683 | { | 1836 | { |
| 1684 | char *ssp; | ||
| 1685 | int may; | 1837 | int may; |
| 1686 | 1838 | ||
| 1687 | switch (cmd) { | 1839 | switch (cmd) { |
| @@ -1704,9 +1856,7 @@ static int smack_shm_shmctl(struct shmid_kernel *shp, int cmd) | |||
| 1704 | default: | 1856 | default: |
| 1705 | return -EINVAL; | 1857 | return -EINVAL; |
| 1706 | } | 1858 | } |
| 1707 | 1859 | return smk_curacc_shm(shp, may); | |
| 1708 | ssp = smack_of_shm(shp); | ||
| 1709 | return smk_curacc(ssp, may); | ||
| 1710 | } | 1860 | } |
| 1711 | 1861 | ||
| 1712 | /** | 1862 | /** |
| @@ -1720,11 +1870,10 @@ static int smack_shm_shmctl(struct shmid_kernel *shp, int cmd) | |||
| 1720 | static int smack_shm_shmat(struct shmid_kernel *shp, char __user *shmaddr, | 1870 | static int smack_shm_shmat(struct shmid_kernel *shp, char __user *shmaddr, |
| 1721 | int shmflg) | 1871 | int shmflg) |
| 1722 | { | 1872 | { |
| 1723 | char *ssp = smack_of_shm(shp); | ||
| 1724 | int may; | 1873 | int may; |
| 1725 | 1874 | ||
| 1726 | may = smack_flags_to_may(shmflg); | 1875 | may = smack_flags_to_may(shmflg); |
| 1727 | return smk_curacc(ssp, may); | 1876 | return smk_curacc_shm(shp, may); |
| 1728 | } | 1877 | } |
| 1729 | 1878 | ||
| 1730 | /** | 1879 | /** |
| @@ -1766,6 +1915,25 @@ static void smack_sem_free_security(struct sem_array *sma) | |||
| 1766 | } | 1915 | } |
| 1767 | 1916 | ||
| 1768 | /** | 1917 | /** |
| 1918 | * smk_curacc_sem : check if current has access on sem | ||
| 1919 | * @sma : the object | ||
| 1920 | * @access : access requested | ||
| 1921 | * | ||
| 1922 | * Returns 0 if current has the requested access, error code otherwise | ||
| 1923 | */ | ||
| 1924 | static int smk_curacc_sem(struct sem_array *sma, int access) | ||
| 1925 | { | ||
| 1926 | char *ssp = smack_of_sem(sma); | ||
| 1927 | struct smk_audit_info ad; | ||
| 1928 | |||
| 1929 | #ifdef CONFIG_AUDIT | ||
| 1930 | smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_IPC); | ||
| 1931 | ad.a.u.ipc_id = sma->sem_perm.id; | ||
| 1932 | #endif | ||
| 1933 | return smk_curacc(ssp, access, &ad); | ||
| 1934 | } | ||
| 1935 | |||
| 1936 | /** | ||
| 1769 | * smack_sem_associate - Smack access check for sem | 1937 | * smack_sem_associate - Smack access check for sem |
| 1770 | * @sma: the object | 1938 | * @sma: the object |
| 1771 | * @semflg: access requested | 1939 | * @semflg: access requested |
| @@ -1774,11 +1942,10 @@ static void smack_sem_free_security(struct sem_array *sma) | |||
| 1774 | */ | 1942 | */ |
| 1775 | static int smack_sem_associate(struct sem_array *sma, int semflg) | 1943 | static int smack_sem_associate(struct sem_array *sma, int semflg) |
| 1776 | { | 1944 | { |
| 1777 | char *ssp = smack_of_sem(sma); | ||
| 1778 | int may; | 1945 | int may; |
| 1779 | 1946 | ||
| 1780 | may = smack_flags_to_may(semflg); | 1947 | may = smack_flags_to_may(semflg); |
| 1781 | return smk_curacc(ssp, may); | 1948 | return smk_curacc_sem(sma, may); |
| 1782 | } | 1949 | } |
| 1783 | 1950 | ||
| 1784 | /** | 1951 | /** |
| @@ -1790,7 +1957,6 @@ static int smack_sem_associate(struct sem_array *sma, int semflg) | |||
| 1790 | */ | 1957 | */ |
| 1791 | static int smack_sem_semctl(struct sem_array *sma, int cmd) | 1958 | static int smack_sem_semctl(struct sem_array *sma, int cmd) |
| 1792 | { | 1959 | { |
| 1793 | char *ssp; | ||
| 1794 | int may; | 1960 | int may; |
| 1795 | 1961 | ||
| 1796 | switch (cmd) { | 1962 | switch (cmd) { |
| @@ -1819,8 +1985,7 @@ static int smack_sem_semctl(struct sem_array *sma, int cmd) | |||
| 1819 | return -EINVAL; | 1985 | return -EINVAL; |
| 1820 | } | 1986 | } |
| 1821 | 1987 | ||
| 1822 | ssp = smack_of_sem(sma); | 1988 | return smk_curacc_sem(sma, may); |
| 1823 | return smk_curacc(ssp, may); | ||
| 1824 | } | 1989 | } |
| 1825 | 1990 | ||
| 1826 | /** | 1991 | /** |
| @@ -1837,9 +2002,7 @@ static int smack_sem_semctl(struct sem_array *sma, int cmd) | |||
| 1837 | static int smack_sem_semop(struct sem_array *sma, struct sembuf *sops, | 2002 | static int smack_sem_semop(struct sem_array *sma, struct sembuf *sops, |
| 1838 | unsigned nsops, int alter) | 2003 | unsigned nsops, int alter) |
| 1839 | { | 2004 | { |
| 1840 | char *ssp = smack_of_sem(sma); | 2005 | return smk_curacc_sem(sma, MAY_READWRITE); |
| 1841 | |||
| 1842 | return smk_curacc(ssp, MAY_READWRITE); | ||
| 1843 | } | 2006 | } |
| 1844 | 2007 | ||
| 1845 | /** | 2008 | /** |
| @@ -1881,6 +2044,25 @@ static char *smack_of_msq(struct msg_queue *msq) | |||
| 1881 | } | 2044 | } |
| 1882 | 2045 | ||
| 1883 | /** | 2046 | /** |
| 2047 | * smk_curacc_msq : helper to check if current has access on msq | ||
| 2048 | * @msq : the msq | ||
| 2049 | * @access : access requested | ||
| 2050 | * | ||
| 2051 | * return 0 if current has access, error otherwise | ||
| 2052 | */ | ||
| 2053 | static int smk_curacc_msq(struct msg_queue *msq, int access) | ||
| 2054 | { | ||
| 2055 | char *msp = smack_of_msq(msq); | ||
| 2056 | struct smk_audit_info ad; | ||
| 2057 | |||
| 2058 | #ifdef CONFIG_AUDIT | ||
| 2059 | smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_IPC); | ||
| 2060 | ad.a.u.ipc_id = msq->q_perm.id; | ||
| 2061 | #endif | ||
| 2062 | return smk_curacc(msp, access, &ad); | ||
| 2063 | } | ||
| 2064 | |||
| 2065 | /** | ||
| 1884 | * smack_msg_queue_associate - Smack access check for msg_queue | 2066 | * smack_msg_queue_associate - Smack access check for msg_queue |
| 1885 | * @msq: the object | 2067 | * @msq: the object |
| 1886 | * @msqflg: access requested | 2068 | * @msqflg: access requested |
| @@ -1889,11 +2071,10 @@ static char *smack_of_msq(struct msg_queue *msq) | |||
| 1889 | */ | 2071 | */ |
| 1890 | static int smack_msg_queue_associate(struct msg_queue *msq, int msqflg) | 2072 | static int smack_msg_queue_associate(struct msg_queue *msq, int msqflg) |
| 1891 | { | 2073 | { |
| 1892 | char *msp = smack_of_msq(msq); | ||
| 1893 | int may; | 2074 | int may; |
| 1894 | 2075 | ||
| 1895 | may = smack_flags_to_may(msqflg); | 2076 | may = smack_flags_to_may(msqflg); |
| 1896 | return smk_curacc(msp, may); | 2077 | return smk_curacc_msq(msq, may); |
| 1897 | } | 2078 | } |
| 1898 | 2079 | ||
| 1899 | /** | 2080 | /** |
| @@ -1905,7 +2086,6 @@ static int smack_msg_queue_associate(struct msg_queue *msq, int msqflg) | |||
| 1905 | */ | 2086 | */ |
| 1906 | static int smack_msg_queue_msgctl(struct msg_queue *msq, int cmd) | 2087 | static int smack_msg_queue_msgctl(struct msg_queue *msq, int cmd) |
| 1907 | { | 2088 | { |
| 1908 | char *msp; | ||
| 1909 | int may; | 2089 | int may; |
| 1910 | 2090 | ||
| 1911 | switch (cmd) { | 2091 | switch (cmd) { |
| @@ -1927,8 +2107,7 @@ static int smack_msg_queue_msgctl(struct msg_queue *msq, int cmd) | |||
| 1927 | return -EINVAL; | 2107 | return -EINVAL; |
| 1928 | } | 2108 | } |
| 1929 | 2109 | ||
| 1930 | msp = smack_of_msq(msq); | 2110 | return smk_curacc_msq(msq, may); |
| 1931 | return smk_curacc(msp, may); | ||
| 1932 | } | 2111 | } |
| 1933 | 2112 | ||
| 1934 | /** | 2113 | /** |
| @@ -1942,11 +2121,10 @@ static int smack_msg_queue_msgctl(struct msg_queue *msq, int cmd) | |||
| 1942 | static int smack_msg_queue_msgsnd(struct msg_queue *msq, struct msg_msg *msg, | 2121 | static int smack_msg_queue_msgsnd(struct msg_queue *msq, struct msg_msg *msg, |
| 1943 | int msqflg) | 2122 | int msqflg) |
| 1944 | { | 2123 | { |
| 1945 | char *msp = smack_of_msq(msq); | 2124 | int may; |
| 1946 | int rc; | ||
| 1947 | 2125 | ||
| 1948 | rc = smack_flags_to_may(msqflg); | 2126 | may = smack_flags_to_may(msqflg); |
| 1949 | return smk_curacc(msp, rc); | 2127 | return smk_curacc_msq(msq, may); |
| 1950 | } | 2128 | } |
| 1951 | 2129 | ||
| 1952 | /** | 2130 | /** |
| @@ -1962,9 +2140,7 @@ static int smack_msg_queue_msgsnd(struct msg_queue *msq, struct msg_msg *msg, | |||
| 1962 | static int smack_msg_queue_msgrcv(struct msg_queue *msq, struct msg_msg *msg, | 2140 | static int smack_msg_queue_msgrcv(struct msg_queue *msq, struct msg_msg *msg, |
| 1963 | struct task_struct *target, long type, int mode) | 2141 | struct task_struct *target, long type, int mode) |
| 1964 | { | 2142 | { |
| 1965 | char *msp = smack_of_msq(msq); | 2143 | return smk_curacc_msq(msq, MAY_READWRITE); |
| 1966 | |||
| 1967 | return smk_curacc(msp, MAY_READWRITE); | ||
| 1968 | } | 2144 | } |
| 1969 | 2145 | ||
| 1970 | /** | 2146 | /** |
| @@ -1977,10 +2153,14 @@ static int smack_msg_queue_msgrcv(struct msg_queue *msq, struct msg_msg *msg, | |||
| 1977 | static int smack_ipc_permission(struct kern_ipc_perm *ipp, short flag) | 2153 | static int smack_ipc_permission(struct kern_ipc_perm *ipp, short flag) |
| 1978 | { | 2154 | { |
| 1979 | char *isp = ipp->security; | 2155 | char *isp = ipp->security; |
| 1980 | int may; | 2156 | int may = smack_flags_to_may(flag); |
| 2157 | struct smk_audit_info ad; | ||
| 1981 | 2158 | ||
| 1982 | may = smack_flags_to_may(flag); | 2159 | #ifdef CONFIG_AUDIT |
| 1983 | return smk_curacc(isp, may); | 2160 | smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_IPC); |
| 2161 | ad.a.u.ipc_id = ipp->id; | ||
| 2162 | #endif | ||
| 2163 | return smk_curacc(isp, may, &ad); | ||
| 1984 | } | 2164 | } |
| 1985 | 2165 | ||
| 1986 | /** | 2166 | /** |
| @@ -2239,8 +2419,12 @@ static int smack_unix_stream_connect(struct socket *sock, | |||
| 2239 | { | 2419 | { |
| 2240 | struct inode *sp = SOCK_INODE(sock); | 2420 | struct inode *sp = SOCK_INODE(sock); |
| 2241 | struct inode *op = SOCK_INODE(other); | 2421 | struct inode *op = SOCK_INODE(other); |
| 2422 | struct smk_audit_info ad; | ||
| 2242 | 2423 | ||
| 2243 | return smk_access(smk_of_inode(sp), smk_of_inode(op), MAY_READWRITE); | 2424 | smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_NET); |
| 2425 | smk_ad_setfield_u_net_sk(&ad, other->sk); | ||
| 2426 | return smk_access(smk_of_inode(sp), smk_of_inode(op), | ||
| 2427 | MAY_READWRITE, &ad); | ||
| 2244 | } | 2428 | } |
| 2245 | 2429 | ||
| 2246 | /** | 2430 | /** |
| @@ -2255,8 +2439,11 @@ static int smack_unix_may_send(struct socket *sock, struct socket *other) | |||
| 2255 | { | 2439 | { |
| 2256 | struct inode *sp = SOCK_INODE(sock); | 2440 | struct inode *sp = SOCK_INODE(sock); |
| 2257 | struct inode *op = SOCK_INODE(other); | 2441 | struct inode *op = SOCK_INODE(other); |
| 2442 | struct smk_audit_info ad; | ||
| 2258 | 2443 | ||
| 2259 | return smk_access(smk_of_inode(sp), smk_of_inode(op), MAY_WRITE); | 2444 | smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_NET); |
| 2445 | smk_ad_setfield_u_net_sk(&ad, other->sk); | ||
| 2446 | return smk_access(smk_of_inode(sp), smk_of_inode(op), MAY_WRITE, &ad); | ||
| 2260 | } | 2447 | } |
| 2261 | 2448 | ||
| 2262 | /** | 2449 | /** |
| @@ -2371,7 +2558,7 @@ static int smack_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb) | |||
| 2371 | char smack[SMK_LABELLEN]; | 2558 | char smack[SMK_LABELLEN]; |
| 2372 | char *csp; | 2559 | char *csp; |
| 2373 | int rc; | 2560 | int rc; |
| 2374 | 2561 | struct smk_audit_info ad; | |
| 2375 | if (sk->sk_family != PF_INET && sk->sk_family != PF_INET6) | 2562 | if (sk->sk_family != PF_INET && sk->sk_family != PF_INET6) |
| 2376 | return 0; | 2563 | return 0; |
| 2377 | 2564 | ||
| @@ -2389,13 +2576,19 @@ static int smack_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb) | |||
| 2389 | 2576 | ||
| 2390 | netlbl_secattr_destroy(&secattr); | 2577 | netlbl_secattr_destroy(&secattr); |
| 2391 | 2578 | ||
| 2579 | #ifdef CONFIG_AUDIT | ||
| 2580 | smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_NET); | ||
| 2581 | ad.a.u.net.family = sk->sk_family; | ||
| 2582 | ad.a.u.net.netif = skb->iif; | ||
| 2583 | ipv4_skb_to_auditdata(skb, &ad.a, NULL); | ||
| 2584 | #endif | ||
| 2392 | /* | 2585 | /* |
| 2393 | * Receiving a packet requires that the other end | 2586 | * Receiving a packet requires that the other end |
| 2394 | * be able to write here. Read access is not required. | 2587 | * be able to write here. Read access is not required. |
| 2395 | * This is the simplist possible security model | 2588 | * This is the simplist possible security model |
| 2396 | * for networking. | 2589 | * for networking. |
| 2397 | */ | 2590 | */ |
| 2398 | rc = smk_access(csp, ssp->smk_in, MAY_WRITE); | 2591 | rc = smk_access(csp, ssp->smk_in, MAY_WRITE, &ad); |
| 2399 | if (rc != 0) | 2592 | if (rc != 0) |
| 2400 | netlbl_skbuff_err(skb, rc, 0); | 2593 | netlbl_skbuff_err(skb, rc, 0); |
| 2401 | return rc; | 2594 | return rc; |
| @@ -2524,6 +2717,7 @@ static int smack_inet_conn_request(struct sock *sk, struct sk_buff *skb, | |||
| 2524 | struct iphdr *hdr; | 2717 | struct iphdr *hdr; |
| 2525 | char smack[SMK_LABELLEN]; | 2718 | char smack[SMK_LABELLEN]; |
| 2526 | int rc; | 2719 | int rc; |
| 2720 | struct smk_audit_info ad; | ||
| 2527 | 2721 | ||
| 2528 | /* handle mapped IPv4 packets arriving via IPv6 sockets */ | 2722 | /* handle mapped IPv4 packets arriving via IPv6 sockets */ |
| 2529 | if (family == PF_INET6 && skb->protocol == htons(ETH_P_IP)) | 2723 | if (family == PF_INET6 && skb->protocol == htons(ETH_P_IP)) |
| @@ -2537,11 +2731,17 @@ static int smack_inet_conn_request(struct sock *sk, struct sk_buff *skb, | |||
| 2537 | strncpy(smack, smack_known_huh.smk_known, SMK_MAXLEN); | 2731 | strncpy(smack, smack_known_huh.smk_known, SMK_MAXLEN); |
| 2538 | netlbl_secattr_destroy(&secattr); | 2732 | netlbl_secattr_destroy(&secattr); |
| 2539 | 2733 | ||
| 2734 | #ifdef CONFIG_AUDIT | ||
| 2735 | smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_NET); | ||
| 2736 | ad.a.u.net.family = family; | ||
| 2737 | ad.a.u.net.netif = skb->iif; | ||
| 2738 | ipv4_skb_to_auditdata(skb, &ad.a, NULL); | ||
| 2739 | #endif | ||
| 2540 | /* | 2740 | /* |
| 2541 | * Receiving a packet requires that the other end be able to write | 2741 | * Receiving a packet requires that the other end be able to write |
| 2542 | * here. Read access is not required. | 2742 | * here. Read access is not required. |
| 2543 | */ | 2743 | */ |
| 2544 | rc = smk_access(smack, ssp->smk_in, MAY_WRITE); | 2744 | rc = smk_access(smack, ssp->smk_in, MAY_WRITE, &ad); |
| 2545 | if (rc != 0) | 2745 | if (rc != 0) |
| 2546 | return rc; | 2746 | return rc; |
| 2547 | 2747 | ||
| @@ -2643,6 +2843,7 @@ static int smack_key_permission(key_ref_t key_ref, | |||
| 2643 | const struct cred *cred, key_perm_t perm) | 2843 | const struct cred *cred, key_perm_t perm) |
| 2644 | { | 2844 | { |
| 2645 | struct key *keyp; | 2845 | struct key *keyp; |
| 2846 | struct smk_audit_info ad; | ||
| 2646 | 2847 | ||
| 2647 | keyp = key_ref_to_ptr(key_ref); | 2848 | keyp = key_ref_to_ptr(key_ref); |
| 2648 | if (keyp == NULL) | 2849 | if (keyp == NULL) |
| @@ -2658,8 +2859,13 @@ static int smack_key_permission(key_ref_t key_ref, | |||
| 2658 | */ | 2859 | */ |
| 2659 | if (cred->security == NULL) | 2860 | if (cred->security == NULL) |
| 2660 | return -EACCES; | 2861 | return -EACCES; |
| 2661 | 2862 | #ifdef CONFIG_AUDIT | |
| 2662 | return smk_access(cred->security, keyp->security, MAY_READWRITE); | 2863 | smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_KEY); |
| 2864 | ad.a.u.key_struct.key = keyp->serial; | ||
| 2865 | ad.a.u.key_struct.key_desc = keyp->description; | ||
| 2866 | #endif | ||
| 2867 | return smk_access(cred->security, keyp->security, | ||
| 2868 | MAY_READWRITE, &ad); | ||
| 2663 | } | 2869 | } |
| 2664 | #endif /* CONFIG_KEYS */ | 2870 | #endif /* CONFIG_KEYS */ |
| 2665 | 2871 | ||
| @@ -2828,15 +3034,7 @@ struct security_operations smack_ops = { | |||
| 2828 | 3034 | ||
| 2829 | .ptrace_may_access = smack_ptrace_may_access, | 3035 | .ptrace_may_access = smack_ptrace_may_access, |
| 2830 | .ptrace_traceme = smack_ptrace_traceme, | 3036 | .ptrace_traceme = smack_ptrace_traceme, |
| 2831 | .capget = cap_capget, | ||
| 2832 | .capset = cap_capset, | ||
| 2833 | .capable = cap_capable, | ||
| 2834 | .syslog = smack_syslog, | 3037 | .syslog = smack_syslog, |
| 2835 | .settime = cap_settime, | ||
| 2836 | .vm_enough_memory = cap_vm_enough_memory, | ||
| 2837 | |||
| 2838 | .bprm_set_creds = cap_bprm_set_creds, | ||
| 2839 | .bprm_secureexec = cap_bprm_secureexec, | ||
| 2840 | 3038 | ||
| 2841 | .sb_alloc_security = smack_sb_alloc_security, | 3039 | .sb_alloc_security = smack_sb_alloc_security, |
| 2842 | .sb_free_security = smack_sb_free_security, | 3040 | .sb_free_security = smack_sb_free_security, |
| @@ -2860,8 +3058,6 @@ struct security_operations smack_ops = { | |||
| 2860 | .inode_post_setxattr = smack_inode_post_setxattr, | 3058 | .inode_post_setxattr = smack_inode_post_setxattr, |
| 2861 | .inode_getxattr = smack_inode_getxattr, | 3059 | .inode_getxattr = smack_inode_getxattr, |
| 2862 | .inode_removexattr = smack_inode_removexattr, | 3060 | .inode_removexattr = smack_inode_removexattr, |
| 2863 | .inode_need_killpriv = cap_inode_need_killpriv, | ||
| 2864 | .inode_killpriv = cap_inode_killpriv, | ||
| 2865 | .inode_getsecurity = smack_inode_getsecurity, | 3061 | .inode_getsecurity = smack_inode_getsecurity, |
| 2866 | .inode_setsecurity = smack_inode_setsecurity, | 3062 | .inode_setsecurity = smack_inode_setsecurity, |
| 2867 | .inode_listsecurity = smack_inode_listsecurity, | 3063 | .inode_listsecurity = smack_inode_listsecurity, |
| @@ -2882,7 +3078,6 @@ struct security_operations smack_ops = { | |||
| 2882 | .cred_commit = smack_cred_commit, | 3078 | .cred_commit = smack_cred_commit, |
| 2883 | .kernel_act_as = smack_kernel_act_as, | 3079 | .kernel_act_as = smack_kernel_act_as, |
| 2884 | .kernel_create_files_as = smack_kernel_create_files_as, | 3080 | .kernel_create_files_as = smack_kernel_create_files_as, |
| 2885 | .task_fix_setuid = cap_task_fix_setuid, | ||
| 2886 | .task_setpgid = smack_task_setpgid, | 3081 | .task_setpgid = smack_task_setpgid, |
| 2887 | .task_getpgid = smack_task_getpgid, | 3082 | .task_getpgid = smack_task_getpgid, |
| 2888 | .task_getsid = smack_task_getsid, | 3083 | .task_getsid = smack_task_getsid, |
| @@ -2896,7 +3091,6 @@ struct security_operations smack_ops = { | |||
| 2896 | .task_kill = smack_task_kill, | 3091 | .task_kill = smack_task_kill, |
| 2897 | .task_wait = smack_task_wait, | 3092 | .task_wait = smack_task_wait, |
| 2898 | .task_to_inode = smack_task_to_inode, | 3093 | .task_to_inode = smack_task_to_inode, |
| 2899 | .task_prctl = cap_task_prctl, | ||
| 2900 | 3094 | ||
| 2901 | .ipc_permission = smack_ipc_permission, | 3095 | .ipc_permission = smack_ipc_permission, |
| 2902 | .ipc_getsecid = smack_ipc_getsecid, | 3096 | .ipc_getsecid = smack_ipc_getsecid, |
| @@ -2923,9 +3117,6 @@ struct security_operations smack_ops = { | |||
| 2923 | .sem_semctl = smack_sem_semctl, | 3117 | .sem_semctl = smack_sem_semctl, |
| 2924 | .sem_semop = smack_sem_semop, | 3118 | .sem_semop = smack_sem_semop, |
| 2925 | 3119 | ||
| 2926 | .netlink_send = cap_netlink_send, | ||
| 2927 | .netlink_recv = cap_netlink_recv, | ||
| 2928 | |||
| 2929 | .d_instantiate = smack_d_instantiate, | 3120 | .d_instantiate = smack_d_instantiate, |
| 2930 | 3121 | ||
| 2931 | .getprocattr = smack_getprocattr, | 3122 | .getprocattr = smack_getprocattr, |
diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c index 11d2cb19d7a6..f83a80980726 100644 --- a/security/smack/smackfs.c +++ b/security/smack/smackfs.c | |||
| @@ -41,6 +41,7 @@ enum smk_inos { | |||
| 41 | SMK_AMBIENT = 7, /* internet ambient label */ | 41 | SMK_AMBIENT = 7, /* internet ambient label */ |
| 42 | SMK_NETLBLADDR = 8, /* single label hosts */ | 42 | SMK_NETLBLADDR = 8, /* single label hosts */ |
| 43 | SMK_ONLYCAP = 9, /* the only "capable" label */ | 43 | SMK_ONLYCAP = 9, /* the only "capable" label */ |
| 44 | SMK_LOGGING = 10, /* logging */ | ||
| 44 | }; | 45 | }; |
| 45 | 46 | ||
| 46 | /* | 47 | /* |
| @@ -775,7 +776,7 @@ static ssize_t smk_write_netlbladdr(struct file *file, const char __user *buf, | |||
| 775 | struct sockaddr_in newname; | 776 | struct sockaddr_in newname; |
| 776 | char smack[SMK_LABELLEN]; | 777 | char smack[SMK_LABELLEN]; |
| 777 | char *sp; | 778 | char *sp; |
| 778 | char data[SMK_NETLBLADDRMAX]; | 779 | char data[SMK_NETLBLADDRMAX + 1]; |
| 779 | char *host = (char *)&newname.sin_addr.s_addr; | 780 | char *host = (char *)&newname.sin_addr.s_addr; |
| 780 | int rc; | 781 | int rc; |
| 781 | struct netlbl_audit audit_info; | 782 | struct netlbl_audit audit_info; |
| @@ -1192,6 +1193,69 @@ static const struct file_operations smk_onlycap_ops = { | |||
| 1192 | }; | 1193 | }; |
| 1193 | 1194 | ||
| 1194 | /** | 1195 | /** |
| 1196 | * smk_read_logging - read() for /smack/logging | ||
| 1197 | * @filp: file pointer, not actually used | ||
| 1198 | * @buf: where to put the result | ||
| 1199 | * @cn: maximum to send along | ||
| 1200 | * @ppos: where to start | ||
| 1201 | * | ||
| 1202 | * Returns number of bytes read or error code, as appropriate | ||
| 1203 | */ | ||
| 1204 | static ssize_t smk_read_logging(struct file *filp, char __user *buf, | ||
| 1205 | size_t count, loff_t *ppos) | ||
| 1206 | { | ||
| 1207 | char temp[32]; | ||
| 1208 | ssize_t rc; | ||
| 1209 | |||
| 1210 | if (*ppos != 0) | ||
| 1211 | return 0; | ||
| 1212 | |||
| 1213 | sprintf(temp, "%d\n", log_policy); | ||
| 1214 | rc = simple_read_from_buffer(buf, count, ppos, temp, strlen(temp)); | ||
| 1215 | return rc; | ||
| 1216 | } | ||
| 1217 | |||
| 1218 | /** | ||
| 1219 | * smk_write_logging - write() for /smack/logging | ||
| 1220 | * @file: file pointer, not actually used | ||
| 1221 | * @buf: where to get the data from | ||
| 1222 | * @count: bytes sent | ||
| 1223 | * @ppos: where to start | ||
| 1224 | * | ||
| 1225 | * Returns number of bytes written or error code, as appropriate | ||
| 1226 | */ | ||
| 1227 | static ssize_t smk_write_logging(struct file *file, const char __user *buf, | ||
| 1228 | size_t count, loff_t *ppos) | ||
| 1229 | { | ||
| 1230 | char temp[32]; | ||
| 1231 | int i; | ||
| 1232 | |||
| 1233 | if (!capable(CAP_MAC_ADMIN)) | ||
| 1234 | return -EPERM; | ||
| 1235 | |||
| 1236 | if (count >= sizeof(temp) || count == 0) | ||
| 1237 | return -EINVAL; | ||
| 1238 | |||
| 1239 | if (copy_from_user(temp, buf, count) != 0) | ||
| 1240 | return -EFAULT; | ||
| 1241 | |||
| 1242 | temp[count] = '\0'; | ||
| 1243 | |||
| 1244 | if (sscanf(temp, "%d", &i) != 1) | ||
| 1245 | return -EINVAL; | ||
| 1246 | if (i < 0 || i > 3) | ||
| 1247 | return -EINVAL; | ||
| 1248 | log_policy = i; | ||
| 1249 | return count; | ||
| 1250 | } | ||
| 1251 | |||
| 1252 | |||
| 1253 | |||
| 1254 | static const struct file_operations smk_logging_ops = { | ||
| 1255 | .read = smk_read_logging, | ||
| 1256 | .write = smk_write_logging, | ||
| 1257 | }; | ||
| 1258 | /** | ||
| 1195 | * smk_fill_super - fill the /smackfs superblock | 1259 | * smk_fill_super - fill the /smackfs superblock |
| 1196 | * @sb: the empty superblock | 1260 | * @sb: the empty superblock |
| 1197 | * @data: unused | 1261 | * @data: unused |
| @@ -1221,6 +1285,8 @@ static int smk_fill_super(struct super_block *sb, void *data, int silent) | |||
| 1221 | {"netlabel", &smk_netlbladdr_ops, S_IRUGO|S_IWUSR}, | 1285 | {"netlabel", &smk_netlbladdr_ops, S_IRUGO|S_IWUSR}, |
| 1222 | [SMK_ONLYCAP] = | 1286 | [SMK_ONLYCAP] = |
| 1223 | {"onlycap", &smk_onlycap_ops, S_IRUGO|S_IWUSR}, | 1287 | {"onlycap", &smk_onlycap_ops, S_IRUGO|S_IWUSR}, |
| 1288 | [SMK_LOGGING] = | ||
| 1289 | {"logging", &smk_logging_ops, S_IRUGO|S_IWUSR}, | ||
| 1224 | /* last one */ {""} | 1290 | /* last one */ {""} |
| 1225 | }; | 1291 | }; |
| 1226 | 1292 | ||
