瀏覽代碼

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>
Joachim Wiberg 3 年之前
父節點
當前提交
e745c0b92d
共有 1 個文件被更改,包括 5 次插入3 次删除
  1. 5 3
      package/makedevs/makedevs.c

+ 5 - 3
package/makedevs/makedevs.c

@@ -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) {