mirror of
https://github.com/checkpoint-restore/criu.git
synced 2026-08-03 07:12:48 +00:00
zdtm: Implemented get_current_dir_name wrapper that checks for 'x' permissions
Any filesystem syscall, that needs to navigate to inode by it's absolute path performs successive lookup operations for each part of the path. Lookup operation includes access rights check. Usually but not always zdtm tests processes fall under 'other' access category. Also, usually directories don't have 'x' bit set for other. In case when bit 'x' is not set and user-ID and group-ID of a process relate it to 'other', test's will not succeed in performing these syscalls which are most of filesystem api, that has const char *path as part of it arguments (open, openat, mkdir, bind, etc). The observable behavior of that is that zdtm tests fail at file creation ops on one system and pass on the other. The above is not immediately clear to the developer by just looking at failed test's logs. Investigation of that is also not quick for a developer due to the complex structure of zdtm runtime where nested clones with NAMESPACE flags take place alongside with bind-mounts. As an additional note: 'get_current_dir_name' is documented as returning EACCESS in case when some part of the path lacks read/list permissions. But in fact it's not always so. Practice shows, that test processes can get false success on this operation only to fail on later call to something like mkdir/mknod/bind with a given path in arguments. 'get_cwd_check_perm' is a wrapper around 'get_current_dir_name'. It also checks for permissions on the given filepath and logs the error. This directs the developer towards the right investigation path or even eliminates the need for investigation completely. Signed-off-by: Valeriy Vdovin <valeriy.vdovin@virtuozzo.com>
This commit is contained in:
parent
c40c09cbbf
commit
691b4a4e7e
2 changed files with 48 additions and 0 deletions
|
|
@ -94,3 +94,27 @@ err:
|
|||
mnt_info_free(&m);
|
||||
goto out;
|
||||
}
|
||||
|
||||
int get_cwd_check_perm(char **result)
|
||||
{
|
||||
char *cwd;
|
||||
*result = 0;
|
||||
cwd = get_current_dir_name();
|
||||
if (!cwd) {
|
||||
pr_perror("failed to get current directory");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (access(cwd, X_OK)) {
|
||||
pr_err("access check for bit X for current dir path '%s' "
|
||||
"failed for uid:%d,gid:%d, error: %d(%s). "
|
||||
"Bit 'x' should be set in all path components of "
|
||||
"this directory\n",
|
||||
cwd, getuid(), getgid(), errno, strerror(errno)
|
||||
);
|
||||
return -1;
|
||||
}
|
||||
|
||||
*result = cwd;
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -50,4 +50,28 @@ extern mnt_info_t *mnt_info_alloc(void);
|
|||
extern void mnt_info_free(mnt_info_t **m);
|
||||
extern mnt_info_t *get_cwd_mnt_info(void);
|
||||
|
||||
/*
|
||||
* get_cwd_check_perm is called to check that cwd is actually usable for a calling
|
||||
* process.
|
||||
*
|
||||
* Example output of a stat command on a '/root' path shows file access bits:
|
||||
* > stat /root
|
||||
* File: ‘/root’
|
||||
* ...
|
||||
* Access: (0550/dr-xr-x---) Uid: ( 0/root) Gid: ( 0/root)
|
||||
* ^- no 'x' bit for other
|
||||
*
|
||||
* Here we can see that '/root' dir (that often can be part of cwd path) does not
|
||||
* allow non-root user and non-root group to list contents of this directory.
|
||||
* Calling process matching 'other' access category may succeed getting cwd path, but will
|
||||
* fail performing further filesystem operations based on this path with confusing errors.
|
||||
*
|
||||
* This function calls get_current_dir_name and explicitly checks that bit 'x' is enabled for
|
||||
* a calling process and logs the error.
|
||||
*
|
||||
* If check passes, stores get_current_dir's result in *result and returns 0
|
||||
* If check fails, stores 0 in *result and returns -1
|
||||
*/
|
||||
extern int get_cwd_check_perm(char **result);
|
||||
|
||||
#endif /* ZDTM_FS_H_ */
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue