switch readdir(2) to unsafe_copy_dirent_name()

... and the same for its compat counterpart

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
Al Viro 2020-02-18 14:39:56 -05:00
parent b44f687386
commit 391b7461d4
1 changed files with 16 additions and 14 deletions

View File

@ -157,17 +157,18 @@ static int fillonedir(struct dir_context *ctx, const char *name, int namlen,
} }
buf->result++; buf->result++;
dirent = buf->dirent; dirent = buf->dirent;
if (!access_ok(dirent, if (!user_write_access_begin(dirent,
(unsigned long)(dirent->d_name + namlen + 1) - (unsigned long)(dirent->d_name + namlen + 1) -
(unsigned long)dirent)) (unsigned long)dirent))
goto efault; goto efault;
if ( __put_user(d_ino, &dirent->d_ino) || unsafe_put_user(d_ino, &dirent->d_ino, efault_end);
__put_user(offset, &dirent->d_offset) || unsafe_put_user(offset, &dirent->d_offset, efault_end);
__put_user(namlen, &dirent->d_namlen) || unsafe_put_user(namlen, &dirent->d_namlen, efault_end);
__copy_to_user(dirent->d_name, name, namlen) || unsafe_copy_dirent_name(dirent->d_name, name, namlen, efault_end);
__put_user(0, dirent->d_name + namlen)) user_write_access_end();
goto efault;
return 0; return 0;
efault_end:
user_write_access_end();
efault: efault:
buf->result = -EFAULT; buf->result = -EFAULT;
return -EFAULT; return -EFAULT;
@ -424,17 +425,18 @@ static int compat_fillonedir(struct dir_context *ctx, const char *name,
} }
buf->result++; buf->result++;
dirent = buf->dirent; dirent = buf->dirent;
if (!access_ok(dirent, if (!user_write_access_begin(dirent,
(unsigned long)(dirent->d_name + namlen + 1) - (unsigned long)(dirent->d_name + namlen + 1) -
(unsigned long)dirent)) (unsigned long)dirent))
goto efault; goto efault;
if ( __put_user(d_ino, &dirent->d_ino) || unsafe_put_user(d_ino, &dirent->d_ino, efault_end);
__put_user(offset, &dirent->d_offset) || unsafe_put_user(offset, &dirent->d_offset, efault_end);
__put_user(namlen, &dirent->d_namlen) || unsafe_put_user(namlen, &dirent->d_namlen, efault_end);
__copy_to_user(dirent->d_name, name, namlen) || unsafe_copy_dirent_name(dirent->d_name, name, namlen, efault_end);
__put_user(0, dirent->d_name + namlen)) user_write_access_end();
goto efault;
return 0; return 0;
efault_end:
user_write_access_end();
efault: efault:
buf->result = -EFAULT; buf->result = -EFAULT;
return -EFAULT; return -EFAULT;