diff options
Diffstat (limited to 'security')
25 files changed, 171 insertions, 136 deletions
diff --git a/security/integrity/ima/Kconfig b/security/integrity/ima/Kconfig index 35664fe6daa1..b9c1219924f1 100644 --- a/security/integrity/ima/Kconfig +++ b/security/integrity/ima/Kconfig | |||
| @@ -38,8 +38,9 @@ config IMA_MEASURE_PCR_IDX | |||
| 38 | measurement list. If unsure, use the default 10. | 38 | measurement list. If unsure, use the default 10. |
| 39 | 39 | ||
| 40 | config IMA_AUDIT | 40 | config IMA_AUDIT |
| 41 | bool | 41 | bool "Enables auditing support" |
| 42 | depends on IMA | 42 | depends on IMA |
| 43 | depends on AUDIT | ||
| 43 | default y | 44 | default y |
| 44 | help | 45 | help |
| 45 | This option adds a kernel parameter 'ima_audit', which | 46 | This option adds a kernel parameter 'ima_audit', which |
diff --git a/security/integrity/ima/Makefile b/security/integrity/ima/Makefile index 5690c021de8f..5f740f6971e1 100644 --- a/security/integrity/ima/Makefile +++ b/security/integrity/ima/Makefile | |||
| @@ -6,4 +6,5 @@ | |||
| 6 | obj-$(CONFIG_IMA) += ima.o | 6 | obj-$(CONFIG_IMA) += ima.o |
| 7 | 7 | ||
| 8 | ima-y := ima_fs.o ima_queue.o ima_init.o ima_main.o ima_crypto.o ima_api.o \ | 8 | ima-y := ima_fs.o ima_queue.o ima_init.o ima_main.o ima_crypto.o ima_api.o \ |
| 9 | ima_policy.o ima_audit.o | 9 | ima_policy.o |
| 10 | ima-$(CONFIG_IMA_AUDIT) += ima_audit.o | ||
diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h index 3ccf7acac6df..e7c99fd0d223 100644 --- a/security/integrity/ima/ima.h +++ b/security/integrity/ima/ima.h | |||
| @@ -61,10 +61,19 @@ struct ima_queue_entry { | |||
| 61 | }; | 61 | }; |
| 62 | extern struct list_head ima_measurements; /* list of all measurements */ | 62 | extern struct list_head ima_measurements; /* list of all measurements */ |
| 63 | 63 | ||
| 64 | #ifdef CONFIG_IMA_AUDIT | ||
| 64 | /* declarations */ | 65 | /* declarations */ |
| 65 | void integrity_audit_msg(int audit_msgno, struct inode *inode, | 66 | void integrity_audit_msg(int audit_msgno, struct inode *inode, |
| 66 | const unsigned char *fname, const char *op, | 67 | const unsigned char *fname, const char *op, |
| 67 | const char *cause, int result, int info); | 68 | const char *cause, int result, int info); |
| 69 | #else | ||
| 70 | static inline void integrity_audit_msg(int audit_msgno, struct inode *inode, | ||
| 71 | const unsigned char *fname, | ||
| 72 | const char *op, const char *cause, | ||
| 73 | int result, int info) | ||
| 74 | { | ||
| 75 | } | ||
| 76 | #endif | ||
| 68 | 77 | ||
| 69 | /* Internal IMA function definitions */ | 78 | /* Internal IMA function definitions */ |
| 70 | int ima_init(void); | 79 | int ima_init(void); |
diff --git a/security/integrity/ima/ima_api.c b/security/integrity/ima/ima_api.c index 88a2788b981d..032ff03ad907 100644 --- a/security/integrity/ima/ima_api.c +++ b/security/integrity/ima/ima_api.c | |||
| @@ -175,7 +175,9 @@ void ima_store_measurement(struct integrity_iint_cache *iint, | |||
| 175 | } | 175 | } |
| 176 | memset(&entry->template, 0, sizeof(entry->template)); | 176 | memset(&entry->template, 0, sizeof(entry->template)); |
| 177 | memcpy(entry->template.digest, iint->digest, IMA_DIGEST_SIZE); | 177 | memcpy(entry->template.digest, iint->digest, IMA_DIGEST_SIZE); |
| 178 | strncpy(entry->template.file_name, filename, IMA_EVENT_NAME_LEN_MAX); | 178 | strcpy(entry->template.file_name, |
| 179 | (strlen(filename) > IMA_EVENT_NAME_LEN_MAX) ? | ||
| 180 | file->f_dentry->d_name.name : filename); | ||
| 179 | 181 | ||
| 180 | result = ima_store_template(entry, violation, inode); | 182 | result = ima_store_template(entry, violation, inode); |
| 181 | if (!result || result == -EEXIST) | 183 | if (!result || result == -EEXIST) |
diff --git a/security/integrity/ima/ima_audit.c b/security/integrity/ima/ima_audit.c index 21e96bf188df..7a57f6769e9c 100644 --- a/security/integrity/ima/ima_audit.c +++ b/security/integrity/ima/ima_audit.c | |||
| @@ -17,8 +17,6 @@ | |||
| 17 | 17 | ||
| 18 | static int ima_audit; | 18 | static int ima_audit; |
| 19 | 19 | ||
| 20 | #ifdef CONFIG_IMA_AUDIT | ||
| 21 | |||
| 22 | /* ima_audit_setup - enable informational auditing messages */ | 20 | /* ima_audit_setup - enable informational auditing messages */ |
| 23 | static int __init ima_audit_setup(char *str) | 21 | static int __init ima_audit_setup(char *str) |
| 24 | { | 22 | { |
| @@ -29,7 +27,6 @@ static int __init ima_audit_setup(char *str) | |||
| 29 | return 1; | 27 | return 1; |
| 30 | } | 28 | } |
| 31 | __setup("ima_audit=", ima_audit_setup); | 29 | __setup("ima_audit=", ima_audit_setup); |
| 32 | #endif | ||
| 33 | 30 | ||
| 34 | void integrity_audit_msg(int audit_msgno, struct inode *inode, | 31 | void integrity_audit_msg(int audit_msgno, struct inode *inode, |
| 35 | const unsigned char *fname, const char *op, | 32 | const unsigned char *fname, const char *op, |
diff --git a/security/integrity/ima/ima_fs.c b/security/integrity/ima/ima_fs.c index e1aa2b482dd2..38477c9c3415 100644 --- a/security/integrity/ima/ima_fs.c +++ b/security/integrity/ima/ima_fs.c | |||
| @@ -367,20 +367,11 @@ int __init ima_fs_init(void) | |||
| 367 | 367 | ||
| 368 | return 0; | 368 | return 0; |
| 369 | out: | 369 | out: |
| 370 | securityfs_remove(runtime_measurements_count); | ||
| 371 | securityfs_remove(ascii_runtime_measurements); | ||
| 372 | securityfs_remove(binary_runtime_measurements); | ||
| 373 | securityfs_remove(ima_dir); | ||
| 374 | securityfs_remove(ima_policy); | ||
| 375 | return -1; | ||
| 376 | } | ||
| 377 | |||
| 378 | void __exit ima_fs_cleanup(void) | ||
| 379 | { | ||
| 380 | securityfs_remove(violations); | 370 | securityfs_remove(violations); |
| 381 | securityfs_remove(runtime_measurements_count); | 371 | securityfs_remove(runtime_measurements_count); |
| 382 | securityfs_remove(ascii_runtime_measurements); | 372 | securityfs_remove(ascii_runtime_measurements); |
| 383 | securityfs_remove(binary_runtime_measurements); | 373 | securityfs_remove(binary_runtime_measurements); |
| 384 | securityfs_remove(ima_dir); | 374 | securityfs_remove(ima_dir); |
| 385 | securityfs_remove(ima_policy); | 375 | securityfs_remove(ima_policy); |
| 376 | return -1; | ||
| 386 | } | 377 | } |
diff --git a/security/integrity/ima/ima_init.c b/security/integrity/ima/ima_init.c index 17f1f060306f..b5dfd534f13d 100644 --- a/security/integrity/ima/ima_init.c +++ b/security/integrity/ima/ima_init.c | |||
| @@ -90,8 +90,3 @@ int __init ima_init(void) | |||
| 90 | 90 | ||
| 91 | return ima_fs_init(); | 91 | return ima_fs_init(); |
| 92 | } | 92 | } |
| 93 | |||
| 94 | void __exit ima_cleanup(void) | ||
| 95 | { | ||
| 96 | ima_fs_cleanup(); | ||
| 97 | } | ||
diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c index b17be79b9cf2..be8294915cf7 100644 --- a/security/integrity/ima/ima_main.c +++ b/security/integrity/ima/ima_main.c | |||
| @@ -54,6 +54,7 @@ static void ima_rdwr_violation_check(struct file *file) | |||
| 54 | fmode_t mode = file->f_mode; | 54 | fmode_t mode = file->f_mode; |
| 55 | int rc; | 55 | int rc; |
| 56 | bool send_tomtou = false, send_writers = false; | 56 | bool send_tomtou = false, send_writers = false; |
| 57 | unsigned char *pathname = NULL, *pathbuf = NULL; | ||
| 57 | 58 | ||
| 58 | if (!S_ISREG(inode->i_mode) || !ima_initialized) | 59 | if (!S_ISREG(inode->i_mode) || !ima_initialized) |
| 59 | return; | 60 | return; |
| @@ -75,12 +76,27 @@ static void ima_rdwr_violation_check(struct file *file) | |||
| 75 | out: | 76 | out: |
| 76 | mutex_unlock(&inode->i_mutex); | 77 | mutex_unlock(&inode->i_mutex); |
| 77 | 78 | ||
| 79 | if (!send_tomtou && !send_writers) | ||
| 80 | return; | ||
| 81 | |||
| 82 | /* We will allow 11 spaces for ' (deleted)' to be appended */ | ||
| 83 | pathbuf = kmalloc(PATH_MAX + 11, GFP_KERNEL); | ||
| 84 | if (pathbuf) { | ||
| 85 | pathname = d_path(&file->f_path, pathbuf, PATH_MAX + 11); | ||
| 86 | if (IS_ERR(pathname)) | ||
| 87 | pathname = NULL; | ||
| 88 | else if (strlen(pathname) > IMA_EVENT_NAME_LEN_MAX) | ||
| 89 | pathname = NULL; | ||
| 90 | } | ||
| 78 | if (send_tomtou) | 91 | if (send_tomtou) |
| 79 | ima_add_violation(inode, dentry->d_name.name, "invalid_pcr", | 92 | ima_add_violation(inode, |
| 80 | "ToMToU"); | 93 | !pathname ? dentry->d_name.name : pathname, |
| 94 | "invalid_pcr", "ToMToU"); | ||
| 81 | if (send_writers) | 95 | if (send_writers) |
| 82 | ima_add_violation(inode, dentry->d_name.name, "invalid_pcr", | 96 | ima_add_violation(inode, |
| 83 | "open_writers"); | 97 | !pathname ? dentry->d_name.name : pathname, |
| 98 | "invalid_pcr", "open_writers"); | ||
| 99 | kfree(pathbuf); | ||
| 84 | } | 100 | } |
| 85 | 101 | ||
| 86 | static void ima_check_last_writer(struct integrity_iint_cache *iint, | 102 | static void ima_check_last_writer(struct integrity_iint_cache *iint, |
| @@ -123,6 +139,7 @@ static int process_measurement(struct file *file, const unsigned char *filename, | |||
| 123 | { | 139 | { |
| 124 | struct inode *inode = file->f_dentry->d_inode; | 140 | struct inode *inode = file->f_dentry->d_inode; |
| 125 | struct integrity_iint_cache *iint; | 141 | struct integrity_iint_cache *iint; |
| 142 | unsigned char *pathname = NULL, *pathbuf = NULL; | ||
| 126 | int rc = 0; | 143 | int rc = 0; |
| 127 | 144 | ||
| 128 | if (!ima_initialized || !S_ISREG(inode->i_mode)) | 145 | if (!ima_initialized || !S_ISREG(inode->i_mode)) |
| @@ -147,8 +164,21 @@ retry: | |||
| 147 | goto out; | 164 | goto out; |
| 148 | 165 | ||
| 149 | rc = ima_collect_measurement(iint, file); | 166 | rc = ima_collect_measurement(iint, file); |
| 150 | if (!rc) | 167 | if (rc != 0) |
| 151 | ima_store_measurement(iint, file, filename); | 168 | goto out; |
| 169 | |||
| 170 | if (function != BPRM_CHECK) { | ||
| 171 | /* We will allow 11 spaces for ' (deleted)' to be appended */ | ||
| 172 | pathbuf = kmalloc(PATH_MAX + 11, GFP_KERNEL); | ||
| 173 | if (pathbuf) { | ||
| 174 | pathname = | ||
| 175 | d_path(&file->f_path, pathbuf, PATH_MAX + 11); | ||
| 176 | if (IS_ERR(pathname)) | ||
| 177 | pathname = NULL; | ||
| 178 | } | ||
| 179 | } | ||
| 180 | ima_store_measurement(iint, file, !pathname ? filename : pathname); | ||
| 181 | kfree(pathbuf); | ||
| 152 | out: | 182 | out: |
| 153 | mutex_unlock(&iint->mutex); | 183 | mutex_unlock(&iint->mutex); |
| 154 | return rc; | 184 | return rc; |
| @@ -228,15 +258,11 @@ static int __init init_ima(void) | |||
| 228 | int error; | 258 | int error; |
| 229 | 259 | ||
| 230 | error = ima_init(); | 260 | error = ima_init(); |
| 231 | ima_initialized = 1; | 261 | if (!error) |
| 262 | ima_initialized = 1; | ||
| 232 | return error; | 263 | return error; |
| 233 | } | 264 | } |
| 234 | 265 | ||
| 235 | static void __exit cleanup_ima(void) | ||
| 236 | { | ||
| 237 | ima_cleanup(); | ||
| 238 | } | ||
| 239 | |||
| 240 | late_initcall(init_ima); /* Start IMA after the TPM is available */ | 266 | late_initcall(init_ima); /* Start IMA after the TPM is available */ |
| 241 | 267 | ||
| 242 | MODULE_DESCRIPTION("Integrity Measurement Architecture"); | 268 | MODULE_DESCRIPTION("Integrity Measurement Architecture"); |
diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c index d8edff209bf3..1a9583008aae 100644 --- a/security/integrity/ima/ima_policy.c +++ b/security/integrity/ima/ima_policy.c | |||
| @@ -63,6 +63,8 @@ static struct ima_measure_rule_entry default_rules[] = { | |||
| 63 | {.action = DONT_MEASURE,.fsmagic = DEBUGFS_MAGIC,.flags = IMA_FSMAGIC}, | 63 | {.action = DONT_MEASURE,.fsmagic = DEBUGFS_MAGIC,.flags = IMA_FSMAGIC}, |
| 64 | {.action = DONT_MEASURE,.fsmagic = TMPFS_MAGIC,.flags = IMA_FSMAGIC}, | 64 | {.action = DONT_MEASURE,.fsmagic = TMPFS_MAGIC,.flags = IMA_FSMAGIC}, |
| 65 | {.action = DONT_MEASURE,.fsmagic = RAMFS_MAGIC,.flags = IMA_FSMAGIC}, | 65 | {.action = DONT_MEASURE,.fsmagic = RAMFS_MAGIC,.flags = IMA_FSMAGIC}, |
| 66 | {.action = DONT_MEASURE,.fsmagic = DEVPTS_SUPER_MAGIC,.flags = IMA_FSMAGIC}, | ||
| 67 | {.action = DONT_MEASURE,.fsmagic = BINFMTFS_MAGIC,.flags = IMA_FSMAGIC}, | ||
| 66 | {.action = DONT_MEASURE,.fsmagic = SECURITYFS_MAGIC,.flags = IMA_FSMAGIC}, | 68 | {.action = DONT_MEASURE,.fsmagic = SECURITYFS_MAGIC,.flags = IMA_FSMAGIC}, |
| 67 | {.action = DONT_MEASURE,.fsmagic = SELINUX_MAGIC,.flags = IMA_FSMAGIC}, | 69 | {.action = DONT_MEASURE,.fsmagic = SELINUX_MAGIC,.flags = IMA_FSMAGIC}, |
| 68 | {.action = MEASURE,.func = FILE_MMAP,.mask = MAY_EXEC, | 70 | {.action = MEASURE,.func = FILE_MMAP,.mask = MAY_EXEC, |
diff --git a/security/keys/compat.c b/security/keys/compat.c index c92d42b021aa..1c261763f479 100644 --- a/security/keys/compat.c +++ b/security/keys/compat.c | |||
| @@ -24,7 +24,7 @@ | |||
| 24 | * | 24 | * |
| 25 | * If successful, 0 will be returned. | 25 | * If successful, 0 will be returned. |
| 26 | */ | 26 | */ |
| 27 | long compat_keyctl_instantiate_key_iov( | 27 | static long compat_keyctl_instantiate_key_iov( |
| 28 | key_serial_t id, | 28 | key_serial_t id, |
| 29 | const struct compat_iovec __user *_payload_iov, | 29 | const struct compat_iovec __user *_payload_iov, |
| 30 | unsigned ioc, | 30 | unsigned ioc, |
| @@ -33,7 +33,7 @@ long compat_keyctl_instantiate_key_iov( | |||
| 33 | struct iovec iovstack[UIO_FASTIOV], *iov = iovstack; | 33 | struct iovec iovstack[UIO_FASTIOV], *iov = iovstack; |
| 34 | long ret; | 34 | long ret; |
| 35 | 35 | ||
| 36 | if (_payload_iov == 0 || ioc == 0) | 36 | if (!_payload_iov || !ioc) |
| 37 | goto no_payload; | 37 | goto no_payload; |
| 38 | 38 | ||
| 39 | ret = compat_rw_copy_check_uvector(WRITE, _payload_iov, ioc, | 39 | ret = compat_rw_copy_check_uvector(WRITE, _payload_iov, ioc, |
diff --git a/security/keys/internal.h b/security/keys/internal.h index 3dcbf86b0d31..22ff05269e3d 100644 --- a/security/keys/internal.h +++ b/security/keys/internal.h | |||
| @@ -149,7 +149,7 @@ extern key_ref_t lookup_user_key(key_serial_t id, unsigned long flags, | |||
| 149 | #define KEY_LOOKUP_FOR_UNLINK 0x04 | 149 | #define KEY_LOOKUP_FOR_UNLINK 0x04 |
| 150 | 150 | ||
| 151 | extern long join_session_keyring(const char *name); | 151 | extern long join_session_keyring(const char *name); |
| 152 | extern void key_change_session_keyring(struct task_work *twork); | 152 | extern void key_change_session_keyring(struct callback_head *twork); |
| 153 | 153 | ||
| 154 | extern struct work_struct key_gc_work; | 154 | extern struct work_struct key_gc_work; |
| 155 | extern unsigned key_gc_delay; | 155 | extern unsigned key_gc_delay; |
| @@ -242,7 +242,7 @@ extern long keyctl_instantiate_key_iov(key_serial_t, | |||
| 242 | extern long keyctl_invalidate_key(key_serial_t); | 242 | extern long keyctl_invalidate_key(key_serial_t); |
| 243 | 243 | ||
| 244 | extern long keyctl_instantiate_key_common(key_serial_t, | 244 | extern long keyctl_instantiate_key_common(key_serial_t, |
| 245 | const struct iovec __user *, | 245 | const struct iovec *, |
| 246 | unsigned, size_t, key_serial_t); | 246 | unsigned, size_t, key_serial_t); |
| 247 | 247 | ||
| 248 | /* | 248 | /* |
diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c index 0f5b3f027299..3364fbf46807 100644 --- a/security/keys/keyctl.c +++ b/security/keys/keyctl.c | |||
| @@ -1106,7 +1106,7 @@ long keyctl_instantiate_key_iov(key_serial_t id, | |||
| 1106 | struct iovec iovstack[UIO_FASTIOV], *iov = iovstack; | 1106 | struct iovec iovstack[UIO_FASTIOV], *iov = iovstack; |
| 1107 | long ret; | 1107 | long ret; |
| 1108 | 1108 | ||
| 1109 | if (_payload_iov == 0 || ioc == 0) | 1109 | if (!_payload_iov || !ioc) |
| 1110 | goto no_payload; | 1110 | goto no_payload; |
| 1111 | 1111 | ||
| 1112 | ret = rw_copy_check_uvector(WRITE, _payload_iov, ioc, | 1112 | ret = rw_copy_check_uvector(WRITE, _payload_iov, ioc, |
| @@ -1456,7 +1456,7 @@ long keyctl_session_to_parent(void) | |||
| 1456 | { | 1456 | { |
| 1457 | struct task_struct *me, *parent; | 1457 | struct task_struct *me, *parent; |
| 1458 | const struct cred *mycred, *pcred; | 1458 | const struct cred *mycred, *pcred; |
| 1459 | struct task_work *newwork, *oldwork; | 1459 | struct callback_head *newwork, *oldwork; |
| 1460 | key_ref_t keyring_r; | 1460 | key_ref_t keyring_r; |
| 1461 | struct cred *cred; | 1461 | struct cred *cred; |
| 1462 | int ret; | 1462 | int ret; |
| @@ -1466,19 +1466,17 @@ long keyctl_session_to_parent(void) | |||
| 1466 | return PTR_ERR(keyring_r); | 1466 | return PTR_ERR(keyring_r); |
| 1467 | 1467 | ||
| 1468 | ret = -ENOMEM; | 1468 | ret = -ENOMEM; |
| 1469 | newwork = kmalloc(sizeof(struct task_work), GFP_KERNEL); | ||
| 1470 | if (!newwork) | ||
| 1471 | goto error_keyring; | ||
| 1472 | 1469 | ||
| 1473 | /* our parent is going to need a new cred struct, a new tgcred struct | 1470 | /* our parent is going to need a new cred struct, a new tgcred struct |
| 1474 | * and new security data, so we allocate them here to prevent ENOMEM in | 1471 | * and new security data, so we allocate them here to prevent ENOMEM in |
| 1475 | * our parent */ | 1472 | * our parent */ |
| 1476 | cred = cred_alloc_blank(); | 1473 | cred = cred_alloc_blank(); |
| 1477 | if (!cred) | 1474 | if (!cred) |
| 1478 | goto error_newwork; | 1475 | goto error_keyring; |
| 1476 | newwork = &cred->rcu; | ||
| 1479 | 1477 | ||
| 1480 | cred->tgcred->session_keyring = key_ref_to_ptr(keyring_r); | 1478 | cred->tgcred->session_keyring = key_ref_to_ptr(keyring_r); |
| 1481 | init_task_work(newwork, key_change_session_keyring, cred); | 1479 | init_task_work(newwork, key_change_session_keyring); |
| 1482 | 1480 | ||
| 1483 | me = current; | 1481 | me = current; |
| 1484 | rcu_read_lock(); | 1482 | rcu_read_lock(); |
| @@ -1488,6 +1486,7 @@ long keyctl_session_to_parent(void) | |||
| 1488 | oldwork = NULL; | 1486 | oldwork = NULL; |
| 1489 | parent = me->real_parent; | 1487 | parent = me->real_parent; |
| 1490 | 1488 | ||
| 1489 | task_lock(parent); | ||
| 1491 | /* the parent mustn't be init and mustn't be a kernel thread */ | 1490 | /* the parent mustn't be init and mustn't be a kernel thread */ |
| 1492 | if (parent->pid <= 1 || !parent->mm) | 1491 | if (parent->pid <= 1 || !parent->mm) |
| 1493 | goto unlock; | 1492 | goto unlock; |
| @@ -1531,20 +1530,15 @@ long keyctl_session_to_parent(void) | |||
| 1531 | if (!ret) | 1530 | if (!ret) |
| 1532 | newwork = NULL; | 1531 | newwork = NULL; |
| 1533 | unlock: | 1532 | unlock: |
| 1533 | task_unlock(parent); | ||
| 1534 | write_unlock_irq(&tasklist_lock); | 1534 | write_unlock_irq(&tasklist_lock); |
| 1535 | rcu_read_unlock(); | 1535 | rcu_read_unlock(); |
| 1536 | if (oldwork) { | 1536 | if (oldwork) |
| 1537 | put_cred(oldwork->data); | 1537 | put_cred(container_of(oldwork, struct cred, rcu)); |
| 1538 | kfree(oldwork); | 1538 | if (newwork) |
| 1539 | } | 1539 | put_cred(cred); |
| 1540 | if (newwork) { | ||
| 1541 | put_cred(newwork->data); | ||
| 1542 | kfree(newwork); | ||
| 1543 | } | ||
| 1544 | return ret; | 1540 | return ret; |
| 1545 | 1541 | ||
| 1546 | error_newwork: | ||
| 1547 | kfree(newwork); | ||
| 1548 | error_keyring: | 1542 | error_keyring: |
| 1549 | key_ref_put(keyring_r); | 1543 | key_ref_put(keyring_r); |
| 1550 | return ret; | 1544 | return ret; |
diff --git a/security/keys/keyring.c b/security/keys/keyring.c index 7445875f6818..81e7852d281d 100644 --- a/security/keys/keyring.c +++ b/security/keys/keyring.c | |||
| @@ -751,6 +751,7 @@ static void keyring_unlink_rcu_disposal(struct rcu_head *rcu) | |||
| 751 | int __key_link_begin(struct key *keyring, const struct key_type *type, | 751 | int __key_link_begin(struct key *keyring, const struct key_type *type, |
| 752 | const char *description, unsigned long *_prealloc) | 752 | const char *description, unsigned long *_prealloc) |
| 753 | __acquires(&keyring->sem) | 753 | __acquires(&keyring->sem) |
| 754 | __acquires(&keyring_serialise_link_sem) | ||
| 754 | { | 755 | { |
| 755 | struct keyring_list *klist, *nklist; | 756 | struct keyring_list *klist, *nklist; |
| 756 | unsigned long prealloc; | 757 | unsigned long prealloc; |
| @@ -960,6 +961,7 @@ void __key_link(struct key *keyring, struct key *key, | |||
| 960 | void __key_link_end(struct key *keyring, struct key_type *type, | 961 | void __key_link_end(struct key *keyring, struct key_type *type, |
| 961 | unsigned long prealloc) | 962 | unsigned long prealloc) |
| 962 | __releases(&keyring->sem) | 963 | __releases(&keyring->sem) |
| 964 | __releases(&keyring_serialise_link_sem) | ||
| 963 | { | 965 | { |
| 964 | BUG_ON(type == NULL); | 966 | BUG_ON(type == NULL); |
| 965 | BUG_ON(type->name == NULL); | 967 | BUG_ON(type->name == NULL); |
diff --git a/security/keys/process_keys.c b/security/keys/process_keys.c index 4ad54eea1ea4..54339cfd6734 100644 --- a/security/keys/process_keys.c +++ b/security/keys/process_keys.c | |||
| @@ -834,12 +834,11 @@ error: | |||
| 834 | * Replace a process's session keyring on behalf of one of its children when | 834 | * Replace a process's session keyring on behalf of one of its children when |
| 835 | * the target process is about to resume userspace execution. | 835 | * the target process is about to resume userspace execution. |
| 836 | */ | 836 | */ |
| 837 | void key_change_session_keyring(struct task_work *twork) | 837 | void key_change_session_keyring(struct callback_head *twork) |
| 838 | { | 838 | { |
| 839 | const struct cred *old = current_cred(); | 839 | const struct cred *old = current_cred(); |
| 840 | struct cred *new = twork->data; | 840 | struct cred *new = container_of(twork, struct cred, rcu); |
| 841 | 841 | ||
| 842 | kfree(twork); | ||
| 843 | if (unlikely(current->flags & PF_EXITING)) { | 842 | if (unlikely(current->flags & PF_EXITING)) { |
| 844 | put_cred(new); | 843 | put_cred(new); |
| 845 | return; | 844 | return; |
diff --git a/security/security.c b/security/security.c index 3efc9b12aef4..860aeb349cb3 100644 --- a/security/security.c +++ b/security/security.c | |||
| @@ -23,6 +23,7 @@ | |||
| 23 | #include <linux/mman.h> | 23 | #include <linux/mman.h> |
| 24 | #include <linux/mount.h> | 24 | #include <linux/mount.h> |
| 25 | #include <linux/personality.h> | 25 | #include <linux/personality.h> |
| 26 | #include <linux/backing-dev.h> | ||
| 26 | #include <net/flow.h> | 27 | #include <net/flow.h> |
| 27 | 28 | ||
| 28 | #define MAX_LSM_EVM_XATTR 2 | 29 | #define MAX_LSM_EVM_XATTR 2 |
diff --git a/security/selinux/avc.c b/security/selinux/avc.c index 68d82daed257..4d3fab47e643 100644 --- a/security/selinux/avc.c +++ b/security/selinux/avc.c | |||
| @@ -274,7 +274,7 @@ static struct avc_node *avc_alloc_node(void) | |||
| 274 | { | 274 | { |
| 275 | struct avc_node *node; | 275 | struct avc_node *node; |
| 276 | 276 | ||
| 277 | node = kmem_cache_zalloc(avc_node_cachep, GFP_ATOMIC); | 277 | node = kmem_cache_zalloc(avc_node_cachep, GFP_ATOMIC|__GFP_NOMEMALLOC); |
| 278 | if (!node) | 278 | if (!node) |
| 279 | goto out; | 279 | goto out; |
| 280 | 280 | ||
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 372ec6502aa8..6c77f63c7591 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c | |||
| @@ -2129,7 +2129,7 @@ static inline void flush_unauthorized_files(const struct cred *cred, | |||
| 2129 | int fd; | 2129 | int fd; |
| 2130 | 2130 | ||
| 2131 | j++; | 2131 | j++; |
| 2132 | i = j * __NFDBITS; | 2132 | i = j * BITS_PER_LONG; |
| 2133 | fdt = files_fdtable(files); | 2133 | fdt = files_fdtable(files); |
| 2134 | if (i >= fdt->max_fds) | 2134 | if (i >= fdt->max_fds) |
| 2135 | break; | 2135 | break; |
| @@ -2157,8 +2157,7 @@ static inline void flush_unauthorized_files(const struct cred *cred, | |||
| 2157 | get_file(devnull); | 2157 | get_file(devnull); |
| 2158 | } else { | 2158 | } else { |
| 2159 | devnull = dentry_open( | 2159 | devnull = dentry_open( |
| 2160 | dget(selinux_null), | 2160 | &selinux_null, |
| 2161 | mntget(selinuxfs_mount), | ||
| 2162 | O_RDWR, cred); | 2161 | O_RDWR, cred); |
| 2163 | if (IS_ERR(devnull)) { | 2162 | if (IS_ERR(devnull)) { |
| 2164 | devnull = NULL; | 2163 | devnull = NULL; |
| @@ -2717,7 +2716,7 @@ static int selinux_inode_setattr(struct dentry *dentry, struct iattr *iattr) | |||
| 2717 | ATTR_ATIME_SET | ATTR_MTIME_SET | ATTR_TIMES_SET)) | 2716 | ATTR_ATIME_SET | ATTR_MTIME_SET | ATTR_TIMES_SET)) |
| 2718 | return dentry_has_perm(cred, dentry, FILE__SETATTR); | 2717 | return dentry_has_perm(cred, dentry, FILE__SETATTR); |
| 2719 | 2718 | ||
| 2720 | if (ia_valid & ATTR_SIZE) | 2719 | if (selinux_policycap_openperm && (ia_valid & ATTR_SIZE)) |
| 2721 | av |= FILE__OPEN; | 2720 | av |= FILE__OPEN; |
| 2722 | 2721 | ||
| 2723 | return dentry_has_perm(cred, dentry, av); | 2722 | return dentry_has_perm(cred, dentry, av); |
| @@ -2792,11 +2791,16 @@ static int selinux_inode_setxattr(struct dentry *dentry, const char *name, | |||
| 2792 | 2791 | ||
| 2793 | /* We strip a nul only if it is at the end, otherwise the | 2792 | /* We strip a nul only if it is at the end, otherwise the |
| 2794 | * context contains a nul and we should audit that */ | 2793 | * context contains a nul and we should audit that */ |
| 2795 | str = value; | 2794 | if (value) { |
| 2796 | if (str[size - 1] == '\0') | 2795 | str = value; |
| 2797 | audit_size = size - 1; | 2796 | if (str[size - 1] == '\0') |
| 2798 | else | 2797 | audit_size = size - 1; |
| 2799 | audit_size = size; | 2798 | else |
| 2799 | audit_size = size; | ||
| 2800 | } else { | ||
| 2801 | str = ""; | ||
| 2802 | audit_size = 0; | ||
| 2803 | } | ||
| 2800 | ab = audit_log_start(current->audit_context, GFP_ATOMIC, AUDIT_SELINUX_ERR); | 2804 | ab = audit_log_start(current->audit_context, GFP_ATOMIC, AUDIT_SELINUX_ERR); |
| 2801 | audit_log_format(ab, "op=setxattr invalid_context="); | 2805 | audit_log_format(ab, "op=setxattr invalid_context="); |
| 2802 | audit_log_n_untrustedstring(ab, value, audit_size); | 2806 | audit_log_n_untrustedstring(ab, value, audit_size); |
| @@ -3181,6 +3185,7 @@ static int selinux_file_fcntl(struct file *file, unsigned int cmd, | |||
| 3181 | case F_GETFL: | 3185 | case F_GETFL: |
| 3182 | case F_GETOWN: | 3186 | case F_GETOWN: |
| 3183 | case F_GETSIG: | 3187 | case F_GETSIG: |
| 3188 | case F_GETOWNER_UIDS: | ||
| 3184 | /* Just check FD__USE permission */ | 3189 | /* Just check FD__USE permission */ |
| 3185 | err = file_has_perm(cred, file, 0); | 3190 | err = file_has_perm(cred, file, 0); |
| 3186 | break; | 3191 | break; |
| @@ -5763,21 +5768,21 @@ static struct nf_hook_ops selinux_ipv4_ops[] = { | |||
| 5763 | { | 5768 | { |
| 5764 | .hook = selinux_ipv4_postroute, | 5769 | .hook = selinux_ipv4_postroute, |
| 5765 | .owner = THIS_MODULE, | 5770 | .owner = THIS_MODULE, |
| 5766 | .pf = PF_INET, | 5771 | .pf = NFPROTO_IPV4, |
| 5767 | .hooknum = NF_INET_POST_ROUTING, | 5772 | .hooknum = NF_INET_POST_ROUTING, |
| 5768 | .priority = NF_IP_PRI_SELINUX_LAST, | 5773 | .priority = NF_IP_PRI_SELINUX_LAST, |
| 5769 | }, | 5774 | }, |
| 5770 | { | 5775 | { |
| 5771 | .hook = selinux_ipv4_forward, | 5776 | .hook = selinux_ipv4_forward, |
| 5772 | .owner = THIS_MODULE, | 5777 | .owner = THIS_MODULE, |
| 5773 | .pf = PF_INET, | 5778 | .pf = NFPROTO_IPV4, |
| 5774 | .hooknum = NF_INET_FORWARD, | 5779 | .hooknum = NF_INET_FORWARD, |
| 5775 | .priority = NF_IP_PRI_SELINUX_FIRST, | 5780 | .priority = NF_IP_PRI_SELINUX_FIRST, |
| 5776 | }, | 5781 | }, |
| 5777 | { | 5782 | { |
| 5778 | .hook = selinux_ipv4_output, | 5783 | .hook = selinux_ipv4_output, |
| 5779 | .owner = THIS_MODULE, | 5784 | .owner = THIS_MODULE, |
| 5780 | .pf = PF_INET, | 5785 | .pf = NFPROTO_IPV4, |
| 5781 | .hooknum = NF_INET_LOCAL_OUT, | 5786 | .hooknum = NF_INET_LOCAL_OUT, |
| 5782 | .priority = NF_IP_PRI_SELINUX_FIRST, | 5787 | .priority = NF_IP_PRI_SELINUX_FIRST, |
| 5783 | } | 5788 | } |
| @@ -5789,14 +5794,14 @@ static struct nf_hook_ops selinux_ipv6_ops[] = { | |||
| 5789 | { | 5794 | { |
| 5790 | .hook = selinux_ipv6_postroute, | 5795 | .hook = selinux_ipv6_postroute, |
| 5791 | .owner = THIS_MODULE, | 5796 | .owner = THIS_MODULE, |
| 5792 | .pf = PF_INET6, | 5797 | .pf = NFPROTO_IPV6, |
| 5793 | .hooknum = NF_INET_POST_ROUTING, | 5798 | .hooknum = NF_INET_POST_ROUTING, |
| 5794 | .priority = NF_IP6_PRI_SELINUX_LAST, | 5799 | .priority = NF_IP6_PRI_SELINUX_LAST, |
| 5795 | }, | 5800 | }, |
| 5796 | { | 5801 | { |
| 5797 | .hook = selinux_ipv6_forward, | 5802 | .hook = selinux_ipv6_forward, |
| 5798 | .owner = THIS_MODULE, | 5803 | .owner = THIS_MODULE, |
| 5799 | .pf = PF_INET6, | 5804 | .pf = NFPROTO_IPV6, |
| 5800 | .hooknum = NF_INET_FORWARD, | 5805 | .hooknum = NF_INET_FORWARD, |
| 5801 | .priority = NF_IP6_PRI_SELINUX_FIRST, | 5806 | .priority = NF_IP6_PRI_SELINUX_FIRST, |
| 5802 | } | 5807 | } |
diff --git a/security/selinux/include/classmap.h b/security/selinux/include/classmap.h index b8c53723e09b..df2de54a958d 100644 --- a/security/selinux/include/classmap.h +++ b/security/selinux/include/classmap.h | |||
| @@ -145,7 +145,9 @@ struct security_class_mapping secclass_map[] = { | |||
| 145 | "node_bind", "name_connect", NULL } }, | 145 | "node_bind", "name_connect", NULL } }, |
| 146 | { "memprotect", { "mmap_zero", NULL } }, | 146 | { "memprotect", { "mmap_zero", NULL } }, |
| 147 | { "peer", { "recv", NULL } }, | 147 | { "peer", { "recv", NULL } }, |
| 148 | { "capability2", { "mac_override", "mac_admin", "syslog", NULL } }, | 148 | { "capability2", |
| 149 | { "mac_override", "mac_admin", "syslog", "wake_alarm", "block_suspend", | ||
| 150 | NULL } }, | ||
| 149 | { "kernel_service", { "use_as_override", "create_files_as", NULL } }, | 151 | { "kernel_service", { "use_as_override", "create_files_as", NULL } }, |
| 150 | { "tun_socket", | 152 | { "tun_socket", |
| 151 | { COMMON_SOCK_PERMS, NULL } }, | 153 | { COMMON_SOCK_PERMS, NULL } }, |
diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h index dde2005407aa..6d3885165d14 100644 --- a/security/selinux/include/security.h +++ b/security/selinux/include/security.h | |||
| @@ -221,7 +221,7 @@ extern void selinux_status_update_policyload(int seqno); | |||
| 221 | extern void selinux_complete_init(void); | 221 | extern void selinux_complete_init(void); |
| 222 | extern int selinux_disable(void); | 222 | extern int selinux_disable(void); |
| 223 | extern void exit_sel_fs(void); | 223 | extern void exit_sel_fs(void); |
| 224 | extern struct dentry *selinux_null; | 224 | extern struct path selinux_null; |
| 225 | extern struct vfsmount *selinuxfs_mount; | 225 | extern struct vfsmount *selinuxfs_mount; |
| 226 | extern void selnl_notify_setenforce(int val); | 226 | extern void selnl_notify_setenforce(int val); |
| 227 | extern void selnl_notify_policyload(u32 seqno); | 227 | extern void selnl_notify_policyload(u32 seqno); |
diff --git a/security/selinux/netlink.c b/security/selinux/netlink.c index 161e01a6c7ef..8a77725423e0 100644 --- a/security/selinux/netlink.c +++ b/security/selinux/netlink.c | |||
| @@ -19,6 +19,7 @@ | |||
| 19 | #include <linux/netlink.h> | 19 | #include <linux/netlink.h> |
| 20 | #include <linux/selinux_netlink.h> | 20 | #include <linux/selinux_netlink.h> |
| 21 | #include <net/net_namespace.h> | 21 | #include <net/net_namespace.h> |
| 22 | #include <net/netlink.h> | ||
| 22 | 23 | ||
| 23 | #include "security.h" | 24 | #include "security.h" |
| 24 | 25 | ||
| @@ -47,7 +48,7 @@ static void selnl_add_payload(struct nlmsghdr *nlh, int len, int msgtype, void * | |||
| 47 | { | 48 | { |
| 48 | switch (msgtype) { | 49 | switch (msgtype) { |
| 49 | case SELNL_MSG_SETENFORCE: { | 50 | case SELNL_MSG_SETENFORCE: { |
| 50 | struct selnl_msg_setenforce *msg = NLMSG_DATA(nlh); | 51 | struct selnl_msg_setenforce *msg = nlmsg_data(nlh); |
| 51 | 52 | ||
| 52 | memset(msg, 0, len); | 53 | memset(msg, 0, len); |
| 53 | msg->val = *((int *)data); | 54 | msg->val = *((int *)data); |
| @@ -55,7 +56,7 @@ static void selnl_add_payload(struct nlmsghdr *nlh, int len, int msgtype, void * | |||
| 55 | } | 56 | } |
| 56 | 57 | ||
| 57 | case SELNL_MSG_POLICYLOAD: { | 58 | case SELNL_MSG_POLICYLOAD: { |
| 58 | struct selnl_msg_policyload *msg = NLMSG_DATA(nlh); | 59 | struct selnl_msg_policyload *msg = nlmsg_data(nlh); |
| 59 | 60 | ||
| 60 | memset(msg, 0, len); | 61 | memset(msg, 0, len); |
| 61 | msg->seqno = *((u32 *)data); | 62 | msg->seqno = *((u32 *)data); |
| @@ -81,7 +82,9 @@ static void selnl_notify(int msgtype, void *data) | |||
| 81 | goto oom; | 82 | goto oom; |
| 82 | 83 | ||
| 83 | tmp = skb->tail; | 84 | tmp = skb->tail; |
| 84 | nlh = NLMSG_PUT(skb, 0, 0, msgtype, len); | 85 | nlh = nlmsg_put(skb, 0, 0, msgtype, len, 0); |
| 86 | if (!nlh) | ||
| 87 | goto out_kfree_skb; | ||
| 85 | selnl_add_payload(nlh, len, msgtype, data); | 88 | selnl_add_payload(nlh, len, msgtype, data); |
| 86 | nlh->nlmsg_len = skb->tail - tmp; | 89 | nlh->nlmsg_len = skb->tail - tmp; |
| 87 | NETLINK_CB(skb).dst_group = SELNLGRP_AVC; | 90 | NETLINK_CB(skb).dst_group = SELNLGRP_AVC; |
| @@ -89,7 +92,7 @@ static void selnl_notify(int msgtype, void *data) | |||
| 89 | out: | 92 | out: |
| 90 | return; | 93 | return; |
| 91 | 94 | ||
| 92 | nlmsg_failure: | 95 | out_kfree_skb: |
| 93 | kfree_skb(skb); | 96 | kfree_skb(skb); |
| 94 | oom: | 97 | oom: |
| 95 | printk(KERN_ERR "SELinux: OOM in %s\n", __func__); | 98 | printk(KERN_ERR "SELinux: OOM in %s\n", __func__); |
| @@ -108,8 +111,12 @@ void selnl_notify_policyload(u32 seqno) | |||
| 108 | 111 | ||
| 109 | static int __init selnl_init(void) | 112 | static int __init selnl_init(void) |
| 110 | { | 113 | { |
| 114 | struct netlink_kernel_cfg cfg = { | ||
| 115 | .groups = SELNLGRP_MAX, | ||
| 116 | }; | ||
| 117 | |||
| 111 | selnl = netlink_kernel_create(&init_net, NETLINK_SELINUX, | 118 | selnl = netlink_kernel_create(&init_net, NETLINK_SELINUX, |
| 112 | SELNLGRP_MAX, NULL, NULL, THIS_MODULE); | 119 | THIS_MODULE, &cfg); |
| 113 | if (selnl == NULL) | 120 | if (selnl == NULL) |
| 114 | panic("SELinux: Cannot create netlink socket."); | 121 | panic("SELinux: Cannot create netlink socket."); |
| 115 | netlink_set_nonroot(NETLINK_SELINUX, NL_NONROOT_RECV); | 122 | netlink_set_nonroot(NETLINK_SELINUX, NL_NONROOT_RECV); |
diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c index 3ad290251288..298e695d6822 100644 --- a/security/selinux/selinuxfs.c +++ b/security/selinux/selinuxfs.c | |||
| @@ -1297,7 +1297,7 @@ out: | |||
| 1297 | 1297 | ||
| 1298 | #define NULL_FILE_NAME "null" | 1298 | #define NULL_FILE_NAME "null" |
| 1299 | 1299 | ||
| 1300 | struct dentry *selinux_null; | 1300 | struct path selinux_null; |
| 1301 | 1301 | ||
| 1302 | static ssize_t sel_read_avc_cache_threshold(struct file *filp, char __user *buf, | 1302 | static ssize_t sel_read_avc_cache_threshold(struct file *filp, char __user *buf, |
| 1303 | size_t count, loff_t *ppos) | 1303 | size_t count, loff_t *ppos) |
| @@ -1838,7 +1838,7 @@ static int sel_fill_super(struct super_block *sb, void *data, int silent) | |||
| 1838 | 1838 | ||
| 1839 | init_special_inode(inode, S_IFCHR | S_IRUGO | S_IWUGO, MKDEV(MEM_MAJOR, 3)); | 1839 | init_special_inode(inode, S_IFCHR | S_IRUGO | S_IWUGO, MKDEV(MEM_MAJOR, 3)); |
| 1840 | d_add(dentry, inode); | 1840 | d_add(dentry, inode); |
| 1841 | selinux_null = dentry; | 1841 | selinux_null.dentry = dentry; |
| 1842 | 1842 | ||
| 1843 | dentry = sel_make_dir(sb->s_root, "avc", &sel_last_ino); | 1843 | dentry = sel_make_dir(sb->s_root, "avc", &sel_last_ino); |
| 1844 | if (IS_ERR(dentry)) { | 1844 | if (IS_ERR(dentry)) { |
| @@ -1912,7 +1912,7 @@ static int __init init_sel_fs(void) | |||
| 1912 | return err; | 1912 | return err; |
| 1913 | } | 1913 | } |
| 1914 | 1914 | ||
| 1915 | selinuxfs_mount = kern_mount(&sel_fs_type); | 1915 | selinux_null.mnt = selinuxfs_mount = kern_mount(&sel_fs_type); |
| 1916 | if (IS_ERR(selinuxfs_mount)) { | 1916 | if (IS_ERR(selinuxfs_mount)) { |
| 1917 | printk(KERN_ERR "selinuxfs: could not mount!\n"); | 1917 | printk(KERN_ERR "selinuxfs: could not mount!\n"); |
| 1918 | err = PTR_ERR(selinuxfs_mount); | 1918 | err = PTR_ERR(selinuxfs_mount); |
diff --git a/security/smack/smack.h b/security/smack/smack.h index cc361b8f3d13..99b36124f712 100644 --- a/security/smack/smack.h +++ b/security/smack/smack.h | |||
| @@ -43,7 +43,6 @@ struct superblock_smack { | |||
| 43 | char *smk_hat; | 43 | char *smk_hat; |
| 44 | char *smk_default; | 44 | char *smk_default; |
| 45 | int smk_initialized; | 45 | int smk_initialized; |
| 46 | spinlock_t smk_sblock; /* for initialization */ | ||
| 47 | }; | 46 | }; |
| 48 | 47 | ||
| 49 | struct socket_smack { | 48 | struct socket_smack { |
| @@ -284,6 +283,19 @@ static inline char *smk_of_current(void) | |||
| 284 | } | 283 | } |
| 285 | 284 | ||
| 286 | /* | 285 | /* |
| 286 | * Is the task privileged and allowed to be privileged | ||
| 287 | * by the onlycap rule. | ||
| 288 | */ | ||
| 289 | static inline int smack_privileged(int cap) | ||
| 290 | { | ||
| 291 | if (!capable(cap)) | ||
| 292 | return 0; | ||
| 293 | if (smack_onlycap == NULL || smack_onlycap == smk_of_current()) | ||
| 294 | return 1; | ||
| 295 | return 0; | ||
| 296 | } | ||
| 297 | |||
| 298 | /* | ||
| 287 | * logging functions | 299 | * logging functions |
| 288 | */ | 300 | */ |
| 289 | #define SMACK_AUDIT_DENIED 0x1 | 301 | #define SMACK_AUDIT_DENIED 0x1 |
diff --git a/security/smack/smack_access.c b/security/smack/smack_access.c index 9f3705e92712..db14689a21e0 100644 --- a/security/smack/smack_access.c +++ b/security/smack/smack_access.c | |||
| @@ -220,14 +220,9 @@ int smk_curacc(char *obj_label, u32 mode, struct smk_audit_info *a) | |||
| 220 | } | 220 | } |
| 221 | 221 | ||
| 222 | /* | 222 | /* |
| 223 | * Return if a specific label has been designated as the | 223 | * Allow for priviliged to override policy. |
| 224 | * only one that gets privilege and current does not | ||
| 225 | * have that label. | ||
| 226 | */ | 224 | */ |
| 227 | if (smack_onlycap != NULL && smack_onlycap != sp) | 225 | if (rc != 0 && smack_privileged(CAP_MAC_OVERRIDE)) |
| 228 | goto out_audit; | ||
| 229 | |||
| 230 | if (capable(CAP_MAC_OVERRIDE)) | ||
| 231 | rc = 0; | 226 | rc = 0; |
| 232 | 227 | ||
| 233 | out_audit: | 228 | out_audit: |
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c index ee0bb5735f35..8221514cc997 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c | |||
| @@ -217,7 +217,7 @@ static int smack_syslog(int typefrom_file) | |||
| 217 | int rc = 0; | 217 | int rc = 0; |
| 218 | char *sp = smk_of_current(); | 218 | char *sp = smk_of_current(); |
| 219 | 219 | ||
| 220 | if (capable(CAP_MAC_OVERRIDE)) | 220 | if (smack_privileged(CAP_MAC_OVERRIDE)) |
| 221 | return 0; | 221 | return 0; |
| 222 | 222 | ||
| 223 | if (sp != smack_known_floor.smk_known) | 223 | if (sp != smack_known_floor.smk_known) |
| @@ -251,7 +251,6 @@ static int smack_sb_alloc_security(struct super_block *sb) | |||
| 251 | sbsp->smk_floor = smack_known_floor.smk_known; | 251 | sbsp->smk_floor = smack_known_floor.smk_known; |
| 252 | sbsp->smk_hat = smack_known_hat.smk_known; | 252 | sbsp->smk_hat = smack_known_hat.smk_known; |
| 253 | sbsp->smk_initialized = 0; | 253 | sbsp->smk_initialized = 0; |
| 254 | spin_lock_init(&sbsp->smk_sblock); | ||
| 255 | 254 | ||
| 256 | sb->s_security = sbsp; | 255 | sb->s_security = sbsp; |
| 257 | 256 | ||
| @@ -332,13 +331,10 @@ static int smack_sb_kern_mount(struct super_block *sb, int flags, void *data) | |||
| 332 | char *commap; | 331 | char *commap; |
| 333 | char *nsp; | 332 | char *nsp; |
| 334 | 333 | ||
| 335 | spin_lock(&sp->smk_sblock); | 334 | if (sp->smk_initialized != 0) |
| 336 | if (sp->smk_initialized != 0) { | ||
| 337 | spin_unlock(&sp->smk_sblock); | ||
| 338 | return 0; | 335 | return 0; |
| 339 | } | 336 | |
| 340 | sp->smk_initialized = 1; | 337 | sp->smk_initialized = 1; |
| 341 | spin_unlock(&sp->smk_sblock); | ||
| 342 | 338 | ||
| 343 | for (op = data; op != NULL; op = commap) { | 339 | for (op = data; op != NULL; op = commap) { |
| 344 | commap = strchr(op, ','); | 340 | commap = strchr(op, ','); |
| @@ -825,7 +821,7 @@ static int smack_inode_setxattr(struct dentry *dentry, const char *name, | |||
| 825 | strcmp(name, XATTR_NAME_SMACKIPOUT) == 0 || | 821 | strcmp(name, XATTR_NAME_SMACKIPOUT) == 0 || |
| 826 | strcmp(name, XATTR_NAME_SMACKEXEC) == 0 || | 822 | strcmp(name, XATTR_NAME_SMACKEXEC) == 0 || |
| 827 | strcmp(name, XATTR_NAME_SMACKMMAP) == 0) { | 823 | strcmp(name, XATTR_NAME_SMACKMMAP) == 0) { |
| 828 | if (!capable(CAP_MAC_ADMIN)) | 824 | if (!smack_privileged(CAP_MAC_ADMIN)) |
| 829 | rc = -EPERM; | 825 | rc = -EPERM; |
| 830 | /* | 826 | /* |
| 831 | * check label validity here so import wont fail on | 827 | * check label validity here so import wont fail on |
| @@ -835,7 +831,7 @@ static int smack_inode_setxattr(struct dentry *dentry, const char *name, | |||
| 835 | smk_import(value, size) == NULL) | 831 | smk_import(value, size) == NULL) |
| 836 | rc = -EINVAL; | 832 | rc = -EINVAL; |
| 837 | } else if (strcmp(name, XATTR_NAME_SMACKTRANSMUTE) == 0) { | 833 | } else if (strcmp(name, XATTR_NAME_SMACKTRANSMUTE) == 0) { |
| 838 | if (!capable(CAP_MAC_ADMIN)) | 834 | if (!smack_privileged(CAP_MAC_ADMIN)) |
| 839 | rc = -EPERM; | 835 | rc = -EPERM; |
| 840 | if (size != TRANS_TRUE_SIZE || | 836 | if (size != TRANS_TRUE_SIZE || |
| 841 | strncmp(value, TRANS_TRUE, TRANS_TRUE_SIZE) != 0) | 837 | strncmp(value, TRANS_TRUE, TRANS_TRUE_SIZE) != 0) |
| @@ -931,7 +927,7 @@ static int smack_inode_removexattr(struct dentry *dentry, const char *name) | |||
| 931 | strcmp(name, XATTR_NAME_SMACKEXEC) == 0 || | 927 | strcmp(name, XATTR_NAME_SMACKEXEC) == 0 || |
| 932 | strcmp(name, XATTR_NAME_SMACKTRANSMUTE) == 0 || | 928 | strcmp(name, XATTR_NAME_SMACKTRANSMUTE) == 0 || |
| 933 | strcmp(name, XATTR_NAME_SMACKMMAP)) { | 929 | strcmp(name, XATTR_NAME_SMACKMMAP)) { |
| 934 | if (!capable(CAP_MAC_ADMIN)) | 930 | if (!smack_privileged(CAP_MAC_ADMIN)) |
| 935 | rc = -EPERM; | 931 | rc = -EPERM; |
| 936 | } else | 932 | } else |
| 937 | rc = cap_inode_removexattr(dentry, name); | 933 | rc = cap_inode_removexattr(dentry, name); |
| @@ -1720,7 +1716,8 @@ static int smack_task_wait(struct task_struct *p) | |||
| 1720 | * state into account in the decision as well as | 1716 | * state into account in the decision as well as |
| 1721 | * the smack value. | 1717 | * the smack value. |
| 1722 | */ | 1718 | */ |
| 1723 | if (capable(CAP_MAC_OVERRIDE) || has_capability(p, CAP_MAC_OVERRIDE)) | 1719 | if (smack_privileged(CAP_MAC_OVERRIDE) || |
| 1720 | has_capability(p, CAP_MAC_OVERRIDE)) | ||
| 1724 | rc = 0; | 1721 | rc = 0; |
| 1725 | /* we log only if we didn't get overriden */ | 1722 | /* we log only if we didn't get overriden */ |
| 1726 | out_log: | 1723 | out_log: |
| @@ -2721,7 +2718,7 @@ static int smack_setprocattr(struct task_struct *p, char *name, | |||
| 2721 | if (p != current) | 2718 | if (p != current) |
| 2722 | return -EPERM; | 2719 | return -EPERM; |
| 2723 | 2720 | ||
| 2724 | if (!capable(CAP_MAC_ADMIN)) | 2721 | if (!smack_privileged(CAP_MAC_ADMIN)) |
| 2725 | return -EPERM; | 2722 | return -EPERM; |
| 2726 | 2723 | ||
| 2727 | if (value == NULL || size == 0 || size >= SMK_LONGLABEL) | 2724 | if (value == NULL || size == 0 || size >= SMK_LONGLABEL) |
| @@ -2784,7 +2781,7 @@ static int smack_unix_stream_connect(struct sock *sock, | |||
| 2784 | smk_ad_setfield_u_net_sk(&ad, other); | 2781 | smk_ad_setfield_u_net_sk(&ad, other); |
| 2785 | #endif | 2782 | #endif |
| 2786 | 2783 | ||
| 2787 | if (!capable(CAP_MAC_OVERRIDE)) | 2784 | if (!smack_privileged(CAP_MAC_OVERRIDE)) |
| 2788 | rc = smk_access(ssp->smk_out, osp->smk_in, MAY_WRITE, &ad); | 2785 | rc = smk_access(ssp->smk_out, osp->smk_in, MAY_WRITE, &ad); |
| 2789 | 2786 | ||
| 2790 | /* | 2787 | /* |
| @@ -2820,7 +2817,7 @@ static int smack_unix_may_send(struct socket *sock, struct socket *other) | |||
| 2820 | smk_ad_setfield_u_net_sk(&ad, other->sk); | 2817 | smk_ad_setfield_u_net_sk(&ad, other->sk); |
| 2821 | #endif | 2818 | #endif |
| 2822 | 2819 | ||
| 2823 | if (!capable(CAP_MAC_OVERRIDE)) | 2820 | if (!smack_privileged(CAP_MAC_OVERRIDE)) |
| 2824 | rc = smk_access(ssp->smk_out, osp->smk_in, MAY_WRITE, &ad); | 2821 | rc = smk_access(ssp->smk_out, osp->smk_in, MAY_WRITE, &ad); |
| 2825 | 2822 | ||
| 2826 | return rc; | 2823 | return rc; |
diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c index 1810c9a4ed48..b1b768e4049a 100644 --- a/security/smack/smackfs.c +++ b/security/smack/smackfs.c | |||
| @@ -215,28 +215,27 @@ static int smk_set_access(struct smack_rule *srp, struct list_head *rule_list, | |||
| 215 | * @access: access string | 215 | * @access: access string |
| 216 | * @rule: Smack rule | 216 | * @rule: Smack rule |
| 217 | * @import: if non-zero, import labels | 217 | * @import: if non-zero, import labels |
| 218 | * @len: label length limit | ||
| 218 | * | 219 | * |
| 219 | * Returns 0 on success, -1 on failure | 220 | * Returns 0 on success, -1 on failure |
| 220 | */ | 221 | */ |
| 221 | static int smk_fill_rule(const char *subject, const char *object, | 222 | static int smk_fill_rule(const char *subject, const char *object, |
| 222 | const char *access, struct smack_rule *rule, | 223 | const char *access, struct smack_rule *rule, |
| 223 | int import) | 224 | int import, int len) |
| 224 | { | 225 | { |
| 225 | int rc = -1; | ||
| 226 | int done; | ||
| 227 | const char *cp; | 226 | const char *cp; |
| 228 | struct smack_known *skp; | 227 | struct smack_known *skp; |
| 229 | 228 | ||
| 230 | if (import) { | 229 | if (import) { |
| 231 | rule->smk_subject = smk_import(subject, 0); | 230 | rule->smk_subject = smk_import(subject, len); |
| 232 | if (rule->smk_subject == NULL) | 231 | if (rule->smk_subject == NULL) |
| 233 | return -1; | 232 | return -1; |
| 234 | 233 | ||
| 235 | rule->smk_object = smk_import(object, 0); | 234 | rule->smk_object = smk_import(object, len); |
| 236 | if (rule->smk_object == NULL) | 235 | if (rule->smk_object == NULL) |
| 237 | return -1; | 236 | return -1; |
| 238 | } else { | 237 | } else { |
| 239 | cp = smk_parse_smack(subject, 0); | 238 | cp = smk_parse_smack(subject, len); |
| 240 | if (cp == NULL) | 239 | if (cp == NULL) |
| 241 | return -1; | 240 | return -1; |
| 242 | skp = smk_find_entry(cp); | 241 | skp = smk_find_entry(cp); |
| @@ -245,7 +244,7 @@ static int smk_fill_rule(const char *subject, const char *object, | |||
| 245 | return -1; | 244 | return -1; |
| 246 | rule->smk_subject = skp->smk_known; | 245 | rule->smk_subject = skp->smk_known; |
| 247 | 246 | ||
| 248 | cp = smk_parse_smack(object, 0); | 247 | cp = smk_parse_smack(object, len); |
| 249 | if (cp == NULL) | 248 | if (cp == NULL) |
| 250 | return -1; | 249 | return -1; |
| 251 | skp = smk_find_entry(cp); | 250 | skp = smk_find_entry(cp); |
| @@ -257,7 +256,7 @@ static int smk_fill_rule(const char *subject, const char *object, | |||
| 257 | 256 | ||
| 258 | rule->smk_access = 0; | 257 | rule->smk_access = 0; |
| 259 | 258 | ||
| 260 | for (cp = access, done = 0; *cp && !done; cp++) { | 259 | for (cp = access; *cp != '\0'; cp++) { |
| 261 | switch (*cp) { | 260 | switch (*cp) { |
| 262 | case '-': | 261 | case '-': |
| 263 | break; | 262 | break; |
| @@ -282,13 +281,11 @@ static int smk_fill_rule(const char *subject, const char *object, | |||
| 282 | rule->smk_access |= MAY_TRANSMUTE; | 281 | rule->smk_access |= MAY_TRANSMUTE; |
| 283 | break; | 282 | break; |
| 284 | default: | 283 | default: |
| 285 | done = 1; | 284 | return 0; |
| 286 | break; | ||
| 287 | } | 285 | } |
| 288 | } | 286 | } |
| 289 | rc = 0; | ||
| 290 | 287 | ||
| 291 | return rc; | 288 | return 0; |
| 292 | } | 289 | } |
| 293 | 290 | ||
| 294 | /** | 291 | /** |
| @@ -304,7 +301,8 @@ static int smk_parse_rule(const char *data, struct smack_rule *rule, int import) | |||
| 304 | int rc; | 301 | int rc; |
| 305 | 302 | ||
| 306 | rc = smk_fill_rule(data, data + SMK_LABELLEN, | 303 | rc = smk_fill_rule(data, data + SMK_LABELLEN, |
| 307 | data + SMK_LABELLEN + SMK_LABELLEN, rule, import); | 304 | data + SMK_LABELLEN + SMK_LABELLEN, rule, import, |
| 305 | SMK_LABELLEN); | ||
| 308 | return rc; | 306 | return rc; |
| 309 | } | 307 | } |
| 310 | 308 | ||
| @@ -325,11 +323,11 @@ static int smk_parse_long_rule(const char *data, struct smack_rule *rule, | |||
| 325 | int datalen; | 323 | int datalen; |
| 326 | int rc = -1; | 324 | int rc = -1; |
| 327 | 325 | ||
| 328 | /* | 326 | /* This is inefficient */ |
| 329 | * This is probably inefficient, but safe. | ||
| 330 | */ | ||
| 331 | datalen = strlen(data); | 327 | datalen = strlen(data); |
| 332 | subject = kzalloc(datalen, GFP_KERNEL); | 328 | |
| 329 | /* Our first element can be 64 + \0 with no spaces */ | ||
| 330 | subject = kzalloc(datalen + 1, GFP_KERNEL); | ||
| 333 | if (subject == NULL) | 331 | if (subject == NULL) |
| 334 | return -1; | 332 | return -1; |
| 335 | object = kzalloc(datalen, GFP_KERNEL); | 333 | object = kzalloc(datalen, GFP_KERNEL); |
| @@ -340,7 +338,7 @@ static int smk_parse_long_rule(const char *data, struct smack_rule *rule, | |||
| 340 | goto free_out_o; | 338 | goto free_out_o; |
| 341 | 339 | ||
| 342 | if (sscanf(data, "%s %s %s", subject, object, access) == 3) | 340 | if (sscanf(data, "%s %s %s", subject, object, access) == 3) |
| 343 | rc = smk_fill_rule(subject, object, access, rule, import); | 341 | rc = smk_fill_rule(subject, object, access, rule, import, 0); |
| 344 | 342 | ||
| 345 | kfree(access); | 343 | kfree(access); |
| 346 | free_out_o: | 344 | free_out_o: |
| @@ -520,6 +518,9 @@ static void smk_rule_show(struct seq_file *s, struct smack_rule *srp, int max) | |||
| 520 | if (strlen(srp->smk_subject) >= max || strlen(srp->smk_object) >= max) | 518 | if (strlen(srp->smk_subject) >= max || strlen(srp->smk_object) >= max) |
| 521 | return; | 519 | return; |
| 522 | 520 | ||
| 521 | if (srp->smk_access == 0) | ||
| 522 | return; | ||
| 523 | |||
| 523 | seq_printf(s, "%s %s", srp->smk_subject, srp->smk_object); | 524 | seq_printf(s, "%s %s", srp->smk_subject, srp->smk_object); |
| 524 | 525 | ||
| 525 | seq_putc(s, ' '); | 526 | seq_putc(s, ' '); |
| @@ -534,8 +535,6 @@ static void smk_rule_show(struct seq_file *s, struct smack_rule *srp, int max) | |||
| 534 | seq_putc(s, 'a'); | 535 | seq_putc(s, 'a'); |
| 535 | if (srp->smk_access & MAY_TRANSMUTE) | 536 | if (srp->smk_access & MAY_TRANSMUTE) |
| 536 | seq_putc(s, 't'); | 537 | seq_putc(s, 't'); |
| 537 | if (srp->smk_access == 0) | ||
| 538 | seq_putc(s, '-'); | ||
| 539 | 538 | ||
| 540 | seq_putc(s, '\n'); | 539 | seq_putc(s, '\n'); |
| 541 | } | 540 | } |
| @@ -595,13 +594,12 @@ static int smk_open_load(struct inode *inode, struct file *file) | |||
| 595 | static ssize_t smk_write_load(struct file *file, const char __user *buf, | 594 | static ssize_t smk_write_load(struct file *file, const char __user *buf, |
| 596 | size_t count, loff_t *ppos) | 595 | size_t count, loff_t *ppos) |
| 597 | { | 596 | { |
| 598 | |||
| 599 | /* | 597 | /* |
| 600 | * Must have privilege. | 598 | * Must have privilege. |
| 601 | * No partial writes. | 599 | * No partial writes. |
| 602 | * Enough data must be present. | 600 | * Enough data must be present. |
| 603 | */ | 601 | */ |
| 604 | if (!capable(CAP_MAC_ADMIN)) | 602 | if (!smack_privileged(CAP_MAC_ADMIN)) |
| 605 | return -EPERM; | 603 | return -EPERM; |
| 606 | 604 | ||
| 607 | return smk_write_rules_list(file, buf, count, ppos, NULL, NULL, | 605 | return smk_write_rules_list(file, buf, count, ppos, NULL, NULL, |
| @@ -787,7 +785,7 @@ static ssize_t smk_set_cipso(struct file *file, const char __user *buf, | |||
| 787 | * No partial writes. | 785 | * No partial writes. |
| 788 | * Enough data must be present. | 786 | * Enough data must be present. |
| 789 | */ | 787 | */ |
| 790 | if (!capable(CAP_MAC_ADMIN)) | 788 | if (!smack_privileged(CAP_MAC_ADMIN)) |
| 791 | return -EPERM; | 789 | return -EPERM; |
| 792 | if (*ppos != 0) | 790 | if (*ppos != 0) |
| 793 | return -EINVAL; | 791 | return -EINVAL; |
| @@ -1090,7 +1088,7 @@ static ssize_t smk_write_netlbladdr(struct file *file, const char __user *buf, | |||
| 1090 | * "<addr/mask, as a.b.c.d/e><space><label>" | 1088 | * "<addr/mask, as a.b.c.d/e><space><label>" |
| 1091 | * "<addr, as a.b.c.d><space><label>" | 1089 | * "<addr, as a.b.c.d><space><label>" |
| 1092 | */ | 1090 | */ |
| 1093 | if (!capable(CAP_MAC_ADMIN)) | 1091 | if (!smack_privileged(CAP_MAC_ADMIN)) |
| 1094 | return -EPERM; | 1092 | return -EPERM; |
| 1095 | if (*ppos != 0) | 1093 | if (*ppos != 0) |
| 1096 | return -EINVAL; | 1094 | return -EINVAL; |
| @@ -1267,7 +1265,7 @@ static ssize_t smk_write_doi(struct file *file, const char __user *buf, | |||
| 1267 | char temp[80]; | 1265 | char temp[80]; |
| 1268 | int i; | 1266 | int i; |
| 1269 | 1267 | ||
| 1270 | if (!capable(CAP_MAC_ADMIN)) | 1268 | if (!smack_privileged(CAP_MAC_ADMIN)) |
| 1271 | return -EPERM; | 1269 | return -EPERM; |
| 1272 | 1270 | ||
| 1273 | if (count >= sizeof(temp) || count == 0) | 1271 | if (count >= sizeof(temp) || count == 0) |
| @@ -1334,7 +1332,7 @@ static ssize_t smk_write_direct(struct file *file, const char __user *buf, | |||
| 1334 | char temp[80]; | 1332 | char temp[80]; |
| 1335 | int i; | 1333 | int i; |
| 1336 | 1334 | ||
| 1337 | if (!capable(CAP_MAC_ADMIN)) | 1335 | if (!smack_privileged(CAP_MAC_ADMIN)) |
| 1338 | return -EPERM; | 1336 | return -EPERM; |
| 1339 | 1337 | ||
| 1340 | if (count >= sizeof(temp) || count == 0) | 1338 | if (count >= sizeof(temp) || count == 0) |
| @@ -1412,7 +1410,7 @@ static ssize_t smk_write_mapped(struct file *file, const char __user *buf, | |||
| 1412 | char temp[80]; | 1410 | char temp[80]; |
| 1413 | int i; | 1411 | int i; |
| 1414 | 1412 | ||
| 1415 | if (!capable(CAP_MAC_ADMIN)) | 1413 | if (!smack_privileged(CAP_MAC_ADMIN)) |
| 1416 | return -EPERM; | 1414 | return -EPERM; |
| 1417 | 1415 | ||
| 1418 | if (count >= sizeof(temp) || count == 0) | 1416 | if (count >= sizeof(temp) || count == 0) |
| @@ -1503,7 +1501,7 @@ static ssize_t smk_write_ambient(struct file *file, const char __user *buf, | |||
| 1503 | char *data; | 1501 | char *data; |
| 1504 | int rc = count; | 1502 | int rc = count; |
| 1505 | 1503 | ||
| 1506 | if (!capable(CAP_MAC_ADMIN)) | 1504 | if (!smack_privileged(CAP_MAC_ADMIN)) |
| 1507 | return -EPERM; | 1505 | return -EPERM; |
| 1508 | 1506 | ||
| 1509 | data = kzalloc(count + 1, GFP_KERNEL); | 1507 | data = kzalloc(count + 1, GFP_KERNEL); |
| @@ -1586,7 +1584,7 @@ static ssize_t smk_write_onlycap(struct file *file, const char __user *buf, | |||
| 1586 | char *sp = smk_of_task(current->cred->security); | 1584 | char *sp = smk_of_task(current->cred->security); |
| 1587 | int rc = count; | 1585 | int rc = count; |
| 1588 | 1586 | ||
| 1589 | if (!capable(CAP_MAC_ADMIN)) | 1587 | if (!smack_privileged(CAP_MAC_ADMIN)) |
| 1590 | return -EPERM; | 1588 | return -EPERM; |
| 1591 | 1589 | ||
| 1592 | /* | 1590 | /* |
| @@ -1664,7 +1662,7 @@ static ssize_t smk_write_logging(struct file *file, const char __user *buf, | |||
| 1664 | char temp[32]; | 1662 | char temp[32]; |
| 1665 | int i; | 1663 | int i; |
| 1666 | 1664 | ||
| 1667 | if (!capable(CAP_MAC_ADMIN)) | 1665 | if (!smack_privileged(CAP_MAC_ADMIN)) |
| 1668 | return -EPERM; | 1666 | return -EPERM; |
| 1669 | 1667 | ||
| 1670 | if (count >= sizeof(temp) || count == 0) | 1668 | if (count >= sizeof(temp) || count == 0) |
| @@ -1885,7 +1883,7 @@ static ssize_t smk_write_load2(struct file *file, const char __user *buf, | |||
| 1885 | /* | 1883 | /* |
| 1886 | * Must have privilege. | 1884 | * Must have privilege. |
| 1887 | */ | 1885 | */ |
| 1888 | if (!capable(CAP_MAC_ADMIN)) | 1886 | if (!smack_privileged(CAP_MAC_ADMIN)) |
| 1889 | return -EPERM; | 1887 | return -EPERM; |
| 1890 | 1888 | ||
| 1891 | return smk_write_rules_list(file, buf, count, ppos, NULL, NULL, | 1889 | return smk_write_rules_list(file, buf, count, ppos, NULL, NULL, |
| @@ -2051,7 +2049,6 @@ static int smk_fill_super(struct super_block *sb, void *data, int silent) | |||
| 2051 | } | 2049 | } |
| 2052 | 2050 | ||
| 2053 | root_inode = sb->s_root->d_inode; | 2051 | root_inode = sb->s_root->d_inode; |
| 2054 | root_inode->i_security = new_inode_smack(smack_known_floor.smk_known); | ||
| 2055 | 2052 | ||
| 2056 | return 0; | 2053 | return 0; |
| 2057 | } | 2054 | } |
