diff options
| -rw-r--r-- | fs/proc/kmsg.c | 10 | ||||
| -rw-r--r-- | include/linux/syslog.h | 23 | ||||
| -rw-r--r-- | kernel/printk.c | 45 | ||||
| -rw-r--r-- | security/commoncap.c | 5 | ||||
| -rw-r--r-- | security/selinux/hooks.c | 21 |
5 files changed, 61 insertions, 43 deletions
diff --git a/fs/proc/kmsg.c b/fs/proc/kmsg.c index 6a3d843a1088..cfe90a48a6e8 100644 --- a/fs/proc/kmsg.c +++ b/fs/proc/kmsg.c | |||
| @@ -21,12 +21,12 @@ extern wait_queue_head_t log_wait; | |||
| 21 | 21 | ||
| 22 | static int kmsg_open(struct inode * inode, struct file * file) | 22 | static int kmsg_open(struct inode * inode, struct file * file) |
| 23 | { | 23 | { |
| 24 | return do_syslog(1, NULL, 0, SYSLOG_FROM_FILE); | 24 | return do_syslog(SYSLOG_ACTION_OPEN, NULL, 0, SYSLOG_FROM_FILE); |
| 25 | } | 25 | } |
| 26 | 26 | ||
| 27 | static int kmsg_release(struct inode * inode, struct file * file) | 27 | static int kmsg_release(struct inode * inode, struct file * file) |
| 28 | { | 28 | { |
| 29 | (void) do_syslog(0, NULL, 0, SYSLOG_FROM_FILE); | 29 | (void) do_syslog(SYSLOG_ACTION_CLOSE, NULL, 0, SYSLOG_FROM_FILE); |
| 30 | return 0; | 30 | return 0; |
| 31 | } | 31 | } |
| 32 | 32 | ||
| @@ -34,15 +34,15 @@ static ssize_t kmsg_read(struct file *file, char __user *buf, | |||
| 34 | size_t count, loff_t *ppos) | 34 | size_t count, loff_t *ppos) |
| 35 | { | 35 | { |
| 36 | if ((file->f_flags & O_NONBLOCK) && | 36 | if ((file->f_flags & O_NONBLOCK) && |
| 37 | !do_syslog(9, NULL, 0, SYSLOG_FROM_FILE)) | 37 | !do_syslog(SYSLOG_ACTION_SIZE_UNREAD, NULL, 0, SYSLOG_FROM_FILE)) |
| 38 | return -EAGAIN; | 38 | return -EAGAIN; |
| 39 | return do_syslog(2, buf, count, SYSLOG_FROM_FILE); | 39 | return do_syslog(SYSLOG_ACTION_READ, buf, count, SYSLOG_FROM_FILE); |
| 40 | } | 40 | } |
| 41 | 41 | ||
| 42 | static unsigned int kmsg_poll(struct file *file, poll_table *wait) | 42 | static unsigned int kmsg_poll(struct file *file, poll_table *wait) |
| 43 | { | 43 | { |
| 44 | poll_wait(file, &log_wait, wait); | 44 | poll_wait(file, &log_wait, wait); |
| 45 | if (do_syslog(9, NULL, 0, SYSLOG_FROM_FILE)) | 45 | if (do_syslog(SYSLOG_ACTION_SIZE_UNREAD, NULL, 0, SYSLOG_FROM_FILE)) |
| 46 | return POLLIN | POLLRDNORM; | 46 | return POLLIN | POLLRDNORM; |
| 47 | return 0; | 47 | return 0; |
| 48 | } | 48 | } |
diff --git a/include/linux/syslog.h b/include/linux/syslog.h index 5f02b1817be1..38911391a139 100644 --- a/include/linux/syslog.h +++ b/include/linux/syslog.h | |||
| @@ -21,6 +21,29 @@ | |||
| 21 | #ifndef _LINUX_SYSLOG_H | 21 | #ifndef _LINUX_SYSLOG_H |
| 22 | #define _LINUX_SYSLOG_H | 22 | #define _LINUX_SYSLOG_H |
| 23 | 23 | ||
| 24 | /* Close the log. Currently a NOP. */ | ||
| 25 | #define SYSLOG_ACTION_CLOSE 0 | ||
| 26 | /* Open the log. Currently a NOP. */ | ||
| 27 | #define SYSLOG_ACTION_OPEN 1 | ||
| 28 | /* Read from the log. */ | ||
| 29 | #define SYSLOG_ACTION_READ 2 | ||
| 30 | /* Read all messages remaining in the ring buffer. */ | ||
| 31 | #define SYSLOG_ACTION_READ_ALL 3 | ||
| 32 | /* Read and clear all messages remaining in the ring buffer */ | ||
| 33 | #define SYSLOG_ACTION_READ_CLEAR 4 | ||
| 34 | /* Clear ring buffer. */ | ||
| 35 | #define SYSLOG_ACTION_CLEAR 5 | ||
| 36 | /* Disable printk's to console */ | ||
| 37 | #define SYSLOG_ACTION_CONSOLE_OFF 6 | ||
| 38 | /* Enable printk's to console */ | ||
| 39 | #define SYSLOG_ACTION_CONSOLE_ON 7 | ||
| 40 | /* Set level of messages printed to console */ | ||
| 41 | #define SYSLOG_ACTION_CONSOLE_LEVEL 8 | ||
| 42 | /* Return number of unread characters in the log buffer */ | ||
| 43 | #define SYSLOG_ACTION_SIZE_UNREAD 9 | ||
| 44 | /* Return size of the log buffer */ | ||
| 45 | #define SYSLOG_ACTION_SIZE_BUFFER 10 | ||
| 46 | |||
| 24 | #define SYSLOG_FROM_CALL 0 | 47 | #define SYSLOG_FROM_CALL 0 |
| 25 | #define SYSLOG_FROM_FILE 1 | 48 | #define SYSLOG_FROM_FILE 1 |
| 26 | 49 | ||
diff --git a/kernel/printk.c b/kernel/printk.c index 809cf9a258a0..3e162d867098 100644 --- a/kernel/printk.c +++ b/kernel/printk.c | |||
| @@ -259,21 +259,6 @@ static inline void boot_delay_msec(void) | |||
| 259 | } | 259 | } |
| 260 | #endif | 260 | #endif |
| 261 | 261 | ||
| 262 | /* | ||
| 263 | * Commands to do_syslog: | ||
| 264 | * | ||
| 265 | * 0 -- Close the log. Currently a NOP. | ||
| 266 | * 1 -- Open the log. Currently a NOP. | ||
| 267 | * 2 -- Read from the log. | ||
| 268 | * 3 -- Read all messages remaining in the ring buffer. | ||
| 269 | * 4 -- Read and clear all messages remaining in the ring buffer | ||
| 270 | * 5 -- Clear ring buffer. | ||
| 271 | * 6 -- Disable printk's to console | ||
| 272 | * 7 -- Enable printk's to console | ||
| 273 | * 8 -- Set level of messages printed to console | ||
| 274 | * 9 -- Return number of unread characters in the log buffer | ||
| 275 | * 10 -- Return size of the log buffer | ||
| 276 | */ | ||
| 277 | int do_syslog(int type, char __user *buf, int len, bool from_file) | 262 | int do_syslog(int type, char __user *buf, int len, bool from_file) |
| 278 | { | 263 | { |
| 279 | unsigned i, j, limit, count; | 264 | unsigned i, j, limit, count; |
| @@ -286,11 +271,11 @@ int do_syslog(int type, char __user *buf, int len, bool from_file) | |||
| 286 | return error; | 271 | return error; |
| 287 | 272 | ||
| 288 | switch (type) { | 273 | switch (type) { |
| 289 | case 0: /* Close log */ | 274 | case SYSLOG_ACTION_CLOSE: /* Close log */ |
| 290 | break; | 275 | break; |
| 291 | case 1: /* Open log */ | 276 | case SYSLOG_ACTION_OPEN: /* Open log */ |
| 292 | break; | 277 | break; |
| 293 | case 2: /* Read from log */ | 278 | case SYSLOG_ACTION_READ: /* Read from log */ |
| 294 | error = -EINVAL; | 279 | error = -EINVAL; |
| 295 | if (!buf || len < 0) | 280 | if (!buf || len < 0) |
| 296 | goto out; | 281 | goto out; |
| @@ -321,10 +306,12 @@ int do_syslog(int type, char __user *buf, int len, bool from_file) | |||
| 321 | if (!error) | 306 | if (!error) |
| 322 | error = i; | 307 | error = i; |
| 323 | break; | 308 | break; |
| 324 | case 4: /* Read/clear last kernel messages */ | 309 | /* Read/clear last kernel messages */ |
| 310 | case SYSLOG_ACTION_READ_CLEAR: | ||
| 325 | do_clear = 1; | 311 | do_clear = 1; |
| 326 | /* FALL THRU */ | 312 | /* FALL THRU */ |
| 327 | case 3: /* Read last kernel messages */ | 313 | /* Read last kernel messages */ |
| 314 | case SYSLOG_ACTION_READ_ALL: | ||
| 328 | error = -EINVAL; | 315 | error = -EINVAL; |
| 329 | if (!buf || len < 0) | 316 | if (!buf || len < 0) |
| 330 | goto out; | 317 | goto out; |
| @@ -377,21 +364,25 @@ int do_syslog(int type, char __user *buf, int len, bool from_file) | |||
| 377 | } | 364 | } |
| 378 | } | 365 | } |
| 379 | break; | 366 | break; |
| 380 | case 5: /* Clear ring buffer */ | 367 | /* Clear ring buffer */ |
| 368 | case SYSLOG_ACTION_CLEAR: | ||
| 381 | logged_chars = 0; | 369 | logged_chars = 0; |
| 382 | break; | 370 | break; |
| 383 | case 6: /* Disable logging to console */ | 371 | /* Disable logging to console */ |
| 372 | case SYSLOG_ACTION_CONSOLE_OFF: | ||
| 384 | if (saved_console_loglevel == -1) | 373 | if (saved_console_loglevel == -1) |
| 385 | saved_console_loglevel = console_loglevel; | 374 | saved_console_loglevel = console_loglevel; |
| 386 | console_loglevel = minimum_console_loglevel; | 375 | console_loglevel = minimum_console_loglevel; |
| 387 | break; | 376 | break; |
| 388 | case 7: /* Enable logging to console */ | 377 | /* Enable logging to console */ |
| 378 | case SYSLOG_ACTION_CONSOLE_ON: | ||
| 389 | if (saved_console_loglevel != -1) { | 379 | if (saved_console_loglevel != -1) { |
| 390 | console_loglevel = saved_console_loglevel; | 380 | console_loglevel = saved_console_loglevel; |
| 391 | saved_console_loglevel = -1; | 381 | saved_console_loglevel = -1; |
| 392 | } | 382 | } |
| 393 | break; | 383 | break; |
| 394 | case 8: /* Set level of messages printed to console */ | 384 | /* Set level of messages printed to console */ |
| 385 | case SYSLOG_ACTION_CONSOLE_LEVEL: | ||
| 395 | error = -EINVAL; | 386 | error = -EINVAL; |
| 396 | if (len < 1 || len > 8) | 387 | if (len < 1 || len > 8) |
| 397 | goto out; | 388 | goto out; |
| @@ -402,10 +393,12 @@ int do_syslog(int type, char __user *buf, int len, bool from_file) | |||
| 402 | saved_console_loglevel = -1; | 393 | saved_console_loglevel = -1; |
| 403 | error = 0; | 394 | error = 0; |
| 404 | break; | 395 | break; |
| 405 | case 9: /* Number of chars in the log buffer */ | 396 | /* Number of chars in the log buffer */ |
| 397 | case SYSLOG_ACTION_SIZE_UNREAD: | ||
| 406 | error = log_end - log_start; | 398 | error = log_end - log_start; |
| 407 | break; | 399 | break; |
| 408 | case 10: /* Size of the log buffer */ | 400 | /* Size of the log buffer */ |
| 401 | case SYSLOG_ACTION_SIZE_BUFFER: | ||
| 409 | error = log_buf_len; | 402 | error = log_buf_len; |
| 410 | break; | 403 | break; |
| 411 | default: | 404 | default: |
diff --git a/security/commoncap.c b/security/commoncap.c index 677fad9d5cba..cf01b2eebb60 100644 --- a/security/commoncap.c +++ b/security/commoncap.c | |||
| @@ -897,9 +897,10 @@ error: | |||
| 897 | int cap_syslog(int type, bool from_file) | 897 | int cap_syslog(int type, bool from_file) |
| 898 | { | 898 | { |
| 899 | /* /proc/kmsg can open be opened by CAP_SYS_ADMIN */ | 899 | /* /proc/kmsg can open be opened by CAP_SYS_ADMIN */ |
| 900 | if (type != 1 && from_file) | 900 | if (type != SYSLOG_ACTION_OPEN && from_file) |
| 901 | return 0; | 901 | return 0; |
| 902 | if ((type != 3 && type != 10) && !capable(CAP_SYS_ADMIN)) | 902 | if ((type != SYSLOG_ACTION_READ_ALL && |
| 903 | type != SYSLOG_ACTION_SIZE_BUFFER) && !capable(CAP_SYS_ADMIN)) | ||
| 903 | return -EPERM; | 904 | return -EPERM; |
| 904 | return 0; | 905 | return 0; |
| 905 | } | 906 | } |
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index a4862a0730fa..6b36ce2eef2e 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c | |||
| @@ -2059,20 +2059,21 @@ static int selinux_syslog(int type, bool from_file) | |||
| 2059 | return rc; | 2059 | return rc; |
| 2060 | 2060 | ||
| 2061 | switch (type) { | 2061 | switch (type) { |
| 2062 | case 3: /* Read last kernel messages */ | 2062 | case SYSLOG_ACTION_READ_ALL: /* Read last kernel messages */ |
| 2063 | case 10: /* Return size of the log buffer */ | 2063 | case SYSLOG_ACTION_SIZE_BUFFER: /* Return size of the log buffer */ |
| 2064 | rc = task_has_system(current, SYSTEM__SYSLOG_READ); | 2064 | rc = task_has_system(current, SYSTEM__SYSLOG_READ); |
| 2065 | break; | 2065 | break; |
| 2066 | case 6: /* Disable logging to console */ | 2066 | case SYSLOG_ACTION_CONSOLE_OFF: /* Disable logging to console */ |
| 2067 | case 7: /* Enable logging to console */ | 2067 | case SYSLOG_ACTION_CONSOLE_ON: /* Enable logging to console */ |
| 2068 | case 8: /* Set level of messages printed to console */ | 2068 | /* Set level of messages printed to console */ |
| 2069 | case SYSLOG_ACTION_CONSOLE_LEVEL: | ||
| 2069 | rc = task_has_system(current, SYSTEM__SYSLOG_CONSOLE); | 2070 | rc = task_has_system(current, SYSTEM__SYSLOG_CONSOLE); |
| 2070 | break; | 2071 | break; |
| 2071 | case 0: /* Close log */ | 2072 | case SYSLOG_ACTION_CLOSE: /* Close log */ |
| 2072 | case 1: /* Open log */ | 2073 | case SYSLOG_ACTION_OPEN: /* Open log */ |
| 2073 | case 2: /* Read from log */ | 2074 | case SYSLOG_ACTION_READ: /* Read from log */ |
| 2074 | case 4: /* Read/clear last kernel messages */ | 2075 | case SYSLOG_ACTION_READ_CLEAR: /* Read/clear last kernel messages */ |
| 2075 | case 5: /* Clear ring buffer */ | 2076 | case SYSLOG_ACTION_CLEAR: /* Clear ring buffer */ |
| 2076 | default: | 2077 | default: |
| 2077 | rc = task_has_system(current, SYSTEM__SYSLOG_MOD); | 2078 | rc = task_has_system(current, SYSTEM__SYSLOG_MOD); |
| 2078 | break; | 2079 | break; |
