Message ID | 20240401-strncpy-fs-udf-super-c-v1-1-80cddab7a281@google.com (mailing list archive) |
---|---|
State | Mainlined |
Commit | 94755a00a4e79236d4bfa6dc671a339828fb38ce |
Headers | show |
Series | udf: replace deprecated strncpy/strcpy with strscpy | expand |
On Mon 01-04-24 20:01:51, Justin Stitt wrote: > strncpy() is deprecated for use on NUL-terminated destination strings > [1] and as such we should prefer more robust and less ambiguous string > interfaces. Also replace an instance of strcpy() which is also > deprecated. > > s_volume_ident is a NUL-terminated string which is evident from its > usage in udf_debug: > | udf_debug("volIdent[] = '%s'\n", UDF_SB(sb)->s_volume_ident); > > s_volume_ident should also be NUL-padded as it is copied out to > userspace: > | if (copy_to_user((char __user *)arg, > | UDF_SB(inode->i_sb)->s_volume_ident, 32)) > | return -EFAULT; > > Considering the above, a suitable replacement is `strscpy_pad` [2] due > to the fact that it guarantees both NUL-termination and NUL-padding on > the destination buffer. > > To simplify the code, let's use the new 2-argument version of > strscpy_pad() introduced in Commit e6584c3964f2f ("string: Allow > 2-argument strscpy()"). Also zero-allocate @outstr so we can safely use > a non-@ret length argument. This is just in case udf_dstrCS0toChar() > doesn't include the NUL-byte in its return length, we won't truncate > @outstr or write garbage bytes either. > > Link: https://www.kernel.org/doc/html/latest/process/deprecated.html#strncpy-on-nul-terminated-strings [1] > Link: https://manpages.debian.org/testing/linux-manual-4.8/strscpy.9.en.html [2] > Link: https://github.com/KSPP/linux/issues/90 > Cc: linux-hardening@vger.kernel.org > Signed-off-by: Justin Stitt <justinstitt@google.com> Thanks! Added to my tree. Honza > --- > Note: build-tested only. > > Found with: $ rg "strncpy\(" > --- > fs/udf/super.c | 6 +++--- > 1 file changed, 3 insertions(+), 3 deletions(-) > > diff --git a/fs/udf/super.c b/fs/udf/super.c > index 2217f7ed7a49..77d32fe14434 100644 > --- a/fs/udf/super.c > +++ b/fs/udf/super.c > @@ -895,7 +895,7 @@ static int udf_load_pvoldesc(struct super_block *sb, sector_t block) > int ret; > struct timestamp *ts; > > - outstr = kmalloc(128, GFP_KERNEL); > + outstr = kzalloc(128, GFP_KERNEL); > if (!outstr) > return -ENOMEM; > > @@ -921,11 +921,11 @@ static int udf_load_pvoldesc(struct super_block *sb, sector_t block) > > ret = udf_dstrCS0toChar(sb, outstr, 31, pvoldesc->volIdent, 32); > if (ret < 0) { > - strcpy(UDF_SB(sb)->s_volume_ident, "InvalidName"); > + strscpy_pad(UDF_SB(sb)->s_volume_ident, "InvalidName"); > pr_warn("incorrect volume identification, setting to " > "'InvalidName'\n"); > } else { > - strncpy(UDF_SB(sb)->s_volume_ident, outstr, ret); > + strscpy_pad(UDF_SB(sb)->s_volume_ident, outstr); > } > udf_debug("volIdent[] = '%s'\n", UDF_SB(sb)->s_volume_ident); > > > --- > base-commit: 928a87efa42302a23bb9554be081a28058495f22 > change-id: 20240401-strncpy-fs-udf-super-c-983457eb4ac3 > > Best regards, > -- > Justin Stitt <justinstitt@google.com> >
diff --git a/fs/udf/super.c b/fs/udf/super.c index 2217f7ed7a49..77d32fe14434 100644 --- a/fs/udf/super.c +++ b/fs/udf/super.c @@ -895,7 +895,7 @@ static int udf_load_pvoldesc(struct super_block *sb, sector_t block) int ret; struct timestamp *ts; - outstr = kmalloc(128, GFP_KERNEL); + outstr = kzalloc(128, GFP_KERNEL); if (!outstr) return -ENOMEM; @@ -921,11 +921,11 @@ static int udf_load_pvoldesc(struct super_block *sb, sector_t block) ret = udf_dstrCS0toChar(sb, outstr, 31, pvoldesc->volIdent, 32); if (ret < 0) { - strcpy(UDF_SB(sb)->s_volume_ident, "InvalidName"); + strscpy_pad(UDF_SB(sb)->s_volume_ident, "InvalidName"); pr_warn("incorrect volume identification, setting to " "'InvalidName'\n"); } else { - strncpy(UDF_SB(sb)->s_volume_ident, outstr, ret); + strscpy_pad(UDF_SB(sb)->s_volume_ident, outstr); } udf_debug("volIdent[] = '%s'\n", UDF_SB(sb)->s_volume_ident);
strncpy() is deprecated for use on NUL-terminated destination strings [1] and as such we should prefer more robust and less ambiguous string interfaces. Also replace an instance of strcpy() which is also deprecated. s_volume_ident is a NUL-terminated string which is evident from its usage in udf_debug: | udf_debug("volIdent[] = '%s'\n", UDF_SB(sb)->s_volume_ident); s_volume_ident should also be NUL-padded as it is copied out to userspace: | if (copy_to_user((char __user *)arg, | UDF_SB(inode->i_sb)->s_volume_ident, 32)) | return -EFAULT; Considering the above, a suitable replacement is `strscpy_pad` [2] due to the fact that it guarantees both NUL-termination and NUL-padding on the destination buffer. To simplify the code, let's use the new 2-argument version of strscpy_pad() introduced in Commit e6584c3964f2f ("string: Allow 2-argument strscpy()"). Also zero-allocate @outstr so we can safely use a non-@ret length argument. This is just in case udf_dstrCS0toChar() doesn't include the NUL-byte in its return length, we won't truncate @outstr or write garbage bytes either. Link: https://www.kernel.org/doc/html/latest/process/deprecated.html#strncpy-on-nul-terminated-strings [1] Link: https://manpages.debian.org/testing/linux-manual-4.8/strscpy.9.en.html [2] Link: https://github.com/KSPP/linux/issues/90 Cc: linux-hardening@vger.kernel.org Signed-off-by: Justin Stitt <justinstitt@google.com> --- Note: build-tested only. Found with: $ rg "strncpy\(" --- fs/udf/super.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) --- base-commit: 928a87efa42302a23bb9554be081a28058495f22 change-id: 20240401-strncpy-fs-udf-super-c-983457eb4ac3 Best regards, -- Justin Stitt <justinstitt@google.com>