On 26/03/2021 12.38, Peter Zijlstra wrote: > Implement debugfs_create_str() to easily display names and such in > debugfs.
Patches 7-9 don't seem to add any users of this. What's it for precisely? > + > +again: > + rcu_read_lock(); > + str = rcu_dereference(*(char **)file->private_data); > + len = strlen(str) + 1; > + > + if (!copy || copy_len < len) { > + rcu_read_unlock(); > + kfree(copy); > + copy = kmalloc(len + 1, GFP_KERNEL); > + if (!copy) { > + debugfs_file_put(dentry); > + return -ENOMEM; > + } > + copy_len = len; > + goto again; > + } > + > + strncpy(copy, str, len); > + copy[len] = '\n'; > + copy[len+1] = '\0'; > + rcu_read_unlock(); As noted (accidentally off-list), this is broken. I think you want this on top - len = strlen(str) + 1; + len = strlen(str); - strncpy(copy, str, len); + memcpy(copy, str, len); copy[len] = '\n'; - copy[len+1] = '\0'; > +EXPORT_SYMBOL_GPL(debugfs_read_file_str); Why? > + > +ssize_t debugfs_write_file_str(struct file *file, const char __user > *user_buf, > + size_t count, loff_t *ppos) > +{ > + struct dentry *dentry = F_DENTRY(file); > + char *old, *new = NULL; > + int pos = *ppos; > + int r; > + > + r = debugfs_file_get(dentry); > + if (unlikely(r)) > + return r; > + > + old = *(char **)file->private_data; > + > + /* only allow strict concattenation */ > + r = -EINVAL; > + if (pos && pos != strlen(old)) > + goto error; Other than the synchronize_rcu() below, I don't see any rcu stuff in here. What prevents one task from kfree'ing old while another computes its strlen()? Or two tasks from getting the same value of old and both kfree'ing the same pointer? And what part of the kernel periodically looks at some string and decides something needs to be done? Shouldn't a write imply some notification or callback? I can see the usefulness of the read part to expose some otherwise-maintained string, but what good does allowing writes do? Rasmus