Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fs.ftruncate silently accepts negative offsets rather than failing with ERR_INVALID #35632

Closed
sbc100 opened this issue Oct 13, 2020 · 5 comments
Labels
confirmed-bug Issues with confirmed bugs. fs Issues and PRs related to the fs subsystem / file system.

Comments

@sbc100
Copy link

sbc100 commented Oct 13, 2020

fs.ftruncate and fd.ftruncateSync both silently ignore negative offsets:

node/lib/fs.js

Line 840 in 2cfdf28

len = MathMax(0, len);

This didn't always do behave like this.. looks like it was introduced in 8974df1

What steps will reproduce the bug?

var fs = require("fs");
var fd = fs.openSync("f", 'w+');
console.log(fs.ftruncateSync(fd, -99));

What is the expected behavior?

The ftruncate POSIX function is described as returning EINVAL when given a negative offset:
https://linux.die.net/man/2/ftruncate

In emscripten we emulate a POSIX environment on top of the Web and on top of node and expect ftruncate to fail in the same way.

We can obviously add a check to our code as a workaround but this does seem like a bug in node.

What do you see instead?

Silently assumed 0 length is what the caller really wants.

@Narasimha1997
Copy link
Contributor

Narasimha1997 commented Oct 14, 2020

Maybe removing len = MathMax(0, len); would fix the issue, or by explicitly handling the negative value case before calling the internal method. Had experienced this issue, a week back ! I solved this by explicitly checking the len before passing it down to the ftruncateSync()

@RaisinTen
Copy link
Contributor

What about adding this sort of a change?

-  len = MathMax(0, len);
+  if (len < 0) {
+    throw new ERR_FS_FILE_TOO_SMALL(len);
+  } else if (len > kIoMaxLength) {
+    throw new ERR_FS_FILE_TOO_LARGE(len);
+  }

where, ERR_FS_FILE_TOO_LARGE already exists and we make a new error code ERR_FS_FILE_TOO_SMALL for negative sizes and this is all about kIoMaxLength:

node/lib/fs.js

Lines 27 to 29 in 999e7d7

// Most platforms don't allow reads or writes >= 2 GB.
// See https://github.com/libuv/libuv/pull/1501.
const kIoMaxLength = 2 ** 31 - 1;

This would take care of both the upper and the lower limits for the allowed size in ftruncate.

@PoojaDurgad PoojaDurgad added fs Issues and PRs related to the fs subsystem / file system. confirmed-bug Issues with confirmed bugs. labels Oct 14, 2020
@sbc100
Copy link
Author

sbc100 commented Oct 14, 2020

I'm not familiar with node code but isn't there already the simple equivalent of EINVAL? Is it a good idea to add more error codes?

@Narasimha1997
Copy link
Contributor

Node 8.xx.xx throws EINVAL properly for negative offset. Maybe there is no need to handle explicitly. Even len = MathMax(0, len) is not required. The internal system call itself terminates with EINVAL when it sees negative offset. So no need to handle anything explicitly. If you check the source code of 8.xx.xx there is no explicit validation being done.

jasnell added a commit to jasnell/node that referenced this issue Feb 22, 2021
`fs.ftruncate`, `fsPromises.truncate`, and `fsPromises.ftruncate`
all adjust negative lengths to 0 before invoking the system call.
`fs.truncate()` was the one outlier.

This "fixes" nodejs#35632 but in the
opposite direction than discussed in the issue -- specifically by
removing an EINVAL error from one function rather than adding it to
another.

Signed-off-by: James M Snell <jasnell@gmail.com>
Fixes: nodejs#35632
@jasnell
Copy link
Member

jasnell commented Feb 22, 2021

PR: #37483

jasnell added a commit to jasnell/node that referenced this issue Feb 23, 2021
`fs.ftruncate`, `fsPromises.truncate`, and `fsPromises.ftruncate`
all adjust negative lengths to 0 before invoking the system call.
`fs.truncate()` was the one outlier.

This "fixes" nodejs#35632 but in the
opposite direction than discussed in the issue -- specifically by
removing an EINVAL error from one function rather than adding it to
another.

Signed-off-by: James M Snell <jasnell@gmail.com>
Fixes: nodejs#35632
targos pushed a commit that referenced this issue Feb 28, 2021
`fs.ftruncate`, `fsPromises.truncate`, and `fsPromises.ftruncate`
all adjust negative lengths to 0 before invoking the system call.
`fs.truncate()` was the one outlier.

This "fixes" #35632 but in the
opposite direction than discussed in the issue -- specifically by
removing an EINVAL error from one function rather than adding it to
another.

Signed-off-by: James M Snell <jasnell@gmail.com>
Fixes: #35632

PR-URL: #37483
Reviewed-By: Darshan Sen <raisinten@gmail.com>
Reviewed-By: Juan José Arboleda <soyjuanarbol@gmail.com>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
targos pushed a commit that referenced this issue Sep 4, 2021
`fs.ftruncate`, `fsPromises.truncate`, and `fsPromises.ftruncate`
all adjust negative lengths to 0 before invoking the system call.
`fs.truncate()` was the one outlier.

This "fixes" #35632 but in the
opposite direction than discussed in the issue -- specifically by
removing an EINVAL error from one function rather than adding it to
another.

Signed-off-by: James M Snell <jasnell@gmail.com>
Fixes: #35632

PR-URL: #37483
Reviewed-By: Darshan Sen <raisinten@gmail.com>
Reviewed-By: Juan José Arboleda <soyjuanarbol@gmail.com>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
confirmed-bug Issues with confirmed bugs. fs Issues and PRs related to the fs subsystem / file system.
Projects
None yet
5 participants