diff options
| -rw-r--r-- | kernel/printk/printk.c | 69 |
1 files changed, 32 insertions, 37 deletions
diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c index 97bda7b0655b..512f7c2baedd 100644 --- a/kernel/printk/printk.c +++ b/kernel/printk/printk.c | |||
| @@ -1434,7 +1434,7 @@ int do_syslog(int type, char __user *buf, int len, int source) | |||
| 1434 | 1434 | ||
| 1435 | error = check_syslog_permissions(type, source); | 1435 | error = check_syslog_permissions(type, source); |
| 1436 | if (error) | 1436 | if (error) |
| 1437 | goto out; | 1437 | return error; |
| 1438 | 1438 | ||
| 1439 | switch (type) { | 1439 | switch (type) { |
| 1440 | case SYSLOG_ACTION_CLOSE: /* Close log */ | 1440 | case SYSLOG_ACTION_CLOSE: /* Close log */ |
| @@ -1442,20 +1442,16 @@ int do_syslog(int type, char __user *buf, int len, int source) | |||
| 1442 | case SYSLOG_ACTION_OPEN: /* Open log */ | 1442 | case SYSLOG_ACTION_OPEN: /* Open log */ |
| 1443 | break; | 1443 | break; |
| 1444 | case SYSLOG_ACTION_READ: /* Read from log */ | 1444 | case SYSLOG_ACTION_READ: /* Read from log */ |
| 1445 | error = -EINVAL; | ||
| 1446 | if (!buf || len < 0) | 1445 | if (!buf || len < 0) |
| 1447 | goto out; | 1446 | return -EINVAL; |
| 1448 | error = 0; | ||
| 1449 | if (!len) | 1447 | if (!len) |
| 1450 | goto out; | 1448 | return 0; |
| 1451 | if (!access_ok(VERIFY_WRITE, buf, len)) { | 1449 | if (!access_ok(VERIFY_WRITE, buf, len)) |
| 1452 | error = -EFAULT; | 1450 | return -EFAULT; |
| 1453 | goto out; | ||
| 1454 | } | ||
| 1455 | error = wait_event_interruptible(log_wait, | 1451 | error = wait_event_interruptible(log_wait, |
| 1456 | syslog_seq != log_next_seq); | 1452 | syslog_seq != log_next_seq); |
| 1457 | if (error) | 1453 | if (error) |
| 1458 | goto out; | 1454 | return error; |
| 1459 | error = syslog_print(buf, len); | 1455 | error = syslog_print(buf, len); |
| 1460 | break; | 1456 | break; |
| 1461 | /* Read/clear last kernel messages */ | 1457 | /* Read/clear last kernel messages */ |
| @@ -1464,16 +1460,12 @@ int do_syslog(int type, char __user *buf, int len, int source) | |||
| 1464 | /* FALL THRU */ | 1460 | /* FALL THRU */ |
| 1465 | /* Read last kernel messages */ | 1461 | /* Read last kernel messages */ |
| 1466 | case SYSLOG_ACTION_READ_ALL: | 1462 | case SYSLOG_ACTION_READ_ALL: |
| 1467 | error = -EINVAL; | ||
| 1468 | if (!buf || len < 0) | 1463 | if (!buf || len < 0) |
| 1469 | goto out; | 1464 | return -EINVAL; |
| 1470 | error = 0; | ||
| 1471 | if (!len) | 1465 | if (!len) |
| 1472 | goto out; | 1466 | return 0; |
| 1473 | if (!access_ok(VERIFY_WRITE, buf, len)) { | 1467 | if (!access_ok(VERIFY_WRITE, buf, len)) |
| 1474 | error = -EFAULT; | 1468 | return -EFAULT; |
| 1475 | goto out; | ||
| 1476 | } | ||
| 1477 | error = syslog_print_all(buf, len, clear); | 1469 | error = syslog_print_all(buf, len, clear); |
| 1478 | break; | 1470 | break; |
| 1479 | /* Clear ring buffer */ | 1471 | /* Clear ring buffer */ |
| @@ -1495,15 +1487,13 @@ int do_syslog(int type, char __user *buf, int len, int source) | |||
| 1495 | break; | 1487 | break; |
| 1496 | /* Set level of messages printed to console */ | 1488 | /* Set level of messages printed to console */ |
| 1497 | case SYSLOG_ACTION_CONSOLE_LEVEL: | 1489 | case SYSLOG_ACTION_CONSOLE_LEVEL: |
| 1498 | error = -EINVAL; | ||
| 1499 | if (len < 1 || len > 8) | 1490 | if (len < 1 || len > 8) |
| 1500 | goto out; | 1491 | return -EINVAL; |
| 1501 | if (len < minimum_console_loglevel) | 1492 | if (len < minimum_console_loglevel) |
| 1502 | len = minimum_console_loglevel; | 1493 | len = minimum_console_loglevel; |
| 1503 | console_loglevel = len; | 1494 | console_loglevel = len; |
| 1504 | /* Implicitly re-enable logging to console */ | 1495 | /* Implicitly re-enable logging to console */ |
| 1505 | saved_console_loglevel = LOGLEVEL_DEFAULT; | 1496 | saved_console_loglevel = LOGLEVEL_DEFAULT; |
| 1506 | error = 0; | ||
| 1507 | break; | 1497 | break; |
| 1508 | /* Number of chars in the log buffer */ | 1498 | /* Number of chars in the log buffer */ |
| 1509 | case SYSLOG_ACTION_SIZE_UNREAD: | 1499 | case SYSLOG_ACTION_SIZE_UNREAD: |
| @@ -1525,7 +1515,6 @@ int do_syslog(int type, char __user *buf, int len, int source) | |||
| 1525 | u64 seq = syslog_seq; | 1515 | u64 seq = syslog_seq; |
| 1526 | u32 idx = syslog_idx; | 1516 | u32 idx = syslog_idx; |
| 1527 | 1517 | ||
| 1528 | error = 0; | ||
| 1529 | while (seq < log_next_seq) { | 1518 | while (seq < log_next_seq) { |
| 1530 | struct printk_log *msg = log_from_idx(idx); | 1519 | struct printk_log *msg = log_from_idx(idx); |
| 1531 | 1520 | ||
| @@ -1545,7 +1534,7 @@ int do_syslog(int type, char __user *buf, int len, int source) | |||
| 1545 | error = -EINVAL; | 1534 | error = -EINVAL; |
| 1546 | break; | 1535 | break; |
| 1547 | } | 1536 | } |
| 1548 | out: | 1537 | |
| 1549 | return error; | 1538 | return error; |
| 1550 | } | 1539 | } |
| 1551 | 1540 | ||
| @@ -1697,10 +1686,10 @@ asmlinkage int vprintk_emit(int facility, int level, | |||
| 1697 | { | 1686 | { |
| 1698 | static char textbuf[LOG_LINE_MAX]; | 1687 | static char textbuf[LOG_LINE_MAX]; |
| 1699 | char *text = textbuf; | 1688 | char *text = textbuf; |
| 1700 | size_t text_len = 0; | 1689 | size_t text_len; |
| 1701 | enum log_flags lflags = 0; | 1690 | enum log_flags lflags = 0; |
| 1702 | unsigned long flags; | 1691 | unsigned long flags; |
| 1703 | int printed_len = 0; | 1692 | int printed_len; |
| 1704 | bool in_sched = false; | 1693 | bool in_sched = false; |
| 1705 | 1694 | ||
| 1706 | if (level == LOGLEVEL_SCHED) { | 1695 | if (level == LOGLEVEL_SCHED) { |
| @@ -1753,7 +1742,7 @@ asmlinkage int vprintk_emit(int facility, int level, | |||
| 1753 | if (dict) | 1742 | if (dict) |
| 1754 | lflags |= LOG_PREFIX|LOG_NEWLINE; | 1743 | lflags |= LOG_PREFIX|LOG_NEWLINE; |
| 1755 | 1744 | ||
| 1756 | printed_len += log_output(facility, level, lflags, dict, dictlen, text, text_len); | 1745 | printed_len = log_output(facility, level, lflags, dict, dictlen, text, text_len); |
| 1757 | 1746 | ||
| 1758 | logbuf_unlock_irqrestore(flags); | 1747 | logbuf_unlock_irqrestore(flags); |
| 1759 | 1748 | ||
| @@ -2649,9 +2638,8 @@ void __init console_init(void) | |||
| 2649 | * makes it difficult to diagnose problems that occur during this time. | 2638 | * makes it difficult to diagnose problems that occur during this time. |
| 2650 | * | 2639 | * |
| 2651 | * To mitigate this problem somewhat, only unregister consoles whose memory | 2640 | * To mitigate this problem somewhat, only unregister consoles whose memory |
| 2652 | * intersects with the init section. Note that code exists elsewhere to get | 2641 | * intersects with the init section. Note that all other boot consoles will |
| 2653 | * rid of the boot console as soon as the proper console shows up, so there | 2642 | * get unregistred when the real preferred console is registered. |
| 2654 | * won't be side-effects from postponing the removal. | ||
| 2655 | */ | 2643 | */ |
| 2656 | static int __init printk_late_init(void) | 2644 | static int __init printk_late_init(void) |
| 2657 | { | 2645 | { |
| @@ -2659,16 +2647,23 @@ static int __init printk_late_init(void) | |||
| 2659 | int ret; | 2647 | int ret; |
| 2660 | 2648 | ||
| 2661 | for_each_console(con) { | 2649 | for_each_console(con) { |
| 2662 | if (!keep_bootcon && con->flags & CON_BOOT) { | 2650 | if (!(con->flags & CON_BOOT)) |
| 2651 | continue; | ||
| 2652 | |||
| 2653 | /* Check addresses that might be used for enabled consoles. */ | ||
| 2654 | if (init_section_intersects(con, sizeof(*con)) || | ||
| 2655 | init_section_contains(con->write, 0) || | ||
| 2656 | init_section_contains(con->read, 0) || | ||
| 2657 | init_section_contains(con->device, 0) || | ||
| 2658 | init_section_contains(con->unblank, 0) || | ||
| 2659 | init_section_contains(con->data, 0)) { | ||
| 2663 | /* | 2660 | /* |
| 2664 | * Make sure to unregister boot consoles whose data | 2661 | * Please, consider moving the reported consoles out |
| 2665 | * resides in the init section before the init section | 2662 | * of the init section. |
| 2666 | * is discarded. Boot consoles whose data will stick | ||
| 2667 | * around will automatically be unregistered when the | ||
| 2668 | * proper console replaces them. | ||
| 2669 | */ | 2663 | */ |
| 2670 | if (init_section_intersects(con, sizeof(*con))) | 2664 | pr_warn("bootconsole [%s%d] uses init memory and must be disabled even before the real one is ready\n", |
| 2671 | unregister_console(con); | 2665 | con->name, con->index); |
| 2666 | unregister_console(con); | ||
| 2672 | } | 2667 | } |
| 2673 | } | 2668 | } |
| 2674 | ret = cpuhp_setup_state_nocalls(CPUHP_PRINTK_DEAD, "printk:dead", NULL, | 2669 | ret = cpuhp_setup_state_nocalls(CPUHP_PRINTK_DEAD, "printk:dead", NULL, |
