diff options
author | Vasily Averin <vvs@virtuozzo.com> | 2015-06-25 18:01:44 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-06-25 20:00:39 -0400 |
commit | d194e5d666225b04c7754471df0948f645b6ab3a (patch) | |
tree | 07b78850800078b3b4f147939309d29642773266 /kernel/printk | |
parent | e2f15f9a79201ddd596727b84a85c419ee57ad5c (diff) |
security_syslog() should be called once only
The final version of commit 637241a900cb ("kmsg: honor dmesg_restrict
sysctl on /dev/kmsg") lost few hooks, as result security_syslog() are
processed incorrectly:
- open of /dev/kmsg checks syslog access permissions by using
check_syslog_permissions() where security_syslog() is not called if
dmesg_restrict is set.
- syslog syscall and /proc/kmsg calls do_syslog() where security_syslog
can be executed twice (inside check_syslog_permissions() and then
directly in do_syslog())
With this patch security_syslog() is called once only in all
syslog-related operations regardless of dmesg_restrict value.
Fixes: 637241a900cb ("kmsg: honor dmesg_restrict sysctl on /dev/kmsg")
Signed-off-by: Vasily Averin <vvs@virtuozzo.com>
Cc: Kees Cook <keescook@chromium.org>
Cc: Josh Boyer <jwboyer@redhat.com>
Cc: Eric Paris <eparis@redhat.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'kernel/printk')
-rw-r--r-- | kernel/printk/printk.c | 11 |
1 files changed, 4 insertions, 7 deletions
diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c index ae980dc3ac1e..45fa8c88ac47 100644 --- a/kernel/printk/printk.c +++ b/kernel/printk/printk.c | |||
@@ -496,11 +496,11 @@ int check_syslog_permissions(int type, bool from_file) | |||
496 | * already done the capabilities checks at open time. | 496 | * already done the capabilities checks at open time. |
497 | */ | 497 | */ |
498 | if (from_file && type != SYSLOG_ACTION_OPEN) | 498 | if (from_file && type != SYSLOG_ACTION_OPEN) |
499 | return 0; | 499 | goto ok; |
500 | 500 | ||
501 | if (syslog_action_restricted(type)) { | 501 | if (syslog_action_restricted(type)) { |
502 | if (capable(CAP_SYSLOG)) | 502 | if (capable(CAP_SYSLOG)) |
503 | return 0; | 503 | goto ok; |
504 | /* | 504 | /* |
505 | * For historical reasons, accept CAP_SYS_ADMIN too, with | 505 | * For historical reasons, accept CAP_SYS_ADMIN too, with |
506 | * a warning. | 506 | * a warning. |
@@ -510,10 +510,11 @@ int check_syslog_permissions(int type, bool from_file) | |||
510 | "CAP_SYS_ADMIN but no CAP_SYSLOG " | 510 | "CAP_SYS_ADMIN but no CAP_SYSLOG " |
511 | "(deprecated).\n", | 511 | "(deprecated).\n", |
512 | current->comm, task_pid_nr(current)); | 512 | current->comm, task_pid_nr(current)); |
513 | return 0; | 513 | goto ok; |
514 | } | 514 | } |
515 | return -EPERM; | 515 | return -EPERM; |
516 | } | 516 | } |
517 | ok: | ||
517 | return security_syslog(type); | 518 | return security_syslog(type); |
518 | } | 519 | } |
519 | 520 | ||
@@ -1299,10 +1300,6 @@ int do_syslog(int type, char __user *buf, int len, bool from_file) | |||
1299 | if (error) | 1300 | if (error) |
1300 | goto out; | 1301 | goto out; |
1301 | 1302 | ||
1302 | error = security_syslog(type); | ||
1303 | if (error) | ||
1304 | return error; | ||
1305 | |||
1306 | switch (type) { | 1303 | switch (type) { |
1307 | case SYSLOG_ACTION_CLOSE: /* Close log */ | 1304 | case SYSLOG_ACTION_CLOSE: /* Close log */ |
1308 | break; | 1305 | break; |