blob: e58cc184ce4b8478488cbb62bd268704e9882712 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
|
# ChangeSet
# 2005/01/25 10:10:51+00:00 aia21@cantab.net
# NTFS: Add printk rate limiting for ntfs_warning() and ntfs_error() when
# compiled without debug. This avoids a possible denial of service
# attack. Thanks to Carl-Daniel Hailfinger from SuSE for pointing this
# out.
#
# <plasmaroo>: printk_ratelimit() backported from 2.6.
#
diff -Nru a/fs/ntfs/debug.c b/fs/ntfs/debug.c
--- a/fs/ntfs/debug.c 2005-02-15 12:38:26 -08:00
+++ b/fs/ntfs/debug.c 2005-02-15 12:38:26 -08:00
@@ -25,6 +25,48 @@
#endif
#include "debug.h"
+#include <linux/sched.h>
+
+/* minimum time in jiffies between messages */
+int ntfs_debug_printk_ratelimit_jiffies = 5*HZ;
+
+/* number of messages we send before ratelimiting */
+int ntfs_debug_printk_ratelimit_burst = 10;
+
+/*
+ * printk rate limiting, lifted from the networking subsystem.
+ *
+ * This enforces a rate limit: not more than one kernel message
+ * every printk_ratelimit_jiffies to make a denial-of-service
+ * attack impossible.
+ */
+int ntfs_debug_printk_ratelimit(void)
+{
+ static spinlock_t ratelimit_lock = SPIN_LOCK_UNLOCKED;
+ static unsigned long toks = 10*5*HZ;
+ static unsigned long last_msg;
+ static int missed;
+ unsigned long flags;
+ unsigned long now = jiffies;
+
+ spin_lock_irqsave(&ratelimit_lock, flags);
+ toks += now - last_msg;
+ last_msg = now;
+ if (toks > (ntfs_debug_printk_ratelimit_burst * ntfs_debug_printk_ratelimit_jiffies))
+ toks = ntfs_debug_printk_ratelimit_burst * ntfs_debug_printk_ratelimit_jiffies;
+ if (toks >= ntfs_debug_printk_ratelimit_jiffies) {
+ int lost = missed;
+ missed = 0;
+ toks -= ntfs_debug_printk_ratelimit_jiffies;
+ spin_unlock_irqrestore(&ratelimit_lock, flags);
+ if (lost)
+ printk(KERN_WARNING "printk: %d messages suppressed.\n", lost);
+ return 1;
+ }
+ missed++;
+ spin_unlock_irqrestore(&ratelimit_lock, flags);
+ return 0;
+}
/*
* A static buffer to hold the error string being displayed and a spinlock
@@ -53,6 +53,10 @@
va_list args;
int flen = 0;
+#ifndef DEBUG
+ if (!ntfs_debug_printk_ratelimit())
+ return;
+#endif
if (function)
flen = strlen(function);
spin_lock(&err_buf_lock);
@@ -93,6 +97,10 @@
va_list args;
int flen = 0;
+#ifndef DEBUG
+ if (!ntfs_debug_printk_ratelimit())
+ return;
+#endif
if (function)
flen = strlen(function);
spin_lock(&err_buf_lock);
|