@@ -390,8 +390,12 @@ DEFINE_RAW_SPINLOCK(logbuf_lock);
390
390
printk_safe_exit_irqrestore(flags); \
391
391
} while (0)
392
392
393
+ /* syslog_lock protects syslog_* variables and write access to clear_seq. */
394
+ static DEFINE_RAW_SPINLOCK (syslog_lock );
395
+
393
396
#ifdef CONFIG_PRINTK
394
397
DECLARE_WAIT_QUEUE_HEAD (log_wait );
398
+ /* All 3 protected by @syslog_lock. */
395
399
/* the next printk record to read by syslog(READ) or /proc/kmsg */
396
400
static u64 syslog_seq ;
397
401
static size_t syslog_partial ;
@@ -410,7 +414,7 @@ struct latched_seq {
410
414
/*
411
415
* The next printk record to read after the last 'clear' command. There are
412
416
* two copies (updated with seqcount_latch) so that reads can locklessly
413
- * access a valid value. Writers are synchronized by @logbuf_lock .
417
+ * access a valid value. Writers are synchronized by @syslog_lock .
414
418
*/
415
419
static struct latched_seq clear_seq = {
416
420
.latch = SEQCNT_LATCH_ZERO (clear_seq .latch ),
@@ -470,7 +474,7 @@ bool printk_percpu_data_ready(void)
470
474
return __printk_percpu_data_ready ;
471
475
}
472
476
473
- /* Must be called under logbuf_lock . */
477
+ /* Must be called under syslog_lock . */
474
478
static void latched_seq_write (struct latched_seq * ls , u64 val )
475
479
{
476
480
raw_write_seqcount_latch (& ls -> latch );
@@ -1529,7 +1533,9 @@ static int syslog_print(char __user *buf, int size)
1529
1533
size_t skip ;
1530
1534
1531
1535
logbuf_lock_irq ();
1536
+ raw_spin_lock (& syslog_lock );
1532
1537
if (!prb_read_valid (prb , syslog_seq , & r )) {
1538
+ raw_spin_unlock (& syslog_lock );
1533
1539
logbuf_unlock_irq ();
1534
1540
break ;
1535
1541
}
@@ -1559,6 +1565,7 @@ static int syslog_print(char __user *buf, int size)
1559
1565
syslog_partial += n ;
1560
1566
} else
1561
1567
n = 0 ;
1568
+ raw_spin_unlock (& syslog_lock );
1562
1569
logbuf_unlock_irq ();
1563
1570
1564
1571
if (!n )
@@ -1625,8 +1632,11 @@ static int syslog_print_all(char __user *buf, int size, bool clear)
1625
1632
break ;
1626
1633
}
1627
1634
1628
- if (clear )
1635
+ if (clear ) {
1636
+ raw_spin_lock (& syslog_lock );
1629
1637
latched_seq_write (& clear_seq , seq );
1638
+ raw_spin_unlock (& syslog_lock );
1639
+ }
1630
1640
logbuf_unlock_irq ();
1631
1641
1632
1642
kfree (text );
@@ -1636,10 +1646,24 @@ static int syslog_print_all(char __user *buf, int size, bool clear)
1636
1646
static void syslog_clear (void )
1637
1647
{
1638
1648
logbuf_lock_irq ();
1649
+ raw_spin_lock (& syslog_lock );
1639
1650
latched_seq_write (& clear_seq , prb_next_seq (prb ));
1651
+ raw_spin_unlock (& syslog_lock );
1640
1652
logbuf_unlock_irq ();
1641
1653
}
1642
1654
1655
+ /* Return a consistent copy of @syslog_seq. */
1656
+ static u64 read_syslog_seq_irq (void )
1657
+ {
1658
+ u64 seq ;
1659
+
1660
+ raw_spin_lock_irq (& syslog_lock );
1661
+ seq = syslog_seq ;
1662
+ raw_spin_unlock_irq (& syslog_lock );
1663
+
1664
+ return seq ;
1665
+ }
1666
+
1643
1667
int do_syslog (int type , char __user * buf , int len , int source )
1644
1668
{
1645
1669
struct printk_info info ;
@@ -1663,8 +1687,9 @@ int do_syslog(int type, char __user *buf, int len, int source)
1663
1687
return 0 ;
1664
1688
if (!access_ok (buf , len ))
1665
1689
return - EFAULT ;
1690
+
1666
1691
error = wait_event_interruptible (log_wait ,
1667
- prb_read_valid (prb , syslog_seq , NULL ));
1692
+ prb_read_valid (prb , read_syslog_seq_irq () , NULL ));
1668
1693
if (error )
1669
1694
return error ;
1670
1695
error = syslog_print (buf , len );
@@ -1713,8 +1738,10 @@ int do_syslog(int type, char __user *buf, int len, int source)
1713
1738
/* Number of chars in the log buffer */
1714
1739
case SYSLOG_ACTION_SIZE_UNREAD :
1715
1740
logbuf_lock_irq ();
1741
+ raw_spin_lock (& syslog_lock );
1716
1742
if (!prb_read_valid_info (prb , syslog_seq , & info , NULL )) {
1717
1743
/* No unread messages. */
1744
+ raw_spin_unlock (& syslog_lock );
1718
1745
logbuf_unlock_irq ();
1719
1746
return 0 ;
1720
1747
}
@@ -1743,6 +1770,7 @@ int do_syslog(int type, char __user *buf, int len, int source)
1743
1770
}
1744
1771
error -= syslog_partial ;
1745
1772
}
1773
+ raw_spin_unlock (& syslog_lock );
1746
1774
logbuf_unlock_irq ();
1747
1775
break ;
1748
1776
/* Size of the log buffer */
@@ -2992,7 +3020,12 @@ void register_console(struct console *newcon)
2992
3020
*/
2993
3021
exclusive_console = newcon ;
2994
3022
exclusive_console_stop_seq = console_seq ;
3023
+
3024
+ /* Get a consistent copy of @syslog_seq. */
3025
+ raw_spin_lock (& syslog_lock );
2995
3026
console_seq = syslog_seq ;
3027
+ raw_spin_unlock (& syslog_lock );
3028
+
2996
3029
logbuf_unlock_irqrestore (flags );
2997
3030
}
2998
3031
console_unlock ();
0 commit comments