On 09/04/2013 03:11 PM, Al Viro wrote:
On Wed, Sep 04, 2013 at 03:05:23PM -0400, Waiman Long wrote:

  static int prepend_name(char **buffer, int *buflen, struct qstr *name)
  {
-       return prepend(buffer, buflen, name->name, name->len);
+       /*
+        * With RCU path tracing, it may race with rename. Use
+        * ACCESS_ONCE() to make sure that it is either the old or
+        * the new name pointer. The length does not really matter as
+        * the sequence number check will eventually catch any ongoing
+        * rename operation.
+        */
+       const char *dname = ACCESS_ONCE(name->name);
+       int   dlen = name->len;
+
+       if (unlikely(!dname || !dlen))
+               return -EINVAL;
+       return prepend(buffer, buflen, dname, dlen);
NAK.  A race with d_move() can very well leave you with dname pointing into
an object of length smaller than dlen.  You *can* copy it byte-by-byte
and rely on NUL-termination, but you can't rely on length being accurate -
not without having excluded d_move().

I have thought about that. But if a d_move() is going on, the string in the buffer will be discarded as the sequence number will change. So whether or not it have embedded null byte shouldn't matter. That is why I didn't add code to do byte-by-byte copy at this first patch. I can add code to do that if you think it is safer to do so.

Regards,
Longman
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to