diff options
author | Jason Wessel <jason.wessel@windriver.com> | 2019-08-05 09:32:37 -0700 |
---|---|---|
committer | Armin Kuster <akuster808@gmail.com> | 2019-11-10 15:22:03 -0800 |
commit | d1788e865d9bcd70b36d0f239647aeffb0ea8b85 (patch) | |
tree | e835c5d9db218e6ddacc9e05a30a3e3ed08dc662 /meta/classes/bash-completion.bbclass | |
parent | deabbb60b98418bd4fcf97adc3293b65d3ff306e (diff) | |
download | openembedded-core-contrib-d1788e865d9bcd70b36d0f239647aeffb0ea8b85.tar.gz |
pseudo: Fix openat() with a symlink pointing to a directory
While working with ostree disk generation in conjunction with wic, I
found a problem with pseudo where it tried to resolve a symlink when
it shouldn't, based on openat() flags. A C program has been
constructed to test pseudo to show that it is working properly with
the correct behavior around openat().
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <unistd.h>
#include <fcntl.h>
int main()
{
/*
* Tested with: gcc -Wall -o app app.c ; echo "no pseudo" ;
* ./app ; echo "pseudo"; pseudo ./app
*/
system("rm -rf tdir tlink");
system("mkdir tdir");
system("ln -s tdir tlink");
DIR *dir = opendir(".");
int dfd = dirfd(dir);
int target_dfd = openat (dfd, "tlink", O_RDONLY | O_NONBLOCK |
O_DIRECTORY | O_CLOEXEC | O_NOFOLLOW);
if (target_dfd == -1) {
printf("Test 1 good\n");
} else {
printf("Test 1 failed\n");
close(target_dfd);
}
target_dfd = openat (dfd, "tlink", O_RDONLY | O_NONBLOCK |
O_DIRECTORY | O_CLOEXEC);
if (target_dfd == -1) {
printf("Test 2 failed\n");
} else {
printf("Test 2 good\n");
close(target_dfd);
}
/* Test 3 make sure the owner of the link is root */
struct stat sbuf;
if (!lstat("tlink", &sbuf) && sbuf.st_uid == 0) {
printf("Test 3 good\n");
} else {
printf("Test 3 failed\n");
}
/* Test 4 tests open with the "rb" flag, owner should not change */
int ofd = openat(dfd,"./tlink", O_RDONLY|O_CLOEXEC);
if (ofd >= 0) {
if (fstat(ofd, &sbuf) != 0)
printf("ERROR in fstat test 4\n");
else if (sbuf.st_uid == 0)
printf("Test 4 good\n");
close(ofd);
} else {
printf("Test 4 failed with openat()\n");
}
/* Test pseudo db to see the fstat() above did not delete the DB entry */
if (!lstat("tlink", &sbuf) && sbuf.st_uid == 0)
printf("Test 5 good\n");
else
printf("Test 5 failed... tlink is owned by %i and not 0\n", sbuf.st_uid);
return 0;
}
int main()
{
/* Tested with: gcc -Wall -o app app.c ; echo "no pseudo" ; ./app ; echo "pseudo"; pseudo ./app */
system("rm -rf tdir tlink");
system("mkdir tdir");
system("ln -s tdir tlink");
DIR *dir = opendir(".");
int dfd = dirfd(dir);
int target_dfd = openat (dfd, "tlink", O_RDONLY | O_NONBLOCK | O_DIRECTORY | O_CLOEXEC | O_NOFOLLOW);
if (target_dfd == -1) {
printf("This is right\n");
} else {
printf("This is broken\n");
}
return 0;
}
Many thanks to Peter Seebach for fixing the problem in the pseudo code
to use the same logic which was already there for the
AT_SYMLINK_NOFOLLOW.
Also updated is the license MD5 checksum since the master branch of
pseudo has had the SPDX data updated.
Signed-off-by: Jason Wessel <jason.wessel@windriver.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Signed-off-by: Armin Kuster <akuster808@gmail.com>
Diffstat (limited to 'meta/classes/bash-completion.bbclass')
0 files changed, 0 insertions, 0 deletions