记一次uid设置错误导致的adb push失败问题

一、问题背景

我司某项目无法使用adb push push文件到/vendor/firmware_mnt目录。使用的指令以及报错结果如下:

1
2
3
4
5
6
7
adb root
adb disable-verity
adb reboot
adb root
adb remount
adb shell mount -o rw,remount /vendor/firmware_mnt
adb push test.txt /vendor/firmware_mnt

输出结果:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
d:\liuqi\Desktop>adb root

d:\liuqi\Desktop>adb disable-verity
Verity is already disabled

d:\liuqi\Desktop>adb remount
Verity is already disabled
Remounted /system as RW
Remounted /system_ext as RW
Remounted /product as RW
Remounted /vendor as RW
Remounted /vendor_dlkm as RW
Remounted /system_dlkm as RW
Remounted /odm as RW
Remounted /vendor/dsp as RW
Remount succeeded

d:\liuqi\Desktop>adb push test.txt /vendor/firmware_mnt/image/
adb: error: failed to copy 'test.txt' to '/vendor/firmware_mnt/image/考试大�': remote fchown() failed uid: 1000 gid: 1000: Operation not permitted
test.txt: 0 files pushed. 0.2 MB/s (3659 bytes in 0.018s)

二、问题分析

2.1 查询mount

1
2
3
d:\liuqi\Desktop>adb shell
xxxx:/ # mount |grep firmware
/dev/block/sde4 on /vendor/firmware_mnt type vfat (rw,context=u:object_r:firmware_file:s0,relatime,gid=1000,fmask=0337,dmask=0227,codepage=437,iocharset=iso8859-1,shortname=lower,errors=remount-ro)

关键词:

  • vfat
  • gid=1000 groupid(system)的才有读写权限
  • rw 读写权限
  • 无userid

2.2 查询目录权限

1
2
3
4
5
6
7
8
9
10
11
12
spring:/ # ls -al /vendor
total 162
drwxr-xr-x 1 root root 3488 2024-12-02 04:21 .
drwxr-xr-x 29 root root 4096 2009-01-01 00:00 ..
drwxr-xr-x 12 root shell 4096 2009-01-01 00:00 app
drwxr-x--x 4 root shell 8192 2009-01-01 00:00 bin
dr-xr-x--- 3 bluetooth net_bt 16384 1970-01-01 00:00 bt_firmware
-rw------- 1 root root 17429 2009-01-01 00:00 build.prop
drwxr-xr-x 5 root root 4096 1970-01-01 00:00 dsp
drwxr-xr-x 1 root shell 3488 2024-12-02 04:55 etc
drwxr-xr-x 3 root shell 4096 2009-01-01 00:00 firmware
dr-xr-x--- 4 root system 16384 1970-01-01 00:00 firmware_mnt

root对应uid=0
system对应gid=1000

2.3 查询fstab

1
2
spring:/ # cat /vendor/etc/fstab.default |grep firmware_mnt
/dev/block/bootdevice/by-name/modem /vendor/firmware_mnt vfat ro,shortname=lower,uid=0,gid=1000,dmask=227,fmask=337,context=u:object_r:firmware_file:s0 wait,slotselect

2.4 分析结果

其实这里已经很清楚了,firmware_mnt只赋予了groupsystem的读写权限,但是当用户为root时,是没有权限访问的!

三、解决方案

查找firmware_mnt的挂载代码,可以看到如下的行:
device/xxxx/xxxx/fstab.default

1
/dev/block/bootdevice/by-name/modem                     /vendor/firmware_mnt   vfat    ro,shortname=lower,uid=0,gid=1000,dmask=227,fmask=337,context=u:object_r:firmware_file:s0 wait,slotselect

uid=0改为uid=1000即可

3.1 临时验证方案

1
2
3
4
5
6
7
8
9
adb root
adb pull /vendor/etc/fstab.default .
修改fstab.default的firmware_mnt那行 将uid=0 改为uid=1000保存
adb push fstab.default /vendor/etc/fstab.default
adb reboot
adb root
adb remount
adb shell mount -o rw,remount /vendor/firmware_mnt
adb push

四、验证结果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
d:\liuqi\Desktop>adb remount
Verity is already disabled
Remounted /system as RW
Remounted /system_ext as RW
Remounted /product as RW
Remounted /vendor as RW
Remounted /vendor_dlkm as RW
Remounted /system_dlkm as RW
Remounted /odm as RW
Remounted /vendor/dsp as RW
Remount succeeded

d:\liuqi\Desktop>adb shell mount -o rw,remount /vendor/firmware_mnt

d:\liuqi\Desktop>adb push test.txt /vendor/firmware_mnt
test.txt: 1 file pushed.