From 6cac15e514f703a2f23d16c104cbea4162da7a9d Mon Sep 17 00:00:00 2001 From: Jason Wessel Date: Mon, 5 Aug 2019 09:32:37 -0700 Subject: 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 #include #include #include #include #include #include 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. (From OE-Core rev: a98ea4be5ce19ff380ca500ba1ef3da490ec4556) Signed-off-by: Jason Wessel Signed-off-by: Richard Purdie --- meta/recipes-devtools/pseudo/pseudo_git.bb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'meta/recipes-devtools/pseudo/pseudo_git.bb') diff --git a/meta/recipes-devtools/pseudo/pseudo_git.bb b/meta/recipes-devtools/pseudo/pseudo_git.bb index 51db84c4d4..6cf711e4c2 100644 --- a/meta/recipes-devtools/pseudo/pseudo_git.bb +++ b/meta/recipes-devtools/pseudo/pseudo_git.bb @@ -8,7 +8,7 @@ SRC_URI = "git://git.yoctoproject.org/pseudo \ file://toomanyfiles.patch \ " -SRCREV = "3fa7c853e0bcd6fe23f7524c2a3c9e3af90901c3" +SRCREV = "060058bb29f70b244e685b3c704eb0641b736f73" S = "${WORKDIR}/git" PV = "1.9.0+git${SRCPV}" -- cgit v1.2.3-54-g00ecf