pseudo_util: Fix handling of absolute links
Absolute links should be evaluated starting from the chroot path but the
existing implementation drops the whole base path (which includes the
chroot path) when it encounters an absolute link.
Encountered the issue during root image creation process in an OE build
where ldconfig was deleting some absolute links as stat64 calls failed
and the symlinks were deemed dead.
Signed-off-by: Chaitanya Vadrevu <chaitanya.vadrevu@ni.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Chaitanya Vadrevu authored 2 years ago
Richard Purdie committed 2 years ago
693 | 693 |
}
|
694 | 694 |
/* null-terminate buffer */
|
695 | 695 |
linkbuf[linklen] = '\0';
|
696 | |
/* absolute symlink means start over! */
|
|
696 |
/* absolute symlink means go back to root */
|
697 | 697 |
if (*linkbuf == '/') {
|
698 | |
current = newpath;
|
|
698 |
current = root;
|
699 | 699 |
} else {
|
700 | 700 |
/* point back at the end of the previous path... */
|
701 | 701 |
current -= (elen + 1);
|
|
793 | 793 |
* path of baselen characters, presumed not to end in a /. path is
|
794 | 794 |
* the new path to be canonicalized. The tricky part is that path may
|
795 | 795 |
* contain symlinks, which must be resolved.
|
796 | |
* if "path" starts with a /, then it is an absolute path, and
|
797 | |
* we ignore base.
|
798 | 796 |
*/
|
799 | 797 |
char *
|
800 | 798 |
pseudo_fix_path(const char *base, const char *path, size_t rootlen, size_t baselen, size_t *lenp, int leave_last) {
|
|
0 |
/*
|
|
1 |
* Test that stat'ing absolute/relative symlinks in a chroot environment works
|
|
2 |
* SPDX-License-Identifier: LGPL-2.1-only
|
|
3 |
*
|
|
4 |
*/
|
|
5 |
#define _GNU_SOURCE
|
|
6 |
|
|
7 |
#include <unistd.h>
|
|
8 |
#include <sys/stat.h>
|
|
9 |
#include <stdio.h>
|
|
10 |
|
|
11 |
int main(int argc, char *argv[]) {
|
|
12 |
struct stat buf;
|
|
13 |
|
|
14 |
if (argc != 2) {
|
|
15 |
perror("args");
|
|
16 |
return 2;
|
|
17 |
}
|
|
18 |
if (chroot(argv[1]) == -1) {
|
|
19 |
perror("chroot");
|
|
20 |
return 1;
|
|
21 |
}
|
|
22 |
if (stat("symlink", &buf) == -1) {
|
|
23 |
perror("stat symlink");
|
|
24 |
return 1;
|
|
25 |
}
|
|
26 |
return 0;
|
|
27 |
}
|
|
0 |
#!/bin/bash
|
|
1 |
#
|
|
2 |
# Test that stat'ing absolute/relative symlinks in a chroot environment works
|
|
3 |
# SPDX-License-Identifier: LGPL-2.1-only
|
|
4 |
#
|
|
5 |
|
|
6 |
set -e
|
|
7 |
|
|
8 |
touch symlink_target
|
|
9 |
trap "rm -f symlink_target symlink" 0
|
|
10 |
|
|
11 |
# Absolute symlink
|
|
12 |
ln -s /symlink_target symlink
|
|
13 |
./test/test-chroot-symlink `pwd`
|
|
14 |
rm symlink
|
|
15 |
|
|
16 |
# Relative symlink
|
|
17 |
ln -s symlink_target symlink
|
|
18 |
./test/test-chroot-symlink `pwd`
|