mirror of
https://gitlab.com/sortix/sortix.git
synced 2023-02-13 20:55:38 -05:00
Fix unlinkat potentially following paths twice.
This commit is contained in:
parent
8c0252300e
commit
5589085084
4 changed files with 14 additions and 25 deletions
|
@ -606,26 +606,22 @@ int Descriptor::link(ioctx_t* ctx, const char* filename, Ref<Descriptor> node)
|
|||
return ret;
|
||||
}
|
||||
|
||||
int Descriptor::unlink(ioctx_t* ctx, const char* filename)
|
||||
int Descriptor::unlinkat(ioctx_t* ctx, const char* filename, int flags)
|
||||
{
|
||||
if ( flags & ~(AT_REMOVEFILE | AT_REMOVEDIR) )
|
||||
return errno = EINVAL, -1;
|
||||
if ( !(flags & (AT_REMOVEFILE | AT_REMOVEDIR)) )
|
||||
flags |= AT_REMOVEFILE;
|
||||
char* final;
|
||||
Ref<Descriptor> dir = OpenDirContainingPath(ctx, Ref<Descriptor>(this),
|
||||
filename, &final);
|
||||
if ( !dir )
|
||||
return -1;
|
||||
int ret = dir->vnode->unlink(ctx, final);
|
||||
delete[] final;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int Descriptor::rmdir(ioctx_t* ctx, const char* filename)
|
||||
{
|
||||
char* final;
|
||||
Ref<Descriptor> dir = OpenDirContainingPath(ctx, Ref<Descriptor>(this),
|
||||
filename, &final);
|
||||
if ( !dir )
|
||||
return -1;
|
||||
int ret = dir->vnode->rmdir(ctx, final);
|
||||
int ret = -1;
|
||||
if ( ret < 0 && (flags & AT_REMOVEFILE) )
|
||||
ret = dir->vnode->unlink(ctx, final);
|
||||
if ( ret < 0 && (flags & AT_REMOVEDIR) )
|
||||
ret = dir->vnode->rmdir(ctx, final);
|
||||
delete[] final;
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -80,8 +80,7 @@ public:
|
|||
mode_t mode = 0);
|
||||
int mkdir(ioctx_t* ctx, const char* filename, mode_t mode);
|
||||
int link(ioctx_t* ctx, const char* filename, Ref<Descriptor> node);
|
||||
int unlink(ioctx_t* ctx, const char* filename);
|
||||
int rmdir(ioctx_t* ctx, const char* filename);
|
||||
int unlinkat(ioctx_t* ctx, const char* filename, int flags);
|
||||
int symlink(ioctx_t* ctx, const char* oldname, const char* filename);
|
||||
ssize_t readlink(ioctx_t* ctx, char* buf, size_t bufsiz);
|
||||
int tcgetwincurpos(ioctx_t* ctx, struct wincurpos* wcp);
|
||||
|
|
|
@ -392,13 +392,13 @@ bool ExtractFromPhysicalInto(addr_t physaddr, size_t size, Ref<Descriptor> desc)
|
|||
{
|
||||
if ( ((const char*) dirent.d_name)[0] == '.' )
|
||||
continue;
|
||||
ctx.links->unlink(&ctx.ioctx, dirent.d_name);
|
||||
ctx.links->unlinkat(&ctx.ioctx, dirent.d_name, AT_REMOVEFILE);
|
||||
ctx.links->lseek(&ctx.ioctx, 0, SEEK_SET);
|
||||
}
|
||||
|
||||
ctx.links.Reset();
|
||||
|
||||
desc->rmdir(&ctx.ioctx, ".initrd-links");
|
||||
desc->unlinkat(&ctx.ioctx, ".initrd-links", AT_REMOVEDIR);
|
||||
|
||||
// Unmap the pages and return the physical frames for reallocation.
|
||||
for ( size_t i = 0; i < initrd_addr_alloc.size; i += Page::Size() )
|
||||
|
|
|
@ -204,8 +204,6 @@ int sys_faccessat(int dirfd, const char* path, int /*mode*/, int flags)
|
|||
|
||||
int sys_unlinkat(int dirfd, const char* path, int flags)
|
||||
{
|
||||
if ( !(flags & (AT_REMOVEFILE | AT_REMOVEDIR)) )
|
||||
flags |= AT_REMOVEFILE;
|
||||
char* pathcopy = GetStringFromUser(path);
|
||||
if ( !pathcopy )
|
||||
return -1;
|
||||
|
@ -213,11 +211,7 @@ int sys_unlinkat(int dirfd, const char* path, int flags)
|
|||
const char* relpath = pathcopy;
|
||||
Ref<Descriptor> from = PrepareLookup(&relpath, dirfd);
|
||||
if ( !from ) { delete[] pathcopy; return -1; }
|
||||
int ret = -1;
|
||||
if ( ret < 0 && (flags & AT_REMOVEFILE) )
|
||||
ret = from->unlink(&ctx, relpath);
|
||||
if ( ret < 0 && (flags & AT_REMOVEDIR) )
|
||||
ret = from->rmdir(&ctx, relpath);
|
||||
int ret = from->unlinkat(&ctx, relpath, flags);
|
||||
delete[] pathcopy;
|
||||
return ret;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue