Fix open(2) allowing opening directories invalidly and check O_TRUNC errors.
Among other things, redirecting to a directory will now display an error as it should. Also fix a bug when opening /dev/pts: O_WRITE on a directory is a POSIX violation.
This commit is contained in:
parent
b767063c9a
commit
9d29e96c3b
|
@ -645,7 +645,11 @@ static bool IsSaneFlagModeCombination(int flags, mode_t /*mode*/)
|
|||
// opening a directory, attempting to truncate it, and then aborting with an
|
||||
// error because a directory was opened.
|
||||
if ( (flags & (O_CREATE | O_TRUNC)) && (flags & (O_DIRECTORY)) )
|
||||
return errno = EINVAL, false;
|
||||
return false;
|
||||
// POSIX: "The result of using O_TRUNC without either O_RDWR or
|
||||
// O_WRONLY is undefined."
|
||||
if ( (flags & O_TRUNC) && !(flags & O_WRITE) )
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -770,6 +774,21 @@ Ref<Descriptor> Descriptor::open(ioctx_t* ctx, const char* filename, int flags,
|
|||
|
||||
delete[] filename_mine;
|
||||
|
||||
// Abort if the user tries to write to an existing directory.
|
||||
if ( S_ISDIR(desc->type) )
|
||||
{
|
||||
if ( flags & (O_CREATE | O_TRUNC | O_WRITE) )
|
||||
return errno = EISDIR, Ref<Descriptor>();
|
||||
}
|
||||
|
||||
// Truncate the file if requested.
|
||||
if ( (flags & O_TRUNC) && S_ISREG(desc->type) )
|
||||
{
|
||||
assert(flags & O_WRITE); // IsSaneFlagModeCombination
|
||||
if ( desc->truncate(ctx, 0) < 0 )
|
||||
return Ref<Descriptor>();
|
||||
}
|
||||
|
||||
// Abort the open if the user wanted a directory but this wasn't.
|
||||
if ( flags & O_DIRECTORY && !S_ISDIR(desc->type) )
|
||||
return errno = ENOTDIR, Ref<Descriptor>();
|
||||
|
@ -802,13 +821,6 @@ Ref<Descriptor> Descriptor::open_elem(ioctx_t* ctx, const char* filename,
|
|||
if ( !ret )
|
||||
return Ref<Descriptor>();
|
||||
|
||||
// Truncate the file if requested.
|
||||
// TODO: This is a bit dodgy, should this be moved to the inode open method
|
||||
// or something? And how should error handling be done here?
|
||||
if ( (flags & O_TRUNC) && S_ISREG(ret->type) )
|
||||
if ( flags & O_WRITE )
|
||||
ret->truncate(ctx, 0);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -520,7 +520,7 @@ static void BootThread(void* /*user*/)
|
|||
if ( slashdev->mkdir(&ctx, "pts", 0755) < 0 )
|
||||
Panic("Could not mkdir /dev/pts");
|
||||
Ref<Descriptor> ptsdir =
|
||||
slashdev->open(&ctx, "pts", O_DIRECTORY | O_READ | O_WRITE);
|
||||
slashdev->open(&ctx, "pts", O_DIRECTORY | O_READ);
|
||||
if ( !ptsdir )
|
||||
Panic("Could not open /dev/pts");
|
||||
if ( !mtable->AddMount(ptsdir->ino, ptsdir->dev, pts, true) )
|
||||
|
|
Loading…
Reference in New Issue