Jinoh Kang (@iamahuman) commented about server/fd.c:
- if (!strcmp( srcname, dstname )) goto ret;
- /* This is more complicated now, because in case of a casefold (+F) directory, the destination may very well be the same dentry,
* even if the name doesn't match (if it differs just by case), in which case unlinking it is wrong and can be dangerous. Instead,
* we first rename the source to a temporary filename in the same directory. If this is a casefold dir, this will also remove the
* destination, otherwise the destination still exists. We then create a hardlink from the destination to our temporary name, and
* finally, unlink the temporary. This still works if the directory is case sensitive, so it's not a problem in either case. */
- tmp_value += (current_time >> 16) + current_time;
- for (i = 0; i < 0x8000; i++, tmp_value += 7777)
- {
snprintf( tmpname, sizeof(tmpname), tmpname_fmt, tmp_value );
/* create an empty file or directory to avoid TOCTTOU */
if (!is_dir)
{
int fd = openat( dirfd, tmpname, O_CREAT | O_EXCL, 0777 );
```suggestion:-0+0 int fd = openat( dirfd, tmpname, O_CREAT | O_EXCL | O_WRONLY, 0666 ); ```
For consistency with server/registry.c. It's a good idea to stick to the most typical combination of parameters for filesystem operations, to reduce conflict with ACL or LSM.