@@ -22,13 +22,57 @@ static char *extract_string(struct prepend_buffer *p)
2222 return ERR_PTR (- ENAMETOOLONG );
2323}
2424
25- static void prepend (struct prepend_buffer * p , const char * str , int namelen )
25+ static bool prepend_char (struct prepend_buffer * p , unsigned char c )
2626{
27- p -> len -= namelen ;
28- if (likely (p -> len >= 0 )) {
29- p -> buf -= namelen ;
30- memcpy (p -> buf , str , namelen );
27+ if (likely (p -> len > 0 )) {
28+ p -> len -- ;
29+ * -- p -> buf = c ;
30+ return true;
31+ }
32+ p -> len = -1 ;
33+ return false;
34+ }
35+
36+ /*
37+ * The source of the prepend data can be an optimistoc load
38+ * of a dentry name and length. And because we don't hold any
39+ * locks, the length and the pointer to the name may not be
40+ * in sync if a concurrent rename happens, and the kernel
41+ * copy might fault as a result.
42+ *
43+ * The end result will correct itself when we check the
44+ * rename sequence count, but we need to be able to handle
45+ * the fault gracefully.
46+ */
47+ static bool prepend_copy (void * dst , const void * src , int len )
48+ {
49+ if (unlikely (copy_from_kernel_nofault (dst , src , len ))) {
50+ memset (dst , 'x' , len );
51+ return false;
3152 }
53+ return true;
54+ }
55+
56+ static bool prepend (struct prepend_buffer * p , const char * str , int namelen )
57+ {
58+ // Already overflowed?
59+ if (p -> len < 0 )
60+ return false;
61+
62+ // Will overflow?
63+ if (p -> len < namelen ) {
64+ // Fill as much as possible from the end of the name
65+ str += namelen - p -> len ;
66+ p -> buf -= p -> len ;
67+ prepend_copy (p -> buf , str , p -> len );
68+ p -> len = -1 ;
69+ return false;
70+ }
71+
72+ // Fits fully
73+ p -> len -= namelen ;
74+ p -> buf -= namelen ;
75+ return prepend_copy (p -> buf , str , namelen );
3276}
3377
3478/**
@@ -40,32 +84,21 @@ static void prepend(struct prepend_buffer *p, const char *str, int namelen)
4084 * With RCU path tracing, it may race with d_move(). Use READ_ONCE() to
4185 * make sure that either the old or the new name pointer and length are
4286 * fetched. However, there may be mismatch between length and pointer.
43- * The length cannot be trusted, we need to copy it byte-by-byte until
44- * the length is reached or a null byte is found . It also prepends "/" at
87+ * But since the length cannot be trusted, we need to copy the name very
88+ * carefully when doing the prepend_copy() . It also prepends "/" at
4589 * the beginning of the name. The sequence number check at the caller will
4690 * retry it again when a d_move() does happen. So any garbage in the buffer
4791 * due to mismatched pointer and length will be discarded.
4892 *
49- * Load acquire is needed to make sure that we see that terminating NUL.
93+ * Load acquire is needed to make sure that we see the new name data even
94+ * if we might get the length wrong.
5095 */
5196static bool prepend_name (struct prepend_buffer * p , const struct qstr * name )
5297{
5398 const char * dname = smp_load_acquire (& name -> name ); /* ^^^ */
5499 u32 dlen = READ_ONCE (name -> len );
55- char * s ;
56100
57- p -> len -= dlen + 1 ;
58- if (unlikely (p -> len < 0 ))
59- return false;
60- s = p -> buf -= dlen + 1 ;
61- * s ++ = '/' ;
62- while (dlen -- ) {
63- char c = * dname ++ ;
64- if (!c )
65- break ;
66- * s ++ = c ;
67- }
68- return true;
101+ return prepend (p , dname , dlen ) && prepend_char (p , '/' );
69102}
70103
71104static int __prepend_path (const struct dentry * dentry , const struct mount * mnt ,
@@ -158,7 +191,7 @@ static int prepend_path(const struct path *path,
158191 b = * p ;
159192
160193 if (b .len == p -> len )
161- prepend (& b , "/" , 1 );
194+ prepend_char (& b , '/' );
162195
163196 * p = b ;
164197 return error ;
@@ -186,7 +219,7 @@ char *__d_path(const struct path *path,
186219{
187220 DECLARE_BUFFER (b , buf , buflen );
188221
189- prepend (& b , "" , 1 );
222+ prepend_char (& b , 0 );
190223 if (unlikely (prepend_path (path , root , & b ) > 0 ))
191224 return NULL ;
192225 return extract_string (& b );
@@ -198,7 +231,7 @@ char *d_absolute_path(const struct path *path,
198231 struct path root = {};
199232 DECLARE_BUFFER (b , buf , buflen );
200233
201- prepend (& b , "" , 1 );
234+ prepend_char (& b , 0 );
202235 if (unlikely (prepend_path (path , & root , & b ) > 1 ))
203236 return ERR_PTR (- EINVAL );
204237 return extract_string (& b );
@@ -255,7 +288,7 @@ char *d_path(const struct path *path, char *buf, int buflen)
255288 if (unlikely (d_unlinked (path -> dentry )))
256289 prepend (& b , " (deleted)" , 11 );
257290 else
258- prepend (& b , "" , 1 );
291+ prepend_char (& b , 0 );
259292 prepend_path (path , & root , & b );
260293 rcu_read_unlock ();
261294
@@ -290,7 +323,7 @@ char *simple_dname(struct dentry *dentry, char *buffer, int buflen)
290323 /* these dentries are never renamed, so d_lock is not needed */
291324 prepend (& b , " (deleted)" , 11 );
292325 prepend (& b , dentry -> d_name .name , dentry -> d_name .len );
293- prepend (& b , "/" , 1 );
326+ prepend_char (& b , '/' );
294327 return extract_string (& b );
295328}
296329
@@ -324,15 +357,15 @@ static char *__dentry_path(const struct dentry *d, struct prepend_buffer *p)
324357 }
325358 done_seqretry (& rename_lock , seq );
326359 if (b .len == p -> len )
327- prepend (& b , "/" , 1 );
360+ prepend_char (& b , '/' );
328361 return extract_string (& b );
329362}
330363
331364char * dentry_path_raw (const struct dentry * dentry , char * buf , int buflen )
332365{
333366 DECLARE_BUFFER (b , buf , buflen );
334367
335- prepend (& b , "" , 1 );
368+ prepend_char (& b , 0 );
336369 return __dentry_path (dentry , & b );
337370}
338371EXPORT_SYMBOL (dentry_path_raw );
@@ -344,7 +377,7 @@ char *dentry_path(const struct dentry *dentry, char *buf, int buflen)
344377 if (unlikely (d_unlinked (dentry )))
345378 prepend (& b , "//deleted" , 10 );
346379 else
347- prepend (& b , "" , 1 );
380+ prepend_char (& b , 0 );
348381 return __dentry_path (dentry , & b );
349382}
350383
@@ -397,7 +430,7 @@ SYSCALL_DEFINE2(getcwd, char __user *, buf, unsigned long, size)
397430 unsigned len ;
398431 DECLARE_BUFFER (b , page , PATH_MAX );
399432
400- prepend (& b , "" , 1 );
433+ prepend_char (& b , 0 );
401434 if (unlikely (prepend_path (& pwd , & root , & b ) > 0 ))
402435 prepend (& b , "(unreachable)" , 13 );
403436 rcu_read_unlock ();
0 commit comments