aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2018-01-29 12:02:55 -0500
committerDavid S. Miller <davem@davemloft.net>2018-01-29 12:02:55 -0500
commitbfbe5bab66e1aa68033786599cc495e6728e55e8 (patch)
tree68e92d489b96c65ef2fe4a662d615d9400af3635 /tools
parent7ece54a60ee2ba7a386308cae73c790bd580589c (diff)
parent491847f3b29cef0417a03142b96e2a6dea81cca0 (diff)
Merge branch 'ptr_ring-fixes'
Michael S. Tsirkin says: ==================== ptr_ring fixes This fixes a bunch of issues around ptr_ring use in net core. One of these: "tap: fix use-after-free" is also needed on net, but can't be backported cleanly. I will post a net patch separately. Lightly tested - Jason, could you pls confirm this addresses the security issue you saw with ptr_ring? Testing reports would be appreciated too. ==================== Signed-off-by: David S. Miller <davem@davemloft.net> Tested-by: Jason Wang <jasowang@redhat.com> Acked-by: Jason Wang <jasowang@redhat.com>
Diffstat (limited to 'tools')
-rw-r--r--tools/virtio/linux/kernel.h2
-rw-r--r--tools/virtio/linux/thread_info.h1
-rw-r--r--tools/virtio/ringtest/main.h59
-rw-r--r--tools/virtio/ringtest/ptr_ring.c2
4 files changed, 61 insertions, 3 deletions
diff --git a/tools/virtio/linux/kernel.h b/tools/virtio/linux/kernel.h
index 395521a7a8d8..fca8381bbe04 100644
--- a/tools/virtio/linux/kernel.h
+++ b/tools/virtio/linux/kernel.h
@@ -118,7 +118,7 @@ static inline void free_page(unsigned long addr)
118#define dev_err(dev, format, ...) fprintf (stderr, format, ## __VA_ARGS__) 118#define dev_err(dev, format, ...) fprintf (stderr, format, ## __VA_ARGS__)
119#define dev_warn(dev, format, ...) fprintf (stderr, format, ## __VA_ARGS__) 119#define dev_warn(dev, format, ...) fprintf (stderr, format, ## __VA_ARGS__)
120 120
121#define WARN_ON_ONCE(cond) ((cond) && fprintf (stderr, "WARNING\n")) 121#define WARN_ON_ONCE(cond) ((cond) ? fprintf (stderr, "WARNING\n") : 0)
122 122
123#define min(x, y) ({ \ 123#define min(x, y) ({ \
124 typeof(x) _min1 = (x); \ 124 typeof(x) _min1 = (x); \
diff --git a/tools/virtio/linux/thread_info.h b/tools/virtio/linux/thread_info.h
new file mode 100644
index 000000000000..e0f610d08006
--- /dev/null
+++ b/tools/virtio/linux/thread_info.h
@@ -0,0 +1 @@
#define check_copy_size(A, B, C) (1)
diff --git a/tools/virtio/ringtest/main.h b/tools/virtio/ringtest/main.h
index 5706e075adf2..301d59bfcd0a 100644
--- a/tools/virtio/ringtest/main.h
+++ b/tools/virtio/ringtest/main.h
@@ -111,7 +111,7 @@ static inline void busy_wait(void)
111} 111}
112 112
113#if defined(__x86_64__) || defined(__i386__) 113#if defined(__x86_64__) || defined(__i386__)
114#define smp_mb() asm volatile("lock; addl $0,-128(%%rsp)" ::: "memory", "cc") 114#define smp_mb() asm volatile("lock; addl $0,-132(%%rsp)" ::: "memory", "cc")
115#else 115#else
116/* 116/*
117 * Not using __ATOMIC_SEQ_CST since gcc docs say they are only synchronized 117 * Not using __ATOMIC_SEQ_CST since gcc docs say they are only synchronized
@@ -134,4 +134,61 @@ static inline void busy_wait(void)
134 barrier(); \ 134 barrier(); \
135} while (0) 135} while (0)
136 136
137#if defined(__i386__) || defined(__x86_64__) || defined(__s390x__)
138#define smp_wmb() barrier()
139#else
140#define smp_wmb() smp_release()
141#endif
142
143#ifdef __alpha__
144#define smp_read_barrier_depends() smp_acquire()
145#else
146#define smp_read_barrier_depends() do {} while(0)
147#endif
148
149static __always_inline
150void __read_once_size(const volatile void *p, void *res, int size)
151{
152 switch (size) { \
153 case 1: *(unsigned char *)res = *(volatile unsigned char *)p; break; \
154 case 2: *(unsigned short *)res = *(volatile unsigned short *)p; break; \
155 case 4: *(unsigned int *)res = *(volatile unsigned int *)p; break; \
156 case 8: *(unsigned long long *)res = *(volatile unsigned long long *)p; break; \
157 default: \
158 barrier(); \
159 __builtin_memcpy((void *)res, (const void *)p, size); \
160 barrier(); \
161 } \
162}
163
164static __always_inline void __write_once_size(volatile void *p, void *res, int size)
165{
166 switch (size) {
167 case 1: *(volatile unsigned char *)p = *(unsigned char *)res; break;
168 case 2: *(volatile unsigned short *)p = *(unsigned short *)res; break;
169 case 4: *(volatile unsigned int *)p = *(unsigned int *)res; break;
170 case 8: *(volatile unsigned long long *)p = *(unsigned long long *)res; break;
171 default:
172 barrier();
173 __builtin_memcpy((void *)p, (const void *)res, size);
174 barrier();
175 }
176}
177
178#define READ_ONCE(x) \
179({ \
180 union { typeof(x) __val; char __c[1]; } __u; \
181 __read_once_size(&(x), __u.__c, sizeof(x)); \
182 smp_read_barrier_depends(); /* Enforce dependency ordering from x */ \
183 __u.__val; \
184})
185
186#define WRITE_ONCE(x, val) \
187({ \
188 union { typeof(x) __val; char __c[1]; } __u = \
189 { .__val = (typeof(x)) (val) }; \
190 __write_once_size(&(x), __u.__c, sizeof(x)); \
191 __u.__val; \
192})
193
137#endif 194#endif
diff --git a/tools/virtio/ringtest/ptr_ring.c b/tools/virtio/ringtest/ptr_ring.c
index e6e81305ef46..477899c12c51 100644
--- a/tools/virtio/ringtest/ptr_ring.c
+++ b/tools/virtio/ringtest/ptr_ring.c
@@ -187,7 +187,7 @@ bool enable_kick()
187 187
188bool avail_empty() 188bool avail_empty()
189{ 189{
190 return !__ptr_ring_peek(&array); 190 return __ptr_ring_empty(&array);
191} 191}
192 192
193bool use_buf(unsigned *lenp, void **bufp) 193bool use_buf(unsigned *lenp, void **bufp)