diff options
| -rw-r--r-- | kernel/printk.c | 54 |
1 files changed, 35 insertions, 19 deletions
diff --git a/kernel/printk.c b/kernel/printk.c index 2ddbdc73aade..36231525e22f 100644 --- a/kernel/printk.c +++ b/kernel/printk.c | |||
| @@ -262,25 +262,47 @@ int dmesg_restrict = 1; | |||
| 262 | int dmesg_restrict; | 262 | int dmesg_restrict; |
| 263 | #endif | 263 | #endif |
| 264 | 264 | ||
| 265 | static int syslog_action_restricted(int type) | ||
| 266 | { | ||
| 267 | if (dmesg_restrict) | ||
| 268 | return 1; | ||
| 269 | /* Unless restricted, we allow "read all" and "get buffer size" for everybody */ | ||
| 270 | return type != SYSLOG_ACTION_READ_ALL && type != SYSLOG_ACTION_SIZE_BUFFER; | ||
| 271 | } | ||
| 272 | |||
| 273 | static int check_syslog_permissions(int type, bool from_file) | ||
| 274 | { | ||
| 275 | /* | ||
| 276 | * If this is from /proc/kmsg and we've already opened it, then we've | ||
| 277 | * already done the capabilities checks at open time. | ||
| 278 | */ | ||
| 279 | if (from_file && type != SYSLOG_ACTION_OPEN) | ||
| 280 | return 0; | ||
| 281 | |||
| 282 | if (syslog_action_restricted(type)) { | ||
| 283 | if (capable(CAP_SYSLOG)) | ||
| 284 | return 0; | ||
| 285 | /* For historical reasons, accept CAP_SYS_ADMIN too, with a warning */ | ||
| 286 | if (capable(CAP_SYS_ADMIN)) { | ||
| 287 | WARN_ONCE(1, "Attempt to access syslog with CAP_SYS_ADMIN " | ||
| 288 | "but no CAP_SYSLOG (deprecated).\n"); | ||
| 289 | return 0; | ||
| 290 | } | ||
| 291 | return -EPERM; | ||
| 292 | } | ||
| 293 | return 0; | ||
| 294 | } | ||
| 295 | |||
| 265 | int do_syslog(int type, char __user *buf, int len, bool from_file) | 296 | int do_syslog(int type, char __user *buf, int len, bool from_file) |
| 266 | { | 297 | { |
| 267 | unsigned i, j, limit, count; | 298 | unsigned i, j, limit, count; |
| 268 | int do_clear = 0; | 299 | int do_clear = 0; |
| 269 | char c; | 300 | char c; |
| 270 | int error = 0; | 301 | int error; |
| 271 | 302 | ||
| 272 | /* | 303 | error = check_syslog_permissions(type, from_file); |
| 273 | * If this is from /proc/kmsg we only do the capabilities checks | 304 | if (error) |
| 274 | * at open time. | 305 | goto out; |
| 275 | */ | ||
| 276 | if (type == SYSLOG_ACTION_OPEN || !from_file) { | ||
| 277 | if (dmesg_restrict && !capable(CAP_SYSLOG)) | ||
| 278 | goto warn; /* switch to return -EPERM after 2.6.39 */ | ||
| 279 | if ((type != SYSLOG_ACTION_READ_ALL && | ||
| 280 | type != SYSLOG_ACTION_SIZE_BUFFER) && | ||
| 281 | !capable(CAP_SYSLOG)) | ||
| 282 | goto warn; /* switch to return -EPERM after 2.6.39 */ | ||
| 283 | } | ||
| 284 | 306 | ||
| 285 | error = security_syslog(type); | 307 | error = security_syslog(type); |
| 286 | if (error) | 308 | if (error) |
| @@ -423,12 +445,6 @@ int do_syslog(int type, char __user *buf, int len, bool from_file) | |||
| 423 | } | 445 | } |
| 424 | out: | 446 | out: |
| 425 | return error; | 447 | return error; |
| 426 | warn: | ||
| 427 | /* remove after 2.6.39 */ | ||
| 428 | if (capable(CAP_SYS_ADMIN)) | ||
| 429 | WARN_ONCE(1, "Attempt to access syslog with CAP_SYS_ADMIN " | ||
| 430 | "but no CAP_SYSLOG (deprecated and denied).\n"); | ||
| 431 | return -EPERM; | ||
| 432 | } | 448 | } |
| 433 | 449 | ||
| 434 | SYSCALL_DEFINE3(syslog, int, type, char __user *, buf, int, len) | 450 | SYSCALL_DEFINE3(syslog, int, type, char __user *, buf, int, len) |
