package/makedevs: allow recursive on directory with dangling symlinks

When using BR2_ROOTFS_DEVICE_TABLE to change ownership of /etc, like so:

  /etc        r  -1 root     wheel     - - - - -

makedevs fails due to trying to chown() a dangling symlink:

  makedevs: chown failed for /src/myLinux/output/build/buildroot-fs/ext2/target/etc/mtab: No such file or directory
  makedevs: line 25: recursive failed for /src/myLinux/output/build/buildroot-fs/ext2/target/etc: No such file or directory
  make[2]: *** [fs/ext2/ext2.mk:63: /src/myLinux/output/images/rootfs.ext2] Error 1
  make[1]: *** [Makefile:84: _all] Error 2
  make[1]: Leaving directory '/src/myLinux/buildroot'

This patch changes chown() to lchown() in two cases in makedevs.c when
the argument can be a symlink, dangling or not.

In case the recursive operation includes a chmod() as well, explicitly
exclude symlinks that are dangling, because chmod() always operates on
the link target.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Signed-off-by: Yann E. MORIN <yann.morin.1998@free.fr>
2022.02.x
Joachim Wiberg 2021-12-23 10:07:58 +01:00 committed by Yann E. MORIN
parent e644e5df39
commit e745c0b92d
1 changed files with 5 additions and 3 deletions

View File

@ -440,11 +440,13 @@ void bb_show_usage(void)
int bb_recursive(const char *fpath, const struct stat *sb,
int tflag, struct FTW *ftwbuf){
if (chown(fpath, recursive_uid, recursive_gid) == -1) {
if (lchown(fpath, recursive_uid, recursive_gid) == -1) {
bb_perror_msg("chown failed for %s", fpath);
return -1;
}
if (recursive_mode != -1) {
/* chmod() is optional, also skip if dangling symlink */
if (recursive_mode != -1 && tflag == FTW_SL && access(fpath, F_OK)) {
if (chmod(fpath, recursive_mode) < 0) {
bb_perror_msg("chmod failed for %s", fpath);
return -1;
@ -628,7 +630,7 @@ int main(int argc, char **argv)
if (mknod(full_name_inc, mode, rdev) < 0) {
bb_perror_msg("line %d: can't create node %s", linenum, full_name_inc);
ret = EXIT_FAILURE;
} else if (chown(full_name_inc, uid, gid) < 0) {
} else if (lchown(full_name_inc, uid, gid) < 0) {
bb_perror_msg("line %d: can't chown %s", linenum, full_name_inc);
ret = EXIT_FAILURE;
} else if (chmod(full_name_inc, mode) < 0) {