mirror of
https://github.com/clearlinux/graphene.git
synced 2026-09-07 14:21:56 +00:00
[LibOS] Allow inaccessible files during getdents()
Previously, if user performed getdents() on a directory containing inaccessible files (because user doesn't have permission), whole getdents failed with -EACCES. This is incorrect behavior: files must still be listed. This commit fixes the root cause of this bug by marking inaccessible files as DENTRY_NEGATIVE.
This commit is contained in:
@@ -104,7 +104,7 @@ struct shim_fs_ops {
|
||||
};
|
||||
|
||||
#define DENTRY_VALID 0x0001 /* this dentry is verified to be valid */
|
||||
#define DENTRY_NEGATIVE 0x0002 /* negative, recently deleted */
|
||||
#define DENTRY_NEGATIVE 0x0002 /* recently deleted or inaccessible */
|
||||
#define DENTRY_RECENTLY 0x0004 /* recently used */
|
||||
#define DENTRY_PERSIST 0x0008 /* added as a persistent dentry */
|
||||
#define DENTRY_HASHED 0x0010 /* added in the dcache */
|
||||
|
||||
@@ -198,9 +198,9 @@ int lookup_dentry (struct shim_dentry * parent, const char * name, int namelen,
|
||||
* Not done in original code, so leaving for now.
|
||||
*/
|
||||
if (err) {
|
||||
if (err == -ENOENT) {
|
||||
// Let ENOENT fall through so we can get negative dentries in
|
||||
// the cache
|
||||
if (err == -ENOENT || err == -EACCES) {
|
||||
/* Non-existing files and inaccessible files are marked as
|
||||
* negative dentries, so they can still be cached */
|
||||
dent->state |= DENTRY_NEGATIVE;
|
||||
} else {
|
||||
|
||||
@@ -759,8 +759,12 @@ int list_directory_dentry (struct shim_dentry *dent) {
|
||||
for ( ; d ; d = d->next) {
|
||||
struct shim_dentry * child;
|
||||
if ((ret = lookup_dentry(dent, d->name, strlen(d->name),
|
||||
&child, fs)) < 0)
|
||||
goto done_read;
|
||||
&child, fs)) < 0) {
|
||||
if (ret != -ENOENT) {
|
||||
/* if the file is recently deleted or inaccessible, ignore it */
|
||||
goto done_read;
|
||||
}
|
||||
}
|
||||
|
||||
if (child->state & DENTRY_NEGATIVE)
|
||||
continue;
|
||||
@@ -774,6 +778,7 @@ int list_directory_dentry (struct shim_dentry *dent) {
|
||||
}
|
||||
|
||||
dent->state |= DENTRY_LISTED;
|
||||
ret = 0;
|
||||
|
||||
done_read:
|
||||
unlock(&dcache_lock);
|
||||
|
||||
Reference in New Issue
Block a user