Skip to content

Instantly share code, notes, and snippets.

@Lanchon
Created October 2, 2014 05:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Lanchon/c8599c7a4535e8420803 to your computer and use it in GitHub Desktop.
Save Lanchon/c8599c7a4535e8420803 to your computer and use it in GitHub Desktop.
CM11-M10 sdcard.c objdump (i9100)
sdcard: file format elf32-littlearm
Disassembly of section .plt:
00000f68 <__libc_init@plt-0x14>:
f68: e52de004 .word 0xe52de004
f6c: e59fe004 .word 0xe59fe004
f70: e08fe00e .word 0xe08fe00e
f74: e5bef008 .word 0xe5bef008
f78: 00003f44 .word 0x00003f44
00000f7c <__libc_init@plt>:
f7c: e28fc600 .word 0xe28fc600
f80: e28cca03 .word 0xe28cca03
f84: e5bcff44 .word 0xe5bcff44
00000f88 <__cxa_atexit@plt>:
f88: e28fc600 .word 0xe28fc600
f8c: e28cca03 .word 0xe28cca03
f90: e5bcff3c .word 0xe5bcff3c
00000f94 <fprintf@plt>:
f94: e28fc600 .word 0xe28fc600
f98: e28cca03 .word 0xe28cca03
f9c: e5bcff34 .word 0xe5bcff34
00000fa0 <strcasecmp@plt>:
fa0: e28fc600 .word 0xe28fc600
fa4: e28cca03 .word 0xe28cca03
fa8: e5bcff2c .word 0xe5bcff2c
00000fac <strlen@plt>:
fac: e28fc600 .word 0xe28fc600
fb0: e28cca03 .word 0xe28cca03
fb4: e5bcff24 .word 0xe5bcff24
00000fb8 <hashmapHash@plt>:
fb8: e28fc600 .word 0xe28fc600
fbc: e28cca03 .word 0xe28cca03
fc0: e5bcff1c .word 0xe5bcff1c
00000fc4 <memcpy@plt>:
fc4: e28fc600 .word 0xe28fc600
fc8: e28cca03 .word 0xe28cca03
fcc: e5bcff14 .word 0xe5bcff14
00000fd0 <hashmapRemove@plt>:
fd0: e28fc600 .word 0xe28fc600
fd4: e28cca03 .word 0xe28cca03
fd8: e5bcff0c .word 0xe5bcff0c
00000fdc <free@plt>:
fdc: e28fc600 .word 0xe28fc600
fe0: e28cca03 .word 0xe28cca03
fe4: e5bcff04 .word 0xe5bcff04
00000fe8 <writev@plt>:
fe8: e28fc600 .word 0xe28fc600
fec: e28cca03 .word 0xe28cca03
ff0: e5bcfefc .word 0xe5bcfefc
00000ff4 <__errno@plt>:
ff4: e28fc600 .word 0xe28fc600
ff8: e28cca03 .word 0xe28cca03
ffc: e5bcfef4 .word 0xe5bcfef4
00001000 <memset@plt>:
1000: e28fc600 .word 0xe28fc600
1004: e28cca03 .word 0xe28cca03
1008: e5bcfeec .word 0xe5bcfeec
0000100c <multiuser_get_app_id@plt>:
100c: e28fc600 .word 0xe28fc600
1010: e28cca03 .word 0xe28cca03
1014: e5bcfee4 .word 0xe5bcfee4
00001018 <hashmapContainsKey@plt>:
1018: e28fc600 .word 0xe28fc600
101c: e28cca03 .word 0xe28cca03
1020: e5bcfedc .word 0xe5bcfedc
00001024 <pthread_mutex_lock@plt>:
1024: e28fc600 .word 0xe28fc600
1028: e28cca03 .word 0xe28cca03
102c: e5bcfed4 .word 0xe5bcfed4
00001030 <pthread_mutex_unlock@plt>:
1030: e28fc600 .word 0xe28fc600
1034: e28cca03 .word 0xe28cca03
1038: e5bcfecc .word 0xe5bcfecc
0000103c <statfs@plt>:
103c: e28fc600 .word 0xe28fc600
1040: e28cca03 .word 0xe28cca03
1044: e5bcfec4 .word 0xe5bcfec4
00001048 <__stack_chk_fail@plt>:
1048: e28fc600 .word 0xe28fc600
104c: e28cca03 .word 0xe28cca03
1050: e5bcfebc .word 0xe5bcfebc
00001054 <rewinddir@plt>:
1054: e28fc600 .word 0xe28fc600
1058: e28cca03 .word 0xe28cca03
105c: e5bcfeb4 .word 0xe5bcfeb4
00001060 <readdir@plt>:
1060: e28fc600 .word 0xe28fc600
1064: e28cca03 .word 0xe28cca03
1068: e5bcfeac .word 0xe5bcfeac
0000106c <__memcpy_chk@plt>:
106c: e28fc600 .word 0xe28fc600
1070: e28cca03 .word 0xe28cca03
1074: e5bcfea4 .word 0xe5bcfea4
00001078 <open@plt>:
1078: e28fc600 .word 0xe28fc600
107c: e28cca03 .word 0xe28cca03
1080: e5bcfe9c .word 0xe5bcfe9c
00001084 <strerror@plt>:
1084: e28fc600 .word 0xe28fc600
1088: e28cca03 .word 0xe28cca03
108c: e5bcfe94 .word 0xe5bcfe94
00001090 <close@plt>:
1090: e28fc600 .word 0xe28fc600
1094: e28cca03 .word 0xe28cca03
1098: e5bcfe8c .word 0xe5bcfe8c
0000109c <access@plt>:
109c: e28fc600 .word 0xe28fc600
10a0: e28cca03 .word 0xe28cca03
10a4: e5bcfe84 .word 0xe5bcfe84
000010a8 <opendir@plt>:
10a8: e28fc600 .word 0xe28fc600
10ac: e28cca03 .word 0xe28cca03
10b0: e5bcfe7c .word 0xe5bcfe7c
000010b4 <closedir@plt>:
10b4: e28fc600 .word 0xe28fc600
10b8: e28cca03 .word 0xe28cca03
10bc: e5bcfe74 .word 0xe5bcfe74
000010c0 <rmdir@plt>:
10c0: e28fc600 .word 0xe28fc600
10c4: e28cca03 .word 0xe28cca03
10c8: e5bcfe6c .word 0xe5bcfe6c
000010cc <unlink@plt>:
10cc: e28fc600 .word 0xe28fc600
10d0: e28cca03 .word 0xe28cca03
10d4: e5bcfe64 .word 0xe5bcfe64
000010d8 <malloc@plt>:
10d8: e28fc600 .word 0xe28fc600
10dc: e28cca03 .word 0xe28cca03
10e0: e5bcfe5c .word 0xe5bcfe5c
000010e4 <__open_2@plt>:
10e4: e28fc600 .word 0xe28fc600
10e8: e28cca03 .word 0xe28cca03
10ec: e5bcfe54 .word 0xe5bcfe54
000010f0 <lstat@plt>:
10f0: e28fc600 .word 0xe28fc600
10f4: e28cca03 .word 0xe28cca03
10f8: e5bcfe4c .word 0xe5bcfe4c
000010fc <truncate@plt>:
10fc: e28fc600 .word 0xe28fc600
1100: e28cca03 .word 0xe28cca03
1104: e5bcfe44 .word 0xe5bcfe44
00001108 <utimensat@plt>:
1108: e28fc600 .word 0xe28fc600
110c: e28cca03 .word 0xe28cca03
1110: e5bcfe3c .word 0xe5bcfe3c
00001114 <strcmp@plt>:
1114: e28fc600 .word 0xe28fc600
1118: e28cca03 .word 0xe28cca03
111c: e5bcfe34 .word 0xe5bcfe34
00001120 <rename@plt>:
1120: e28fc600 .word 0xe28fc600
1124: e28cca03 .word 0xe28cca03
1128: e5bcfe2c .word 0xe5bcfe2c
0000112c <realloc@plt>:
112c: e28fc600 .word 0xe28fc600
1130: e28cca03 .word 0xe28cca03
1134: e5bcfe24 .word 0xe5bcfe24
00001138 <calloc@plt>:
1138: e28fc600 .word 0xe28fc600
113c: e28cca03 .word 0xe28cca03
1140: e5bcfe1c .word 0xe5bcfe1c
00001144 <strtoul@plt>:
1144: e28fc600 .word 0xe28fc600
1148: e28cca03 .word 0xe28cca03
114c: e5bcfe14 .word 0xe5bcfe14
00001150 <__strlen_chk@plt>:
1150: e28fc600 .word 0xe28fc600
1154: e28cca03 .word 0xe28cca03
1158: e5bcfe0c .word 0xe5bcfe0c
0000115c <hashmapGet@plt>:
115c: e28fc600 .word 0xe28fc600
1160: e28cca03 .word 0xe28cca03
1164: e5bcfe04 .word 0xe5bcfe04
00001168 <multiuser_get_uid@plt>:
1168: e28fc600 .word 0xe28fc600
116c: e28cca03 .word 0xe28cca03
1170: e5bcfdfc .word 0xe5bcfdfc
00001174 <mknod@plt>:
1174: e28fc600 .word 0xe28fc600
1178: e28cca03 .word 0xe28cca03
117c: e5bcfdf4 .word 0xe5bcfdf4
00001180 <mkdir@plt>:
1180: e28fc600 .word 0xe28fc600
1184: e28cca03 .word 0xe28cca03
1188: e5bcfdec .word 0xe5bcfdec
0000118c <snprintf@plt>:
118c: e28fc600 .word 0xe28fc600
1190: e28cca03 .word 0xe28cca03
1194: e5bcfde4 .word 0xe5bcfde4
00001198 <read@plt>:
1198: e28fc600 .word 0xe28fc600
119c: e28cca03 .word 0xe28cca03
11a0: e5bcfddc .word 0xe5bcfddc
000011a4 <pread64@plt>:
11a4: e28fc600 .word 0xe28fc600
11a8: e28cca03 .word 0xe28cca03
11ac: e5bcfdd4 .word 0xe5bcfdd4
000011b0 <pwrite64@plt>:
11b0: e28fc600 .word 0xe28fc600
11b4: e28cca03 .word 0xe28cca03
11b8: e5bcfdcc .word 0xe5bcfdcc
000011bc <fdatasync@plt>:
11bc: e28fc600 .word 0xe28fc600
11c0: e28cca03 .word 0xe28cca03
11c4: e5bcfdc4 .word 0xe5bcfdc4
000011c8 <fsync@plt>:
11c8: e28fc600 .word 0xe28fc600
11cc: e28cca03 .word 0xe28cca03
11d0: e5bcfdbc .word 0xe5bcfdbc
000011d4 <write@plt>:
11d4: e28fc600 .word 0xe28fc600
11d8: e28cca03 .word 0xe28cca03
11dc: e5bcfdb4 .word 0xe5bcfdb4
000011e0 <umount2@plt>:
11e0: e28fc600 .word 0xe28fc600
11e4: e28cca03 .word 0xe28cca03
11e8: e5bcfdac .word 0xe5bcfdac
000011ec <mount@plt>:
11ec: e28fc600 .word 0xe28fc600
11f0: e28cca03 .word 0xe28cca03
11f4: e5bcfda4 .word 0xe5bcfda4
000011f8 <setgroups@plt>:
11f8: e28fc600 .word 0xe28fc600
11fc: e28cca03 .word 0xe28cca03
1200: e5bcfd9c .word 0xe5bcfd9c
00001204 <setgid@plt>:
1204: e28fc600 .word 0xe28fc600
1208: e28cca03 .word 0xe28cca03
120c: e5bcfd94 .word 0xe5bcfd94
00001210 <setuid@plt>:
1210: e28fc600 .word 0xe28fc600
1214: e28cca03 .word 0xe28cca03
1218: e5bcfd8c .word 0xe5bcfd8c
0000121c <pthread_mutex_init@plt>:
121c: e28fc600 .word 0xe28fc600
1220: e28cca03 .word 0xe28cca03
1224: e5bcfd84 .word 0xe5bcfd84
00001228 <strdup@plt>:
1228: e28fc600 .word 0xe28fc600
122c: e28cca03 .word 0xe28cca03
1230: e5bcfd7c .word 0xe5bcfd7c
00001234 <hashmapCreate@plt>:
1234: e28fc600 .word 0xe28fc600
1238: e28cca03 .word 0xe28cca03
123c: e5bcfd74 .word 0xe5bcfd74
00001240 <getuid@plt>:
1240: e28fc600 .word 0xe28fc600
1244: e28cca03 .word 0xe28cca03
1248: e5bcfd6c .word 0xe5bcfd6c
0000124c <getgid@plt>:
124c: e28fc600 .word 0xe28fc600
1250: e28cca03 .word 0xe28cca03
1254: e5bcfd64 .word 0xe5bcfd64
00001258 <fs_prepare_dir@plt>:
1258: e28fc600 .word 0xe28fc600
125c: e28cca03 .word 0xe28cca03
1260: e5bcfd5c .word 0xe5bcfd5c
00001264 <umask@plt>:
1264: e28fc600 .word 0xe28fc600
1268: e28cca03 .word 0xe28cca03
126c: e5bcfd54 .word 0xe5bcfd54
00001270 <fputs@plt>:
1270: e28fc600 .word 0xe28fc600
1274: e28cca03 .word 0xe28cca03
1278: e5bcfd4c .word 0xe5bcfd4c
0000127c <pthread_create@plt>:
127c: e28fc600 .word 0xe28fc600
1280: e28cca03 .word 0xe28cca03
1284: e5bcfd44 .word 0xe5bcfd44
00001288 <inotify_init@plt>:
1288: e28fc600 .word 0xe28fc600
128c: e28cca03 .word 0xe28cca03
1290: e5bcfd3c .word 0xe5bcfd3c
00001294 <inotify_add_watch@plt>:
1294: e28fc600 .word 0xe28fc600
1298: e28cca03 .word 0xe28cca03
129c: e5bcfd34 .word 0xe5bcfd34
000012a0 <sleep@plt>:
12a0: e28fc600 .word 0xe28fc600
12a4: e28cca03 .word 0xe28cca03
12a8: e5bcfd2c .word 0xe5bcfd2c
000012ac <hashmapForEach@plt>:
12ac: e28fc600 .word 0xe28fc600
12b0: e28cca03 .word 0xe28cca03
12b4: e5bcfd24 .word 0xe5bcfd24
000012b8 <fopen@plt>:
12b8: e28fc600 .word 0xe28fc600
12bc: e28cca03 .word 0xe28cca03
12c0: e5bcfd1c .word 0xe5bcfd1c
000012c4 <sscanf@plt>:
12c4: e28fc600 .word 0xe28fc600
12c8: e28cca03 .word 0xe28cca03
12cc: e5bcfd14 .word 0xe5bcfd14
000012d0 <hashmapPut@plt>:
12d0: e28fc600 .word 0xe28fc600
12d4: e28cca03 .word 0xe28cca03
12d8: e5bcfd0c .word 0xe5bcfd0c
000012dc <strtok@plt>:
12dc: e28fc600 .word 0xe28fc600
12e0: e28cca03 .word 0xe28cca03
12e4: e5bcfd04 .word 0xe5bcfd04
000012e8 <fgets@plt>:
12e8: e28fc600 .word 0xe28fc600
12ec: e28cca03 .word 0xe28cca03
12f0: e5bcfcfc .word 0xe5bcfcfc
000012f4 <fclose@plt>:
12f4: e28fc600 .word 0xe28fc600
12f8: e28cca03 .word 0xe28cca03
12fc: e5bcfcf4 .word 0xe5bcfcf4
00001300 <exit@plt>:
1300: e28fc600 .word 0xe28fc600
1304: e28cca03 .word 0xe28cca03
1308: e5bcfcec .word 0xe5bcfcec
0000130c <getopt@plt>:
130c: e28fc600 .word 0xe28fc600
1310: e28cca03 .word 0xe28cca03
1314: e5bcfce4 .word 0xe5bcfce4
00001318 <setrlimit@plt>:
1318: e28fc600 .word 0xe28fc600
131c: e28cca03 .word 0xe28cca03
1320: e5bcfcdc .word 0xe5bcfcdc
Disassembly of section .text:
00001328 <_start>:
1328: e92d4800 push {fp, lr}
132c: e28db004 add fp, sp, #4
1330: e24dd010 sub sp, sp, #16
1334: e59f3050 ldr r3, [pc, #80] ; 138c <_start+0x64>
1338: e08f3003 add r3, pc, r3
133c: e59f204c ldr r2, [pc, #76] ; 1390 <_start+0x68>
1340: e7932002 ldr r2, [r3, r2]
1344: e50b2014 str r2, [fp, #-20]
1348: e59f2044 ldr r2, [pc, #68] ; 1394 <_start+0x6c>
134c: e7932002 ldr r2, [r3, r2]
1350: e50b2010 str r2, [fp, #-16]
1354: e59f203c ldr r2, [pc, #60] ; 1398 <_start+0x70>
1358: e7932002 ldr r2, [r3, r2]
135c: e50b200c str r2, [fp, #-12]
1360: e1a0200b mov r2, fp
1364: e2822004 add r2, r2, #4
1368: e50b2008 str r2, [fp, #-8]
136c: e24bc014 sub ip, fp, #20
1370: e51b0008 ldr r0, [fp, #-8]
1374: e3a01000 mov r1, #0
1378: e59f201c ldr r2, [pc, #28] ; 139c <_start+0x74>
137c: e7933002 ldr r3, [r3, r2]
1380: e1a02003 mov r2, r3
1384: e1a0300c mov r3, ip
1388: ebfffefb bl f7c <__libc_init@plt>
138c: 00003b7c .word 0x00003b7c
1390: ffffffe0 .word 0xffffffe0
1394: ffffffe4 .word 0xffffffe4
1398: ffffffe8 .word 0xffffffe8
139c: ffffffec .word 0xffffffec
000013a0 <atexit>:
13a0: e92d4800 push {fp, lr}
13a4: e28db004 add fp, sp, #4
13a8: e24dd008 sub sp, sp, #8
13ac: e50b0008 str r0, [fp, #-8]
13b0: e51b0008 ldr r0, [fp, #-8]
13b4: e3a01000 mov r1, #0
13b8: e59f3018 ldr r3, [pc, #24] ; 13d8 <atexit+0x38>
13bc: e08f3003 add r3, pc, r3
13c0: e1a02003 mov r2, r3
13c4: ebfffeef bl f88 <__cxa_atexit@plt>
13c8: e1a03000 mov r3, r0
13cc: e1a00003 mov r0, r3
13d0: e24bd004 sub sp, fp, #4
13d4: e8bd8800 pop {fp, pc}
13d8: 00003c3c .word 0x00003c3c
000013dc <main>:
*/
extern int sdcard_main(int argc, char **argv);
int main(int argc, char **argv) {
return sdcard_main(argc, argv);
13dc: f001 be66 b.w 30ac <sdcard_main>
000013e0 <int_hash>:
return strcasecmp(keyA, keyB) == 0;
}
static int int_hash(void *key) {
return (int) key;
}
13e0: 4770 bx lr
000013e2 <int_equals>:
static bool int_equals(void *keyA, void *keyB) {
return keyA == keyB;
}
13e2: 1a0b subs r3, r1, r0
13e4: 4258 negs r0, r3
13e6: 4158 adcs r0, r3
13e8: 4770 bx lr
...
000013ec <usage>:
quit:
exit(1);
}
static int usage()
{
13ec: b508 push {r3, lr}
13ee: 4b06 ldr r3, [pc, #24] ; (1408 <usage+0x1c>)
ERROR("usage: sdcard [OPTIONS] <source_path> <dest_path>\n"
13f0: 4a06 ldr r2, [pc, #24] ; (140c <usage+0x20>)
quit:
exit(1);
}
static int usage()
{
13f2: 447b add r3, pc
ERROR("usage: sdcard [OPTIONS] <source_path> <dest_path>\n"
13f4: 4906 ldr r1, [pc, #24] ; (1410 <usage+0x24>)
13f6: 5898 ldr r0, [r3, r2]
13f8: 2202 movs r2, #2
13fa: 4479 add r1, pc
13fc: 30a8 adds r0, #168 ; 0xa8
13fe: f7ff edca blx f94 <fprintf@plt>
" -d: derive file permissions based on path\n"
" -l: derive file permissions based on legacy internal layout\n"
" -s: split derived permissions for pics, av (requires -d or -l)\n"
"\n", DEFAULT_NUM_THREADS);
return 1;
}
1402: 2001 movs r0, #1
1404: bd08 pop {r3, pc}
1406: bf00 nop
1408: 00003ac6 .word 0x00003ac6
140c: fffffff0 .word 0xfffffff0
1410: 000020e2 .word 0x000020e2
00001414 <str_icase_equals>:
static int str_hash(void *key) {
return hashmapHash(key, strlen(key));
}
/** Test if two string keys are equal ignoring case */
static bool str_icase_equals(void *keyA, void *keyB) {
1414: b508 push {r3, lr}
return strcasecmp(keyA, keyB) == 0;
1416: f7ff edc4 blx fa0 <strcasecmp@plt>
}
141a: f1d0 0001 rsbs r0, r0, #1
141e: bf38 it cc
1420: 2000 movcc r0, #0
1422: bd08 pop {r3, pc}
00001424 <str_hash>:
* position. Used to support things like OBB. */
char* graft_path;
size_t graft_pathlen;
};
static int str_hash(void *key) {
1424: b510 push {r4, lr}
1426: 4604 mov r4, r0
size_t bos = __bos(s);
#if !defined(__clang__)
// Compiler doesn't know destination size. Don't call __strlen_chk
if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
return __builtin_strlen(s);
1428: f7ff edc0 blx fac <strlen@plt>
142c: 4601 mov r1, r0
return hashmapHash(key, strlen(key));
142e: 4620 mov r0, r4
}
1430: e8bd 4010 ldmia.w sp!, {r4, lr}
char* graft_path;
size_t graft_pathlen;
};
static int str_hash(void *key) {
return hashmapHash(key, strlen(key));
1434: f001 bf30 b.w 3298 <sdcard_main+0x1ec>
00001438 <get_node_path_locked>:
/* Gets the absolute path to a node into the provided buffer.
*
* Populates 'buf' with the path and returns the length of the path on success,
* or returns -1 if the path is too long for the provided buffer.
*/
static ssize_t get_node_path_locked(struct node* node, char* buf, size_t bufsize) {
1438: e92d 41f0 stmdb sp!, {r4, r5, r6, r7, r8, lr}
143c: 460f mov r7, r1
const char* name;
size_t namelen;
if (node->graft_path) {
143e: 6c43 ldr r3, [r0, #68] ; 0x44
1440: b113 cbz r3, 1448 <get_node_path_locked+0x10>
name = node->graft_path;
namelen = node->graft_pathlen;
1442: 6c84 ldr r4, [r0, #72] ; 0x48
1444: 461e mov r6, r3
1446: e003 b.n 1450 <get_node_path_locked+0x18>
} else if (node->actual_name) {
1448: 6c06 ldr r6, [r0, #64] ; 0x40
144a: 6b84 ldr r4, [r0, #56] ; 0x38
144c: b906 cbnz r6, 1450 <get_node_path_locked+0x18>
name = node->actual_name;
namelen = node->namelen;
} else {
name = node->name;
144e: 6bc6 ldr r6, [r0, #60] ; 0x3c
namelen = node->namelen;
}
if (bufsize < namelen + 1) {
1450: f104 0801 add.w r8, r4, #1
1454: 4542 cmp r2, r8
1456: d203 bcs.n 1460 <get_node_path_locked+0x28>
return -1;
1458: f04f 30ff mov.w r0, #4294967295 ; 0xffffffff
145c: e8bd 81f0 ldmia.w sp!, {r4, r5, r6, r7, r8, pc}
}
ssize_t pathlen = 0;
if (node->parent && node->graft_path == NULL) {
1460: 6b40 ldr r0, [r0, #52] ; 0x34
1462: b158 cbz r0, 147c <get_node_path_locked+0x44>
1464: b963 cbnz r3, 1480 <get_node_path_locked+0x48>
pathlen = get_node_path_locked(node->parent, buf, bufsize - namelen - 2);
1466: 3a02 subs r2, #2
1468: 4639 mov r1, r7
146a: 1b12 subs r2, r2, r4
146c: f7ff ffe4 bl 1438 <get_node_path_locked>
if (pathlen < 0) {
1470: 2800 cmp r0, #0
1472: dbf1 blt.n 1458 <get_node_path_locked+0x20>
return -1;
}
buf[pathlen++] = '/';
1474: 212f movs r1, #47 ; 0x2f
1476: 1c45 adds r5, r0, #1
1478: 5439 strb r1, [r7, r0]
147a: e002 b.n 1482 <get_node_path_locked+0x4a>
if (bufsize < namelen + 1) {
return -1;
}
ssize_t pathlen = 0;
147c: 4605 mov r5, r0
147e: e000 b.n 1482 <get_node_path_locked+0x4a>
1480: 2500 movs r5, #0
if (__builtin_constant_p(copy_amount) && (copy_amount > s_len)) {
__memcpy_src_size_error();
}
return __builtin___memcpy_chk(dest, src, copy_amount, d_len);
1482: 1978 adds r0, r7, r5
1484: 4631 mov r1, r6
1486: 4642 mov r2, r8
1488: f7ff ed9c blx fc4 <memcpy@plt>
}
buf[pathlen++] = '/';
}
memcpy(buf + pathlen, name, namelen + 1); /* include trailing \0 */
return pathlen + namelen;
148c: 1928 adds r0, r5, r4
}
148e: e8bd 81f0 ldmia.w sp!, {r4, r5, r6, r7, r8, pc}
00001492 <remove_int_to_null>:
hashmapRemove(map, key);
free(key);
return true;
}
static bool remove_int_to_null(void *key, void *value, void *context) {
1492: 4601 mov r1, r0
1494: b508 push {r3, lr}
Hashmap* map = context;
hashmapRemove(map, key);
1496: 4610 mov r0, r2
1498: f7ff ed9a blx fd0 <hashmapRemove@plt>
return true;
}
149c: 2001 movs r0, #1
149e: bd08 pop {r3, pc}
000014a0 <remove_str_to_int>:
struct fuse_handler* handler = data;
handle_fuse_requests(handler);
return NULL;
}
static bool remove_str_to_int(void *key, void *value, void *context) {
14a0: b510 push {r4, lr}
14a2: 4604 mov r4, r0
Hashmap* map = context;
hashmapRemove(map, key);
14a4: 4621 mov r1, r4
14a6: 4610 mov r0, r2
14a8: f7ff ed92 blx fd0 <hashmapRemove@plt>
free(key);
14ac: 4620 mov r0, r4
14ae: f7ff ed96 blx fdc <free@plt>
return true;
}
14b2: 2001 movs r0, #1
14b4: bd10 pop {r4, pc}
...
000014b8 <check_caller_access_to_name>:
/* Kernel has already enforced everything we returned through
* derive_permissions_locked(), so this is used to lock down access
* even further, such as enforcing that apps hold sdcard_rw. */
static bool check_caller_access_to_name(struct fuse* fuse,
const struct fuse_in_header *hdr, const struct node* parent_node,
const char* name, int mode, bool has_rw) {
14b8: e92d 41f0 stmdb sp!, {r4, r5, r6, r7, r8, lr}
14bc: 4680 mov r8, r0
14be: 460f mov r7, r1
14c0: 461e mov r6, r3
/* Always block security-sensitive files at root */
if (parent_node && parent_node->perm == PERM_ROOT) {
14c2: 4615 mov r5, r2
/* Kernel has already enforced everything we returned through
* derive_permissions_locked(), so this is used to lock down access
* even further, such as enforcing that apps hold sdcard_rw. */
static bool check_caller_access_to_name(struct fuse* fuse,
const struct fuse_in_header *hdr, const struct node* parent_node,
const char* name, int mode, bool has_rw) {
14c4: f89d 401c ldrb.w r4, [sp, #28]
/* Always block security-sensitive files at root */
if (parent_node && parent_node->perm == PERM_ROOT) {
14c8: b1a2 cbz r2, 14f4 <check_caller_access_to_name+0x3c>
14ca: 6993 ldr r3, [r2, #24]
14cc: 2b02 cmp r3, #2
14ce: d111 bne.n 14f4 <check_caller_access_to_name+0x3c>
if (!strcasecmp(name, "autorun.inf")
14d0: 4912 ldr r1, [pc, #72] ; (151c <check_caller_access_to_name+0x64>)
14d2: 4630 mov r0, r6
14d4: 4479 add r1, pc
14d6: f7ff ed64 blx fa0 <strcasecmp@plt>
14da: b1c8 cbz r0, 1510 <check_caller_access_to_name+0x58>
|| !strcasecmp(name, ".android_secure")
14dc: 4910 ldr r1, [pc, #64] ; (1520 <check_caller_access_to_name+0x68>)
14de: 4630 mov r0, r6
14e0: 4479 add r1, pc
14e2: f7ff ed5e blx fa0 <strcasecmp@plt>
14e6: b198 cbz r0, 1510 <check_caller_access_to_name+0x58>
|| !strcasecmp(name, "android_secure")) {
14e8: 490e ldr r1, [pc, #56] ; (1524 <check_caller_access_to_name+0x6c>)
14ea: 4630 mov r0, r6
14ec: 4479 add r1, pc
14ee: f7ff ed58 blx fa0 <strcasecmp@plt>
14f2: b168 cbz r0, 1510 <check_caller_access_to_name+0x58>
return false;
}
}
/* No additional permissions enforcement */
if (fuse->derive == DERIVE_NONE) {
14f4: f8d8 0014 ldr.w r0, [r8, #20]
14f8: b160 cbz r0, 1514 <check_caller_access_to_name+0x5c>
return true;
}
/* Root always has access; access for any other UIDs should always
* be controlled through packages.list. */
if (hdr->uid == 0) {
14fa: 69b9 ldr r1, [r7, #24]
14fc: b151 cbz r1, 1514 <check_caller_access_to_name+0x5c>
return true;
}
/* If asking to write, verify that caller either owns the
* parent or holds sdcard_rw. */
if (mode & W_OK) {
14fe: 9a06 ldr r2, [sp, #24]
1500: 0792 lsls r2, r2, #30
1502: d507 bpl.n 1514 <check_caller_access_to_name+0x5c>
if (parent_node && hdr->uid == parent_node->uid) {
1504: b13d cbz r5, 1516 <check_caller_access_to_name+0x5e>
1506: 6a2b ldr r3, [r5, #32]
}
/* Root always has access; access for any other UIDs should always
* be controlled through packages.list. */
if (hdr->uid == 0) {
return true;
1508: 4299 cmp r1, r3
150a: bf08 it eq
150c: 2401 moveq r4, #1
150e: e002 b.n 1516 <check_caller_access_to_name+0x5e>
/* Always block security-sensitive files at root */
if (parent_node && parent_node->perm == PERM_ROOT) {
if (!strcasecmp(name, "autorun.inf")
|| !strcasecmp(name, ".android_secure")
|| !strcasecmp(name, "android_secure")) {
return false;
1510: 4604 mov r4, r0
1512: e000 b.n 1516 <check_caller_access_to_name+0x5e>
}
}
/* No additional permissions enforcement */
if (fuse->derive == DERIVE_NONE) {
return true;
1514: 2401 movs r4, #1
return has_rw;
}
/* No extra permissions to enforce */
return true;
}
1516: 4620 mov r0, r4
1518: e8bd 81f0 ldmia.w sp!, {r4, r5, r6, r7, r8, pc}
151c: 00002199 .word 0x00002199
1520: 00002199 .word 0x00002199
1524: 0000219d .word 0x0000219d
00001528 <fuse_reply>:
hdr.unique = unique;
write(fuse->fd, &hdr, sizeof(hdr));
}
static void fuse_reply(struct fuse *fuse, __u64 unique, void *data, int len)
{
1528: b530 push {r4, r5, lr}
152a: b089 sub sp, #36 ; 0x24
152c: 990d ldr r1, [sp, #52] ; 0x34
struct iovec vec[2];
int res;
hdr.len = len + sizeof(hdr);
hdr.error = 0;
hdr.unique = unique;
152e: e9cd 2302 strd r2, r3, [sp, #8]
vec[0].iov_base = &hdr;
vec[0].iov_len = sizeof(hdr);
1532: 2210 movs r2, #16
{
struct fuse_out_header hdr;
struct iovec vec[2];
int res;
hdr.len = len + sizeof(hdr);
1534: f101 0510 add.w r5, r1, #16
hdr.error = 0;
hdr.unique = unique;
vec[0].iov_base = &hdr;
vec[0].iov_len = sizeof(hdr);
1538: 9205 str r2, [sp, #20]
{
struct fuse_out_header hdr;
struct iovec vec[2];
int res;
hdr.len = len + sizeof(hdr);
153a: 9500 str r5, [sp, #0]
hdr.error = 0;
153c: 2500 movs r5, #0
hdr.unique = unique;
vec[0].iov_base = &hdr;
153e: eb0d 0305 add.w r3, sp, r5
vec[0].iov_len = sizeof(hdr);
vec[1].iov_base = data;
vec[1].iov_len = len;
1542: 9107 str r1, [sp, #28]
hdr.len = len + sizeof(hdr);
hdr.error = 0;
hdr.unique = unique;
vec[0].iov_base = &hdr;
1544: 9304 str r3, [sp, #16]
vec[0].iov_len = sizeof(hdr);
vec[1].iov_base = data;
vec[1].iov_len = len;
res = writev(fuse->fd, vec, 2);
1546: 2202 movs r2, #2
hdr.error = 0;
hdr.unique = unique;
vec[0].iov_base = &hdr;
vec[0].iov_len = sizeof(hdr);
vec[1].iov_base = data;
1548: 9b0c ldr r3, [sp, #48] ; 0x30
vec[1].iov_len = len;
res = writev(fuse->fd, vec, 2);
154a: a904 add r1, sp, #16
hdr.unique = unique;
write(fuse->fd, &hdr, sizeof(hdr));
}
static void fuse_reply(struct fuse *fuse, __u64 unique, void *data, int len)
{
154c: 4c0a ldr r4, [pc, #40] ; (1578 <fuse_reply+0x50>)
vec[0].iov_base = &hdr;
vec[0].iov_len = sizeof(hdr);
vec[1].iov_base = data;
vec[1].iov_len = len;
res = writev(fuse->fd, vec, 2);
154e: 6900 ldr r0, [r0, #16]
struct fuse_out_header hdr;
struct iovec vec[2];
int res;
hdr.len = len + sizeof(hdr);
hdr.error = 0;
1550: 9501 str r5, [sp, #4]
hdr.unique = unique;
vec[0].iov_base = &hdr;
vec[0].iov_len = sizeof(hdr);
vec[1].iov_base = data;
1552: 9306 str r3, [sp, #24]
hdr.unique = unique;
write(fuse->fd, &hdr, sizeof(hdr));
}
static void fuse_reply(struct fuse *fuse, __u64 unique, void *data, int len)
{
1554: 447c add r4, pc
vec[0].iov_base = &hdr;
vec[0].iov_len = sizeof(hdr);
vec[1].iov_base = data;
vec[1].iov_len = len;
res = writev(fuse->fd, vec, 2);
1556: f7ff ed48 blx fe8 <writev@plt>
if (res < 0) {
155a: 42a8 cmp r0, r5
155c: da09 bge.n 1572 <fuse_reply+0x4a>
ERROR("*** REPLY FAILED *** %d\n", errno);
155e: f7ff ed4a blx ff4 <__errno@plt>
1562: 6802 ldr r2, [r0, #0]
1564: 4805 ldr r0, [pc, #20] ; (157c <fuse_reply+0x54>)
1566: 4906 ldr r1, [pc, #24] ; (1580 <fuse_reply+0x58>)
1568: 5820 ldr r0, [r4, r0]
156a: 4479 add r1, pc
156c: 30a8 adds r0, #168 ; 0xa8
156e: f7ff ed12 blx f94 <fprintf@plt>
}
}
1572: b009 add sp, #36 ; 0x24
1574: bd30 pop {r4, r5, pc}
1576: bf00 nop
1578: 00003964 .word 0x00003964
157c: fffffff0 .word 0xfffffff0
1580: 0000212e .word 0x0000212e
00001584 <release_node_locked>:
}
static void remove_node_from_parent_locked(struct node* node);
static void release_node_locked(struct node* node)
{
1584: b510 push {r4, lr}
1586: 4604 mov r4, r0
1588: 4b14 ldr r3, [pc, #80] ; (15dc <release_node_locked+0x58>)
TRACE("RELEASE %p (%s) rc=%d\n", node, node->name, node->refcount);
if (node->refcount > 0) {
158a: 6802 ldr r2, [r0, #0]
}
static void remove_node_from_parent_locked(struct node* node);
static void release_node_locked(struct node* node)
{
158c: 447b add r3, pc
TRACE("RELEASE %p (%s) rc=%d\n", node, node->name, node->refcount);
if (node->refcount > 0) {
158e: b1d2 cbz r2, 15c6 <release_node_locked+0x42>
node->refcount--;
1590: 1e53 subs r3, r2, #1
1592: 6003 str r3, [r0, #0]
if (!node->refcount) {
1594: 2b00 cmp r3, #0
1596: d120 bne.n 15da <release_node_locked+0x56>
TRACE("DESTROY %p (%s)\n", node, node->name);
remove_node_from_parent_locked(node);
1598: f000 f826 bl 15e8 <remove_node_from_parent_locked>
return __builtin___strncat_chk(dest, src, n, __bos(dest));
}
__BIONIC_FORTIFY_INLINE
void* memset(void *s, int c, size_t n) {
return __builtin___memset_chk(s, c, n, __builtin_object_size (s, 0));
159c: 21ef movs r1, #239 ; 0xef
159e: 6ba2 ldr r2, [r4, #56] ; 0x38
15a0: 6be0 ldr r0, [r4, #60] ; 0x3c
15a2: f7ff ed2e blx 1000 <memset@plt>
/* TODO: remove debugging - poison memory */
memset(node->name, 0xef, node->namelen);
free(node->name);
15a6: 6be0 ldr r0, [r4, #60] ; 0x3c
15a8: f7ff ed18 blx fdc <free@plt>
free(node->actual_name);
15ac: 6c20 ldr r0, [r4, #64] ; 0x40
15ae: f7ff ed16 blx fdc <free@plt>
15b2: 4620 mov r0, r4
15b4: 21fc movs r1, #252 ; 0xfc
15b6: 2250 movs r2, #80 ; 0x50
15b8: f7ff ed22 blx 1000 <memset@plt>
memset(node, 0xfc, sizeof(*node));
free(node);
15bc: 4620 mov r0, r4
}
} else {
ERROR("Zero refcnt %p\n", node);
}
}
15be: e8bd 4010 ldmia.w sp!, {r4, lr}
/* TODO: remove debugging - poison memory */
memset(node->name, 0xef, node->namelen);
free(node->name);
free(node->actual_name);
memset(node, 0xfc, sizeof(*node));
free(node);
15c2: f001 be71 b.w 32a8 <sdcard_main+0x1fc>
}
} else {
ERROR("Zero refcnt %p\n", node);
15c6: 4806 ldr r0, [pc, #24] ; (15e0 <release_node_locked+0x5c>)
15c8: 4622 mov r2, r4
15ca: 4906 ldr r1, [pc, #24] ; (15e4 <release_node_locked+0x60>)
15cc: 5818 ldr r0, [r3, r0]
15ce: 4479 add r1, pc
15d0: 30a8 adds r0, #168 ; 0xa8
}
}
15d2: e8bd 4010 ldmia.w sp!, {r4, lr}
free(node->actual_name);
memset(node, 0xfc, sizeof(*node));
free(node);
}
} else {
ERROR("Zero refcnt %p\n", node);
15d6: f001 be6f b.w 32b8 <sdcard_main+0x20c>
15da: bd10 pop {r4, pc}
15dc: 0000392c .word 0x0000392c
15e0: fffffff0 .word 0xfffffff0
15e4: 000020e3 .word 0x000020e3
000015e8 <remove_node_from_parent_locked>:
parent->child = node;
acquire_node_locked(parent);
}
static void remove_node_from_parent_locked(struct node* node)
{
15e8: b510 push {r4, lr}
15ea: 4604 mov r4, r0
if (node->parent) {
15ec: 6b42 ldr r2, [r0, #52] ; 0x34
15ee: b18a cbz r2, 1614 <remove_node_from_parent_locked+0x2c>
if (node->parent->child == node) {
15f0: 6b13 ldr r3, [r2, #48] ; 0x30
15f2: 4283 cmp r3, r0
15f4: d103 bne.n 15fe <remove_node_from_parent_locked+0x16>
node->parent->child = node->parent->child->next;
15f6: 6ac0 ldr r0, [r0, #44] ; 0x2c
15f8: 6310 str r0, [r2, #48] ; 0x30
15fa: e005 b.n 1608 <remove_node_from_parent_locked+0x20>
} else {
struct node *node2;
node2 = node->parent->child;
while (node2->next != node)
node2 = node2->next;
15fc: 4603 mov r3, r0
if (node->parent->child == node) {
node->parent->child = node->parent->child->next;
} else {
struct node *node2;
node2 = node->parent->child;
while (node2->next != node)
15fe: 6ad8 ldr r0, [r3, #44] ; 0x2c
1600: 42a0 cmp r0, r4
1602: d1fb bne.n 15fc <remove_node_from_parent_locked+0x14>
node2 = node2->next;
node2->next = node->next;
1604: 6ae1 ldr r1, [r4, #44] ; 0x2c
1606: 62d9 str r1, [r3, #44] ; 0x2c
}
release_node_locked(node->parent);
1608: 6b60 ldr r0, [r4, #52] ; 0x34
160a: f7ff ffbb bl 1584 <release_node_locked>
node->parent = NULL;
160e: 2200 movs r2, #0
1610: 6362 str r2, [r4, #52] ; 0x34
node->next = NULL;
1612: 62e2 str r2, [r4, #44] ; 0x2c
1614: bd10 pop {r4, pc}
00001616 <get_caller_has_rw_locked>:
break;
}
}
/* Return if the calling UID holds sdcard_rw. */
static bool get_caller_has_rw_locked(struct fuse* fuse, const struct fuse_in_header *hdr) {
1616: b510 push {r4, lr}
1618: 4604 mov r4, r0
/* No additional permissions enforcement */
if (fuse->derive == DERIVE_NONE) {
161a: 6943 ldr r3, [r0, #20]
161c: b153 cbz r3, 1634 <get_caller_has_rw_locked+0x1e>
return true;
}
appid_t appid = multiuser_get_app_id(hdr->uid);
161e: 6988 ldr r0, [r1, #24]
return hashmapContainsKey(fuse->appid_with_rw, (void*) appid);
1620: f504 5483 add.w r4, r4, #4192 ; 0x1060
/* No additional permissions enforcement */
if (fuse->derive == DERIVE_NONE) {
return true;
}
appid_t appid = multiuser_get_app_id(hdr->uid);
1624: f7ff ecf2 blx 100c <multiuser_get_app_id@plt>
1628: 4601 mov r1, r0
return hashmapContainsKey(fuse->appid_with_rw, (void*) appid);
162a: 6960 ldr r0, [r4, #20]
}
162c: e8bd 4010 ldmia.w sp!, {r4, lr}
if (fuse->derive == DERIVE_NONE) {
return true;
}
appid_t appid = multiuser_get_app_id(hdr->uid);
return hashmapContainsKey(fuse->appid_with_rw, (void*) appid);
1630: f001 be4a b.w 32c8 <sdcard_main+0x21c>
}
1634: 2001 movs r0, #1
1636: bd10 pop {r4, pc}
00001638 <handle_statfs.isra.19>:
out.size = res;
fuse_reply(fuse, hdr->unique, &out, sizeof(out));
return NO_STATUS;
}
static int handle_statfs(struct fuse* fuse, struct fuse_handler* handler,
1638: 4b31 ldr r3, [pc, #196] ; (1700 <handle_statfs.isra.19+0xc8>)
163a: 4a32 ldr r2, [pc, #200] ; (1704 <handle_statfs.isra.19+0xcc>)
163c: e92d 42f0 stmdb sp!, {r4, r5, r6, r7, r9, lr}
1640: f5ad 5d85 sub.w sp, sp, #4256 ; 0x10a0
1644: 447b add r3, pc
1646: b086 sub sp, #24
1648: 4689 mov r9, r1
164a: f50d 5185 add.w r1, sp, #4256 ; 0x10a0
164e: 589c ldr r4, [r3, r2]
1650: 3114 adds r1, #20
1652: 4607 mov r7, r0
1654: 6823 ldr r3, [r4, #0]
1656: 600b str r3, [r1, #0]
char path[PATH_MAX];
struct statfs stat;
struct fuse_statfs_out out;
int res;
pthread_mutex_lock(&fuse->lock);
1658: f7ff ece4 blx 1024 <pthread_mutex_lock@plt>
TRACE("[%d] STATFS\n", handler->token);
res = get_node_path_locked(&fuse->root, path, sizeof(path));
165c: a92d add r1, sp, #180 ; 0xb4
165e: f44f 5280 mov.w r2, #4096 ; 0x1000
1662: f107 0020 add.w r0, r7, #32
1666: f7ff fee7 bl 1438 <get_node_path_locked>
166a: 4605 mov r5, r0
pthread_mutex_unlock(&fuse->lock);
166c: 4638 mov r0, r7
166e: f7ff ece0 blx 1030 <pthread_mutex_unlock@plt>
if (res < 0) {
1672: 2d00 cmp r5, #0
1674: db34 blt.n 16e0 <handle_statfs.isra.19+0xa8>
return -ENOENT;
}
if (statfs(fuse->root.name, &stat) < 0) {
1676: 6df8 ldr r0, [r7, #92] ; 0x5c
1678: a916 add r1, sp, #88 ; 0x58
167a: f7ff ece0 blx 103c <statfs@plt>
167e: 2800 cmp r0, #0
1680: da04 bge.n 168c <handle_statfs.isra.19+0x54>
return -errno;
1682: f7ff ecb8 blx ff4 <__errno@plt>
1686: 6800 ldr r0, [r0, #0]
1688: 4240 negs r0, r0
168a: e02b b.n 16e4 <handle_statfs.isra.19+0xac>
}
memset(&out, 0, sizeof(out));
168c: ae02 add r6, sp, #8
168e: 2550 movs r5, #80 ; 0x50
1690: 2100 movs r1, #0
1692: 462a mov r2, r5
1694: 4630 mov r0, r6
1696: f7ff ecb4 blx 1000 <memset@plt>
out.st.blocks = stat.f_blocks;
169a: e9dd 0118 ldrd r0, r1, [sp, #96] ; 0x60
out.st.bfree = stat.f_bfree;
169e: e9dd 231a ldrd r2, r3, [sp, #104] ; 0x68
}
if (statfs(fuse->root.name, &stat) < 0) {
return -errno;
}
memset(&out, 0, sizeof(out));
out.st.blocks = stat.f_blocks;
16a2: e9cd 0102 strd r0, r1, [sp, #8]
out.st.bfree = stat.f_bfree;
out.st.bavail = stat.f_bavail;
16a6: e9dd 011c ldrd r0, r1, [sp, #112] ; 0x70
if (statfs(fuse->root.name, &stat) < 0) {
return -errno;
}
memset(&out, 0, sizeof(out));
out.st.blocks = stat.f_blocks;
out.st.bfree = stat.f_bfree;
16aa: e9cd 2304 strd r2, r3, [sp, #16]
out.st.bavail = stat.f_bavail;
out.st.files = stat.f_files;
16ae: e9dd 231e ldrd r2, r3, [sp, #120] ; 0x78
return -errno;
}
memset(&out, 0, sizeof(out));
out.st.blocks = stat.f_blocks;
out.st.bfree = stat.f_bfree;
out.st.bavail = stat.f_bavail;
16b2: e9c6 0104 strd r0, r1, [r6, #16]
out.st.files = stat.f_files;
out.st.ffree = stat.f_ffree;
16b6: e9dd 0120 ldrd r0, r1, [sp, #128] ; 0x80
}
memset(&out, 0, sizeof(out));
out.st.blocks = stat.f_blocks;
out.st.bfree = stat.f_bfree;
out.st.bavail = stat.f_bavail;
out.st.files = stat.f_files;
16ba: e9c6 2306 strd r2, r3, [r6, #24]
out.st.ffree = stat.f_ffree;
out.st.bsize = stat.f_bsize;
16be: 9b17 ldr r3, [sp, #92] ; 0x5c
memset(&out, 0, sizeof(out));
out.st.blocks = stat.f_blocks;
out.st.bfree = stat.f_bfree;
out.st.bavail = stat.f_bavail;
out.st.files = stat.f_files;
out.st.ffree = stat.f_ffree;
16c0: e9c6 0108 strd r0, r1, [r6, #32]
out.st.bsize = stat.f_bsize;
out.st.namelen = stat.f_namelen;
out.st.frsize = stat.f_frsize;
fuse_reply(fuse, hdr->unique, &out, sizeof(out));
16c4: 4638 mov r0, r7
out.st.bavail = stat.f_bavail;
out.st.files = stat.f_files;
out.st.ffree = stat.f_ffree;
out.st.bsize = stat.f_bsize;
out.st.namelen = stat.f_namelen;
out.st.frsize = stat.f_frsize;
16c6: 9a25 ldr r2, [sp, #148] ; 0x94
out.st.bfree = stat.f_bfree;
out.st.bavail = stat.f_bavail;
out.st.files = stat.f_files;
out.st.ffree = stat.f_ffree;
out.st.bsize = stat.f_bsize;
out.st.namelen = stat.f_namelen;
16c8: 9924 ldr r1, [sp, #144] ; 0x90
out.st.blocks = stat.f_blocks;
out.st.bfree = stat.f_bfree;
out.st.bavail = stat.f_bavail;
out.st.files = stat.f_files;
out.st.ffree = stat.f_ffree;
out.st.bsize = stat.f_bsize;
16ca: 62b3 str r3, [r6, #40] ; 0x28
out.st.namelen = stat.f_namelen;
out.st.frsize = stat.f_frsize;
16cc: 6332 str r2, [r6, #48] ; 0x30
out.st.bfree = stat.f_bfree;
out.st.bavail = stat.f_bavail;
out.st.files = stat.f_files;
out.st.ffree = stat.f_ffree;
out.st.bsize = stat.f_bsize;
out.st.namelen = stat.f_namelen;
16ce: 62f1 str r1, [r6, #44] ; 0x2c
out.st.frsize = stat.f_frsize;
fuse_reply(fuse, hdr->unique, &out, sizeof(out));
16d0: e9d9 2302 ldrd r2, r3, [r9, #8]
16d4: 9600 str r6, [sp, #0]
16d6: 9501 str r5, [sp, #4]
16d8: f7ff ff26 bl 1528 <fuse_reply>
return NO_STATUS;
16dc: 2001 movs r0, #1
16de: e001 b.n 16e4 <handle_statfs.isra.19+0xac>
pthread_mutex_lock(&fuse->lock);
TRACE("[%d] STATFS\n", handler->token);
res = get_node_path_locked(&fuse->root, path, sizeof(path));
pthread_mutex_unlock(&fuse->lock);
if (res < 0) {
return -ENOENT;
16e0: f06f 0001 mvn.w r0, #1
out.st.bsize = stat.f_bsize;
out.st.namelen = stat.f_namelen;
out.st.frsize = stat.f_frsize;
fuse_reply(fuse, hdr->unique, &out, sizeof(out));
return NO_STATUS;
}
16e4: f50d 5385 add.w r3, sp, #4256 ; 0x10a0
16e8: 3314 adds r3, #20
16ea: 6819 ldr r1, [r3, #0]
16ec: 6822 ldr r2, [r4, #0]
16ee: 4291 cmp r1, r2
16f0: d001 beq.n 16f6 <handle_statfs.isra.19+0xbe>
16f2: f7ff ecaa blx 1048 <__stack_chk_fail@plt>
16f6: b02e add sp, #184 ; 0xb8
16f8: f50d 5d80 add.w sp, sp, #4096 ; 0x1000
16fc: e8bd 82f0 ldmia.w sp!, {r4, r5, r6, r7, r9, pc}
1700: 00003874 .word 0x00003874
1704: fffffff4 .word 0xfffffff4
00001708 <handle_readdir.isra.21>:
out.padding = 0;
fuse_reply(fuse, hdr->unique, &out, sizeof(out));
return NO_STATUS;
}
static int handle_readdir(struct fuse* fuse, struct fuse_handler* handler,
1708: 4b3b ldr r3, [pc, #236] ; (17f8 <handle_readdir.isra.21+0xf0>)
170a: e92d 4ff0 stmdb sp!, {r4, r5, r6, r7, r8, r9, sl, fp, lr}
170e: 4690 mov r8, r2
1710: 4a3a ldr r2, [pc, #232] ; (17fc <handle_readdir.isra.21+0xf4>)
1712: 460f mov r7, r1
1714: 447b add r3, pc
1716: f5ad 5d00 sub.w sp, sp, #8192 ; 0x2000
171a: b087 sub sp, #28
171c: 4605 mov r5, r0
171e: 5899 ldr r1, [r3, r2]
1720: f50d 5000 add.w r0, sp, #8192 ; 0x2000
1724: 3014 adds r0, #20
};
};
static inline void *id_to_ptr(__u64 nid)
{
return (void *) (uintptr_t) nid;
1726: f8d8 a000 ldr.w sl, [r8]
out.padding = 0;
fuse_reply(fuse, hdr->unique, &out, sizeof(out));
return NO_STATUS;
}
static int handle_readdir(struct fuse* fuse, struct fuse_handler* handler,
172a: 680b ldr r3, [r1, #0]
172c: 468b mov fp, r1
172e: 6003 str r3, [r0, #0]
struct dirent *de;
struct dirhandle *h = id_to_ptr(req->fh);
struct node* parent_node;
TRACE("[%d] READDIR %p\n", handler->token, h);
if (req->offset == 0) {
1730: e9d8 2302 ldrd r2, r3, [r8, #8]
1734: ea52 0003 orrs.w r0, r2, r3
1738: d103 bne.n 1742 <handle_readdir.isra.21+0x3a>
/* rewinddir() might have been called above us, so rewind here too */
TRACE("[%d] calling rewinddir()\n", handler->token);
rewinddir(h->d);
173a: f8da 0000 ldr.w r0, [sl]
173e: f7ff ec8a blx 1054 <rewinddir@plt>
skip:
de = readdir(h->d);
if (!de) {
return 0;
}
fde->ino = FUSE_UNKNOWN_INO;
1742: ac05 add r4, sp, #20
/* rewinddir() might have been called above us, so rewind here too */
TRACE("[%d] calling rewinddir()\n", handler->token);
rewinddir(h->d);
}
skip:
de = readdir(h->d);
1744: f8da 0000 ldr.w r0, [sl]
1748: f7ff ec8a blx 1060 <readdir@plt>
if (!de) {
174c: 2800 cmp r0, #0
174e: d03e beq.n 17ce <handle_readdir.isra.21+0xc6>
return 0;
}
fde->ino = FUSE_UNKNOWN_INO;
/* increment the offset so we can detect when rewinddir() seeks back to the beginning */
fde->off = req->offset + 1;
1750: eddf 0b27 vldr d16, [pc, #156] ; 17f0 <handle_readdir.isra.21+0xe8>
skip:
de = readdir(h->d);
if (!de) {
return 0;
}
fde->ino = FUSE_UNKNOWN_INO;
1754: 2100 movs r1, #0
/* increment the offset so we can detect when rewinddir() seeks back to the beginning */
fde->off = req->offset + 1;
1756: edd8 1b02 vldr d17, [r8, #8]
skip:
de = readdir(h->d);
if (!de) {
return 0;
}
fde->ino = FUSE_UNKNOWN_INO;
175a: f04f 36ff mov.w r6, #4294967295 ; 0xffffffff
175e: 6026 str r6, [r4, #0]
/* increment the offset so we can detect when rewinddir() seeks back to the beginning */
fde->off = req->offset + 1;
fde->type = de->d_type;
fde->namelen = strlen(de->d_name);
1760: f100 0913 add.w r9, r0, #19
skip:
de = readdir(h->d);
if (!de) {
return 0;
}
fde->ino = FUSE_UNKNOWN_INO;
1764: 6061 str r1, [r4, #4]
/* increment the offset so we can detect when rewinddir() seeks back to the beginning */
fde->off = req->offset + 1;
1766: ef31 08a0 vadd.i64 d0, d17, d16
176a: ec53 2b10 vmov r2, r3, d0
176e: ed84 0a02 vstr s0, [r4, #8]
1772: 60e3 str r3, [r4, #12]
fde->type = de->d_type;
1774: 7c83 ldrb r3, [r0, #18]
size_t bos = __bos(s);
#if !defined(__clang__)
// Compiler doesn't know destination size. Don't call __strlen_chk
if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
return __builtin_strlen(s);
1776: 4648 mov r0, r9
1778: 6163 str r3, [r4, #20]
177a: 9103 str r1, [sp, #12]
177c: f7ff ec16 blx fac <strlen@plt>
fde->namelen = strlen(de->d_name);
parent_node = lookup_node_by_id_locked(fuse, hdr->nodeid);
1780: e9d7 2304 ldrd r2, r3, [r7, #16]
1784: 4606 mov r6, r0
}
fde->ino = FUSE_UNKNOWN_INO;
/* increment the offset so we can detect when rewinddir() seeks back to the beginning */
fde->off = req->offset + 1;
fde->type = de->d_type;
fde->namelen = strlen(de->d_name);
1786: 6120 str r0, [r4, #16]
1788: 9803 ldr r0, [sp, #12]
return 0;
}
static struct node *lookup_node_by_id_locked(struct fuse *fuse, __u64 nid)
{
if (nid == FUSE_ROOT_ID) {
178a: 2b00 cmp r3, #0
178c: bf08 it eq
178e: 2a01 cmpeq r2, #1
fde->type = de->d_type;
fde->namelen = strlen(de->d_name);
parent_node = lookup_node_by_id_locked(fuse, hdr->nodeid);
if (!check_caller_access_to_name(fuse, hdr, parent_node, de->d_name, R_OK, false)) {
1790: 464b mov r3, r9
}
static struct node *lookup_node_by_id_locked(struct fuse *fuse, __u64 nid)
{
if (nid == FUSE_ROOT_ID) {
return &fuse->root;
1792: bf08 it eq
1794: f105 0220 addeq.w r2, r5, #32
fde->type = de->d_type;
fde->namelen = strlen(de->d_name);
parent_node = lookup_node_by_id_locked(fuse, hdr->nodeid);
if (!check_caller_access_to_name(fuse, hdr, parent_node, de->d_name, R_OK, false)) {
1798: 2104 movs r1, #4
179a: 9100 str r1, [sp, #0]
179c: 4639 mov r1, r7
179e: 9001 str r0, [sp, #4]
17a0: 4628 mov r0, r5
17a2: f7ff fe89 bl 14b8 <check_caller_access_to_name>
17a6: 2800 cmp r0, #0
17a8: d0cc beq.n 1744 <handle_readdir.isra.21+0x3c>
if (__builtin_constant_p(copy_amount) && (copy_amount > s_len)) {
__memcpy_src_size_error();
}
return __builtin___memcpy_chk(dest, src, copy_amount, d_len);
17aa: 1c72 adds r2, r6, #1
goto skip;
}
memcpy(fde->name, de->d_name, fde->namelen + 1);
fuse_reply(fuse, hdr->unique, fde,
FUSE_DIRENT_ALIGN(sizeof(struct fuse_dirent) + fde->namelen));
17ac: 361f adds r6, #31
17ae: 4649 mov r1, r9
17b0: f641 73e8 movw r3, #8168 ; 0x1fe8
17b4: a80b add r0, sp, #44 ; 0x2c
if (!check_caller_access_to_name(fuse, hdr, parent_node, de->d_name, R_OK, false)) {
goto skip;
}
memcpy(fde->name, de->d_name, fde->namelen + 1);
fuse_reply(fuse, hdr->unique, fde,
17b6: f026 0607 bic.w r6, r6, #7
17ba: f7ff ec58 blx 106c <__memcpy_chk@plt>
17be: e9d7 2302 ldrd r2, r3, [r7, #8]
17c2: 4628 mov r0, r5
17c4: 9400 str r4, [sp, #0]
17c6: 9601 str r6, [sp, #4]
17c8: f7ff feae bl 1528 <fuse_reply>
FUSE_DIRENT_ALIGN(sizeof(struct fuse_dirent) + fde->namelen));
return NO_STATUS;
17cc: 2001 movs r0, #1
}
17ce: f50d 5200 add.w r2, sp, #8192 ; 0x2000
17d2: 3214 adds r2, #20
17d4: 6811 ldr r1, [r2, #0]
17d6: f8db 3000 ldr.w r3, [fp]
17da: 4299 cmp r1, r3
17dc: d001 beq.n 17e2 <handle_readdir.isra.21+0xda>
17de: f7ff ec34 blx 1048 <__stack_chk_fail@plt>
17e2: b007 add sp, #28
17e4: f50d 5d00 add.w sp, sp, #8192 ; 0x2000
17e8: e8bd 8ff0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, sl, fp, pc}
17ec: f3af 8000 nop.w
17f0: 00000001 .word 0x00000001
17f4: 00000000 .word 0x00000000
17f8: 000037a4 .word 0x000037a4
17fc: fffffff4 .word 0xfffffff4
00001800 <touch.constprop.26>:
int owner_mode = s->st_mode & 0700;
int filtered_mode = node->mode & (owner_mode | (owner_mode >> 3) | (owner_mode >> 6));
attr->mode = (attr->mode & S_IFMT) | filtered_mode;
}
static int touch(char* path, mode_t mode) {
1800: b570 push {r4, r5, r6, lr}
if ((__builtin_va_arg_pack_len() == 0) && !__builtin_constant_p(flags)) {
return __open_2(pathname, flags);
}
return __open_real(pathname, flags, __builtin_va_arg_pack());
1802: f248 01c2 movw r1, #32962 ; 0x80c2
1806: 4d10 ldr r5, [pc, #64] ; (1848 <touch.constprop.26+0x48>)
1808: f44f 72da mov.w r2, #436 ; 0x1b4
180c: 4606 mov r6, r0
180e: f7ff ec34 blx 1078 <open@plt>
int fd = open(path, O_RDWR | O_CREAT | O_EXCL | O_NOFOLLOW, mode);
if (fd == -1) {
1812: 1c41 adds r1, r0, #1
int owner_mode = s->st_mode & 0700;
int filtered_mode = node->mode & (owner_mode | (owner_mode >> 3) | (owner_mode >> 6));
attr->mode = (attr->mode & S_IFMT) | filtered_mode;
}
static int touch(char* path, mode_t mode) {
1814: 447d add r5, pc
1816: 4604 mov r4, r0
int fd = open(path, O_RDWR | O_CREAT | O_EXCL | O_NOFOLLOW, mode);
if (fd == -1) {
1818: d112 bne.n 1840 <touch.constprop.26+0x40>
if (errno == EEXIST) {
181a: f7ff ebec blx ff4 <__errno@plt>
181e: 6803 ldr r3, [r0, #0]
1820: 2b11 cmp r3, #17
1822: d00f beq.n 1844 <touch.constprop.26+0x44>
return 0;
} else {
ERROR("Failed to open(%s): %s\n", path, strerror(errno));
1824: 6800 ldr r0, [r0, #0]
1826: f7ff ec2e blx 1084 <strerror@plt>
182a: 4a08 ldr r2, [pc, #32] ; (184c <touch.constprop.26+0x4c>)
182c: 4603 mov r3, r0
182e: 4908 ldr r1, [pc, #32] ; (1850 <touch.constprop.26+0x50>)
1830: 58a8 ldr r0, [r5, r2]
1832: 4632 mov r2, r6
1834: 4479 add r1, pc
1836: 30a8 adds r0, #168 ; 0xa8
1838: f7ff ebac blx f94 <fprintf@plt>
return -1;
183c: 4620 mov r0, r4
183e: bd70 pop {r4, r5, r6, pc}
}
}
close(fd);
1840: f7ff ec26 blx 1090 <close@plt>
return 0;
1844: 2000 movs r0, #0
}
1846: bd70 pop {r4, r5, r6, pc}
1848: 000036a4 .word 0x000036a4
184c: fffffff0 .word 0xfffffff0
1850: 00001e8d .word 0x00001e8d
00001854 <find_file_within.constprop.27>:
* the buffer to the path that the file would have, assuming the name were case-sensitive.
*
* Populates 'buf' with the path and returns the actual name (within 'buf') on success,
* or returns NULL if the path is too long for the provided buffer.
*/
static char* find_file_within(const char* path, const char* name,
1854: e92d 4ff8 stmdb sp!, {r3, r4, r5, r6, r7, r8, r9, sl, fp, lr}
1858: 460e mov r6, r1
185a: 469b mov fp, r3
185c: 4615 mov r5, r2
185e: 4680 mov r8, r0
size_t bos = __bos(s);
#if !defined(__clang__)
// Compiler doesn't know destination size. Don't call __strlen_chk
if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
return __builtin_strlen(s);
1860: f7ff eba4 blx fac <strlen@plt>
1864: 4681 mov r9, r0
1866: 4630 mov r0, r6
char* buf, size_t bufsize, int search)
{
size_t pathlen = strlen(path);
size_t namelen = strlen(name);
size_t childlen = pathlen + namelen + 1;
1868: f109 0401 add.w r4, r9, #1
* the buffer to the path that the file would have, assuming the name were case-sensitive.
*
* Populates 'buf' with the path and returns the actual name (within 'buf') on success,
* or returns NULL if the path is too long for the provided buffer.
*/
static char* find_file_within(const char* path, const char* name,
186c: f8df a09c ldr.w sl, [pc, #156] ; 190c <find_file_within.constprop.27+0xb8>
1870: f7ff eb9c blx fac <strlen@plt>
char* buf, size_t bufsize, int search)
{
size_t pathlen = strlen(path);
size_t namelen = strlen(name);
size_t childlen = pathlen + namelen + 1;
1874: 1823 adds r3, r4, r0
1876: 4607 mov r7, r0
char* actual;
if (bufsize <= childlen) {
1878: f5b3 5f80 cmp.w r3, #4096 ; 0x1000
* the buffer to the path that the file would have, assuming the name were case-sensitive.
*
* Populates 'buf' with the path and returns the actual name (within 'buf') on success,
* or returns NULL if the path is too long for the provided buffer.
*/
static char* find_file_within(const char* path, const char* name,
187c: 44fa add sl, pc
size_t pathlen = strlen(path);
size_t namelen = strlen(name);
size_t childlen = pathlen + namelen + 1;
char* actual;
if (bufsize <= childlen) {
187e: d240 bcs.n 1902 <find_file_within.constprop.27+0xae>
if (__builtin_constant_p(copy_amount) && (copy_amount > s_len)) {
__memcpy_src_size_error();
}
return __builtin___memcpy_chk(dest, src, copy_amount, d_len);
1880: 4641 mov r1, r8
1882: 464a mov r2, r9
1884: 4628 mov r0, r5
return NULL;
}
memcpy(buf, path, pathlen);
buf[pathlen] = '/';
actual = buf + pathlen + 1;
1886: 192c adds r4, r5, r4
1888: f7ff eb9c blx fc4 <memcpy@plt>
if (bufsize <= childlen) {
return NULL;
}
memcpy(buf, path, pathlen);
buf[pathlen] = '/';
188c: 202f movs r0, #47 ; 0x2f
188e: 4631 mov r1, r6
1890: f805 0009 strb.w r0, [r5, r9]
1894: 1c7a adds r2, r7, #1
1896: 4620 mov r0, r4
1898: f7ff eb94 blx fc4 <memcpy@plt>
actual = buf + pathlen + 1;
memcpy(actual, name, namelen + 1);
if (search && access(buf, F_OK)) {
189c: f1bb 0f00 cmp.w fp, #0
18a0: d030 beq.n 1904 <find_file_within.constprop.27+0xb0>
18a2: 4628 mov r0, r5
18a4: 2100 movs r1, #0
18a6: f7ff ebfa blx 109c <access@plt>
18aa: b358 cbz r0, 1904 <find_file_within.constprop.27+0xb0>
struct dirent* entry;
DIR* dir = opendir(path);
18ac: 4640 mov r0, r8
18ae: f7ff ebfc blx 10a8 <opendir@plt>
if (!dir) {
18b2: 4605 mov r5, r0
18b4: b9e0 cbnz r0, 18f0 <find_file_within.constprop.27+0x9c>
ERROR("opendir %s failed: %s\n", path, strerror(errno));
18b6: f7ff eb9e blx ff4 <__errno@plt>
18ba: 6800 ldr r0, [r0, #0]
18bc: f7ff ebe2 blx 1084 <strerror@plt>
18c0: 4a13 ldr r2, [pc, #76] ; (1910 <find_file_within.constprop.27+0xbc>)
18c2: 4603 mov r3, r0
18c4: 4913 ldr r1, [pc, #76] ; (1914 <find_file_within.constprop.27+0xc0>)
18c6: f85a 0002 ldr.w r0, [sl, r2]
18ca: 4642 mov r2, r8
18cc: 4479 add r1, pc
18ce: 30a8 adds r0, #168 ; 0xa8
18d0: f7ff eb60 blx f94 <fprintf@plt>
18d4: e016 b.n 1904 <find_file_within.constprop.27+0xb0>
return actual;
}
while ((entry = readdir(dir))) {
if (!strcasecmp(entry->d_name, name)) {
18d6: f100 0813 add.w r8, r0, #19
18da: 4631 mov r1, r6
18dc: 4640 mov r0, r8
18de: f7ff eb60 blx fa0 <strcasecmp@plt>
18e2: b928 cbnz r0, 18f0 <find_file_within.constprop.27+0x9c>
18e4: 4620 mov r0, r4
18e6: 4641 mov r1, r8
18e8: 463a mov r2, r7
18ea: f7ff eb6c blx fc4 <memcpy@plt>
18ee: e004 b.n 18fa <find_file_within.constprop.27+0xa6>
DIR* dir = opendir(path);
if (!dir) {
ERROR("opendir %s failed: %s\n", path, strerror(errno));
return actual;
}
while ((entry = readdir(dir))) {
18f0: 4628 mov r0, r5
18f2: f7ff ebb6 blx 1060 <readdir@plt>
18f6: 2800 cmp r0, #0
18f8: d1ed bne.n 18d6 <find_file_within.constprop.27+0x82>
/* we have a match - replace the name, don't need to copy the null again */
memcpy(actual, entry->d_name, namelen);
break;
}
}
closedir(dir);
18fa: 4628 mov r0, r5
18fc: f7ff ebda blx 10b4 <closedir@plt>
1900: e000 b.n 1904 <find_file_within.constprop.27+0xb0>
size_t namelen = strlen(name);
size_t childlen = pathlen + namelen + 1;
char* actual;
if (bufsize <= childlen) {
return NULL;
1902: 2400 movs r4, #0
}
}
closedir(dir);
}
return actual;
}
1904: 4620 mov r0, r4
1906: e8bd 8ff8 ldmia.w sp!, {r3, r4, r5, r6, r7, r8, r9, sl, fp, pc}
190a: bf00 nop
190c: 0000363c .word 0x0000363c
1910: fffffff0 .word 0xfffffff0
1914: 00001e0d .word 0x00001e0d
00001918 <lookup_node_and_path_by_id_locked.constprop.28>:
return 0;
}
static struct node *lookup_node_by_id_locked(struct fuse *fuse, __u64 nid)
{
if (nid == FUSE_ROOT_ID) {
1918: 2b00 cmp r3, #0
191a: bf08 it eq
191c: 2a01 cmpeq r2, #1
} else {
return id_to_ptr(nid);
}
}
static struct node* lookup_node_and_path_by_id_locked(struct fuse* fuse, __u64 nid,
191e: b510 push {r4, lr}
}
static struct node *lookup_node_by_id_locked(struct fuse *fuse, __u64 nid)
{
if (nid == FUSE_ROOT_ID) {
return &fuse->root;
1920: bf0c ite eq
1922: f100 0420 addeq.w r4, r0, #32
};
};
static inline void *id_to_ptr(__u64 nid)
{
return (void *) (uintptr_t) nid;
1926: 4614 movne r4, r2
static struct node* lookup_node_and_path_by_id_locked(struct fuse* fuse, __u64 nid,
char* buf, size_t bufsize)
{
struct node* node = lookup_node_by_id_locked(fuse, nid);
if (node && get_node_path_locked(node, buf, bufsize) < 0) {
1928: b13c cbz r4, 193a <lookup_node_and_path_by_id_locked.constprop.28+0x22>
192a: 4620 mov r0, r4
192c: 9902 ldr r1, [sp, #8]
192e: f44f 5280 mov.w r2, #4096 ; 0x1000
1932: f7ff fd81 bl 1438 <get_node_path_locked>
node = NULL;
1936: ea24 74e0 bic.w r4, r4, r0, asr #31
}
return node;
}
193a: 4620 mov r0, r4
193c: bd10 pop {r4, pc}
...
00001940 <handle_rmdir.isra.16>:
return -errno;
}
return 0;
}
static int handle_rmdir(struct fuse* fuse, struct fuse_handler* handler,
1940: 4b2e ldr r3, [pc, #184] ; (19fc <handle_rmdir.isra.16+0xbc>)
1942: e92d 47f0 stmdb sp!, {r4, r5, r6, r7, r8, r9, sl, lr}
1946: 4616 mov r6, r2
1948: 4a2d ldr r2, [pc, #180] ; (1a00 <handle_rmdir.isra.16+0xc0>)
194a: f5ad 5d00 sub.w sp, sp, #8192 ; 0x2000
194e: 447b add r3, pc
1950: b084 sub sp, #16
1952: 460d mov r5, r1
1954: f50d 5100 add.w r1, sp, #8192 ; 0x2000
1958: f853 8002 ldr.w r8, [r3, r2]
195c: 4604 mov r4, r0
195e: 310c adds r1, #12
char child_path[PATH_MAX];
pthread_mutex_lock(&fuse->lock);
has_rw = get_caller_has_rw_locked(fuse, hdr);
parent_node = lookup_node_and_path_by_id_locked(fuse, hdr->nodeid,
parent_path, sizeof(parent_path));
1960: f10d 0a0c add.w sl, sp, #12
return -errno;
}
return 0;
}
static int handle_rmdir(struct fuse* fuse, struct fuse_handler* handler,
1964: f8d8 3000 ldr.w r3, [r8]
1968: 600b str r3, [r1, #0]
bool has_rw;
struct node* parent_node;
char parent_path[PATH_MAX];
char child_path[PATH_MAX];
pthread_mutex_lock(&fuse->lock);
196a: f7ff eb5c blx 1024 <pthread_mutex_lock@plt>
has_rw = get_caller_has_rw_locked(fuse, hdr);
196e: 4629 mov r1, r5
1970: 4620 mov r0, r4
1972: f7ff fe50 bl 1616 <get_caller_has_rw_locked>
parent_node = lookup_node_and_path_by_id_locked(fuse, hdr->nodeid,
1976: e9d5 2304 ldrd r2, r3, [r5, #16]
struct node* parent_node;
char parent_path[PATH_MAX];
char child_path[PATH_MAX];
pthread_mutex_lock(&fuse->lock);
has_rw = get_caller_has_rw_locked(fuse, hdr);
197a: 4681 mov r9, r0
parent_node = lookup_node_and_path_by_id_locked(fuse, hdr->nodeid,
197c: f8cd a000 str.w sl, [sp]
1980: 4620 mov r0, r4
1982: f7ff ffc9 bl 1918 <lookup_node_and_path_by_id_locked.constprop.28>
1986: 4607 mov r7, r0
parent_path, sizeof(parent_path));
TRACE("[%d] RMDIR %s @ %llx (%s)\n", handler->token,
name, hdr->nodeid, parent_node ? parent_node->name : "?");
pthread_mutex_unlock(&fuse->lock);
1988: 4620 mov r0, r4
198a: f7ff eb52 blx 1030 <pthread_mutex_unlock@plt>
if (!parent_node || !find_file_within(parent_path, name,
198e: b917 cbnz r7, 1996 <handle_rmdir.isra.16+0x56>
child_path, sizeof(child_path), 1)) {
return -ENOENT;
1990: f06f 0001 mvn.w r0, #1
1994: e023 b.n 19de <handle_rmdir.isra.16+0x9e>
parent_path, sizeof(parent_path));
TRACE("[%d] RMDIR %s @ %llx (%s)\n", handler->token,
name, hdr->nodeid, parent_node ? parent_node->name : "?");
pthread_mutex_unlock(&fuse->lock);
if (!parent_node || !find_file_within(parent_path, name,
1996: f50d 5280 add.w r2, sp, #4096 ; 0x1000
199a: 4650 mov r0, sl
199c: 4631 mov r1, r6
199e: 320c adds r2, #12
19a0: 2301 movs r3, #1
19a2: f7ff ff57 bl 1854 <find_file_within.constprop.27>
19a6: 2800 cmp r0, #0
19a8: d0f2 beq.n 1990 <handle_rmdir.isra.16+0x50>
child_path, sizeof(child_path), 1)) {
return -ENOENT;
}
if (!check_caller_access_to_name(fuse, hdr, parent_node, name, W_OK, has_rw)) {
19aa: 2302 movs r3, #2
19ac: 4620 mov r0, r4
19ae: e88d 0208 stmia.w sp, {r3, r9}
19b2: 4629 mov r1, r5
19b4: 463a mov r2, r7
19b6: 4633 mov r3, r6
19b8: f7ff fd7e bl 14b8 <check_caller_access_to_name>
19bc: b158 cbz r0, 19d6 <handle_rmdir.isra.16+0x96>
return -EACCES;
}
if (rmdir(child_path) < 0) {
19be: f50d 5080 add.w r0, sp, #4096 ; 0x1000
19c2: 300c adds r0, #12
19c4: f7ff eb7c blx 10c0 <rmdir@plt>
19c8: 2800 cmp r0, #0
19ca: da07 bge.n 19dc <handle_rmdir.isra.16+0x9c>
return -errno;
19cc: f7ff eb12 blx ff4 <__errno@plt>
19d0: 6800 ldr r0, [r0, #0]
19d2: 4240 negs r0, r0
19d4: e003 b.n 19de <handle_rmdir.isra.16+0x9e>
if (!parent_node || !find_file_within(parent_path, name,
child_path, sizeof(child_path), 1)) {
return -ENOENT;
}
if (!check_caller_access_to_name(fuse, hdr, parent_node, name, W_OK, has_rw)) {
return -EACCES;
19d6: f06f 000c mvn.w r0, #12
19da: e000 b.n 19de <handle_rmdir.isra.16+0x9e>
}
if (rmdir(child_path) < 0) {
return -errno;
}
return 0;
19dc: 2000 movs r0, #0
}
19de: f50d 5200 add.w r2, sp, #8192 ; 0x2000
19e2: 320c adds r2, #12
19e4: 6811 ldr r1, [r2, #0]
19e6: f8d8 3000 ldr.w r3, [r8]
19ea: 4299 cmp r1, r3
19ec: d001 beq.n 19f2 <handle_rmdir.isra.16+0xb2>
19ee: f7ff eb2c blx 1048 <__stack_chk_fail@plt>
19f2: b004 add sp, #16
19f4: f50d 5d00 add.w sp, sp, #8192 ; 0x2000
19f8: e8bd 87f0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, sl, pc}
19fc: 0000356a .word 0x0000356a
1a00: fffffff4 .word 0xfffffff4
00001a04 <handle_unlink.isra.15>:
}
return fuse_reply_entry(fuse, hdr->unique, parent_node, name, actual_name, child_path);
}
static int handle_unlink(struct fuse* fuse, struct fuse_handler* handler,
1a04: 4b2e ldr r3, [pc, #184] ; (1ac0 <handle_unlink.isra.15+0xbc>)
1a06: e92d 47f0 stmdb sp!, {r4, r5, r6, r7, r8, r9, sl, lr}
1a0a: 4616 mov r6, r2
1a0c: 4a2d ldr r2, [pc, #180] ; (1ac4 <handle_unlink.isra.15+0xc0>)
1a0e: f5ad 5d00 sub.w sp, sp, #8192 ; 0x2000
1a12: 447b add r3, pc
1a14: b084 sub sp, #16
1a16: 460d mov r5, r1
1a18: f50d 5100 add.w r1, sp, #8192 ; 0x2000
1a1c: f853 8002 ldr.w r8, [r3, r2]
1a20: 4604 mov r4, r0
1a22: 310c adds r1, #12
char child_path[PATH_MAX];
pthread_mutex_lock(&fuse->lock);
has_rw = get_caller_has_rw_locked(fuse, hdr);
parent_node = lookup_node_and_path_by_id_locked(fuse, hdr->nodeid,
parent_path, sizeof(parent_path));
1a24: f10d 0a0c add.w sl, sp, #12
}
return fuse_reply_entry(fuse, hdr->unique, parent_node, name, actual_name, child_path);
}
static int handle_unlink(struct fuse* fuse, struct fuse_handler* handler,
1a28: f8d8 3000 ldr.w r3, [r8]
1a2c: 600b str r3, [r1, #0]
bool has_rw;
struct node* parent_node;
char parent_path[PATH_MAX];
char child_path[PATH_MAX];
pthread_mutex_lock(&fuse->lock);
1a2e: f7ff eafa blx 1024 <pthread_mutex_lock@plt>
has_rw = get_caller_has_rw_locked(fuse, hdr);
1a32: 4629 mov r1, r5
1a34: 4620 mov r0, r4
1a36: f7ff fdee bl 1616 <get_caller_has_rw_locked>
parent_node = lookup_node_and_path_by_id_locked(fuse, hdr->nodeid,
1a3a: e9d5 2304 ldrd r2, r3, [r5, #16]
struct node* parent_node;
char parent_path[PATH_MAX];
char child_path[PATH_MAX];
pthread_mutex_lock(&fuse->lock);
has_rw = get_caller_has_rw_locked(fuse, hdr);
1a3e: 4681 mov r9, r0
parent_node = lookup_node_and_path_by_id_locked(fuse, hdr->nodeid,
1a40: f8cd a000 str.w sl, [sp]
1a44: 4620 mov r0, r4
1a46: f7ff ff67 bl 1918 <lookup_node_and_path_by_id_locked.constprop.28>
1a4a: 4607 mov r7, r0
parent_path, sizeof(parent_path));
TRACE("[%d] UNLINK %s @ %llx (%s)\n", handler->token,
name, hdr->nodeid, parent_node ? parent_node->name : "?");
pthread_mutex_unlock(&fuse->lock);
1a4c: 4620 mov r0, r4
1a4e: f7ff eaf0 blx 1030 <pthread_mutex_unlock@plt>
if (!parent_node || !find_file_within(parent_path, name,
1a52: b917 cbnz r7, 1a5a <handle_unlink.isra.15+0x56>
child_path, sizeof(child_path), 1)) {
return -ENOENT;
1a54: f06f 0001 mvn.w r0, #1
1a58: e023 b.n 1aa2 <handle_unlink.isra.15+0x9e>
parent_path, sizeof(parent_path));
TRACE("[%d] UNLINK %s @ %llx (%s)\n", handler->token,
name, hdr->nodeid, parent_node ? parent_node->name : "?");
pthread_mutex_unlock(&fuse->lock);
if (!parent_node || !find_file_within(parent_path, name,
1a5a: f50d 5280 add.w r2, sp, #4096 ; 0x1000
1a5e: 4650 mov r0, sl
1a60: 4631 mov r1, r6
1a62: 320c adds r2, #12
1a64: 2301 movs r3, #1
1a66: f7ff fef5 bl 1854 <find_file_within.constprop.27>
1a6a: 2800 cmp r0, #0
1a6c: d0f2 beq.n 1a54 <handle_unlink.isra.15+0x50>
child_path, sizeof(child_path), 1)) {
return -ENOENT;
}
if (!check_caller_access_to_name(fuse, hdr, parent_node, name, W_OK, has_rw)) {
1a6e: 2302 movs r3, #2
1a70: 4620 mov r0, r4
1a72: e88d 0208 stmia.w sp, {r3, r9}
1a76: 4629 mov r1, r5
1a78: 463a mov r2, r7
1a7a: 4633 mov r3, r6
1a7c: f7ff fd1c bl 14b8 <check_caller_access_to_name>
1a80: b158 cbz r0, 1a9a <handle_unlink.isra.15+0x96>
return -EACCES;
}
if (unlink(child_path) < 0) {
1a82: f50d 5080 add.w r0, sp, #4096 ; 0x1000
1a86: 300c adds r0, #12
1a88: f7ff eb20 blx 10cc <unlink@plt>
1a8c: 2800 cmp r0, #0
1a8e: da07 bge.n 1aa0 <handle_unlink.isra.15+0x9c>
return -errno;
1a90: f7ff eab0 blx ff4 <__errno@plt>
1a94: 6800 ldr r0, [r0, #0]
1a96: 4240 negs r0, r0
1a98: e003 b.n 1aa2 <handle_unlink.isra.15+0x9e>
if (!parent_node || !find_file_within(parent_path, name,
child_path, sizeof(child_path), 1)) {
return -ENOENT;
}
if (!check_caller_access_to_name(fuse, hdr, parent_node, name, W_OK, has_rw)) {
return -EACCES;
1a9a: f06f 000c mvn.w r0, #12
1a9e: e000 b.n 1aa2 <handle_unlink.isra.15+0x9e>
}
if (unlink(child_path) < 0) {
return -errno;
}
return 0;
1aa0: 2000 movs r0, #0
}
1aa2: f50d 5200 add.w r2, sp, #8192 ; 0x2000
1aa6: 320c adds r2, #12
1aa8: 6811 ldr r1, [r2, #0]
1aaa: f8d8 3000 ldr.w r3, [r8]
1aae: 4299 cmp r1, r3
1ab0: d001 beq.n 1ab6 <handle_unlink.isra.15+0xb2>
1ab2: f7ff eaca blx 1048 <__stack_chk_fail@plt>
1ab6: b004 add sp, #16
1ab8: f50d 5d00 add.w sp, sp, #8192 ; 0x2000
1abc: e8bd 87f0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, sl, pc}
1ac0: 000034a6 .word 0x000034a6
1ac4: fffffff4 .word 0xfffffff4
00001ac8 <handle_open.isra.14>:
/* Probably O_RDRW, but treat as default to be safe */
return R_OK | W_OK;
}
}
static int handle_open(struct fuse* fuse, struct fuse_handler* handler,
1ac8: 4b3c ldr r3, [pc, #240] ; (1bbc <handle_open.isra.14+0xf4>)
1aca: e92d 4ff0 stmdb sp!, {r4, r5, r6, r7, r8, r9, sl, fp, lr}
1ace: 4616 mov r6, r2
1ad0: 4a3b ldr r2, [pc, #236] ; (1bc0 <handle_open.isra.14+0xf8>)
1ad2: f5ad 5d81 sub.w sp, sp, #4128 ; 0x1020
1ad6: 447b add r3, pc
1ad8: b081 sub sp, #4
1ada: 460d mov r5, r1
1adc: f50d 5180 add.w r1, sp, #4096 ; 0x1000
1ae0: 589f ldr r7, [r3, r2]
1ae2: 4604 mov r4, r0
1ae4: 311c adds r1, #28
struct fuse_open_out out;
struct handle *h;
pthread_mutex_lock(&fuse->lock);
has_rw = get_caller_has_rw_locked(fuse, hdr);
node = lookup_node_and_path_by_id_locked(fuse, hdr->nodeid, path, sizeof(path));
1ae6: f10d 091c add.w r9, sp, #28
/* Probably O_RDRW, but treat as default to be safe */
return R_OK | W_OK;
}
}
static int handle_open(struct fuse* fuse, struct fuse_handler* handler,
1aea: 683b ldr r3, [r7, #0]
1aec: 46b8 mov r8, r7
1aee: 600b str r3, [r1, #0]
struct node* node;
char path[PATH_MAX];
struct fuse_open_out out;
struct handle *h;
pthread_mutex_lock(&fuse->lock);
1af0: f7ff ea98 blx 1024 <pthread_mutex_lock@plt>
has_rw = get_caller_has_rw_locked(fuse, hdr);
1af4: 4629 mov r1, r5
1af6: 4620 mov r0, r4
1af8: f7ff fd8d bl 1616 <get_caller_has_rw_locked>
node = lookup_node_and_path_by_id_locked(fuse, hdr->nodeid, path, sizeof(path));
1afc: e9d5 2304 ldrd r2, r3, [r5, #16]
char path[PATH_MAX];
struct fuse_open_out out;
struct handle *h;
pthread_mutex_lock(&fuse->lock);
has_rw = get_caller_has_rw_locked(fuse, hdr);
1b00: 4682 mov sl, r0
node = lookup_node_and_path_by_id_locked(fuse, hdr->nodeid, path, sizeof(path));
1b02: f8cd 9000 str.w r9, [sp]
1b06: 4620 mov r0, r4
1b08: f7ff ff06 bl 1918 <lookup_node_and_path_by_id_locked.constprop.28>
1b0c: 4683 mov fp, r0
TRACE("[%d] OPEN 0%o @ %llx (%s)\n", handler->token,
req->flags, hdr->nodeid, node ? node->name : "?");
pthread_mutex_unlock(&fuse->lock);
1b0e: 4620 mov r0, r4
1b10: f7ff ea8e blx 1030 <pthread_mutex_unlock@plt>
if (!node) {
1b14: f1bb 0f00 cmp.w fp, #0
1b18: d038 beq.n 1b8c <handle_open.isra.14+0xc4>
return -ENOENT;
}
if (!check_caller_access_to_node(fuse, hdr, node,
open_flags_to_access_mode(req->flags), has_rw)) {
1b1a: 6837 ldr r7, [r6, #0]
pthread_mutex_unlock(&fuse->lock);
return res;
}
static int open_flags_to_access_mode(int open_flags) {
if ((open_flags & O_ACCMODE) == O_RDONLY) {
1b1c: f017 0003 ands.w r0, r7, #3
1b20: d004 beq.n 1b2c <handle_open.isra.14+0x64>
return R_OK;
} else if ((open_flags & O_ACCMODE) == O_WRONLY) {
return W_OK;
1b22: 2801 cmp r0, #1
1b24: bf14 ite ne
1b26: 2306 movne r3, #6
1b28: 2302 moveq r3, #2
1b2a: e000 b.n 1b2e <handle_open.isra.14+0x66>
return res;
}
static int open_flags_to_access_mode(int open_flags) {
if ((open_flags & O_ACCMODE) == O_RDONLY) {
return R_OK;
1b2c: 2304 movs r3, #4
return true;
}
static bool check_caller_access_to_node(struct fuse* fuse,
const struct fuse_in_header *hdr, const struct node* node, int mode, bool has_rw) {
return check_caller_access_to_name(fuse, hdr, node->parent, node->name, mode, has_rw);
1b2e: e88d 0408 stmia.w sp, {r3, sl}
1b32: 4620 mov r0, r4
1b34: 4629 mov r1, r5
1b36: f8db 2034 ldr.w r2, [fp, #52] ; 0x34
1b3a: f8db 303c ldr.w r3, [fp, #60] ; 0x3c
1b3e: f7ff fcbb bl 14b8 <check_caller_access_to_name>
pthread_mutex_unlock(&fuse->lock);
if (!node) {
return -ENOENT;
}
if (!check_caller_access_to_node(fuse, hdr, node,
1b42: b330 cbz r0, 1b92 <handle_open.isra.14+0xca>
open_flags_to_access_mode(req->flags), has_rw)) {
return -EACCES;
}
h = malloc(sizeof(*h));
1b44: 2004 movs r0, #4
1b46: f7ff eac8 blx 10d8 <malloc@plt>
if (!h) {
1b4a: 4606 mov r6, r0
1b4c: b320 cbz r0, 1b98 <handle_open.isra.14+0xd0>
if (__builtin_va_arg_pack_len() > 1) {
__creat_too_many_args(); // compile time error
}
if ((__builtin_va_arg_pack_len() == 0) && !__builtin_constant_p(flags)) {
return __open_2(pathname, flags);
1b4e: 4648 mov r0, r9
1b50: 4639 mov r1, r7
1b52: f7ff eac8 blx 10e4 <__open_2@plt>
return -ENOMEM;
}
TRACE("[%d] OPEN %s\n", handler->token, path);
h->fd = open(path, req->flags);
if (h->fd < 0) {
1b56: 2800 cmp r0, #0
h = malloc(sizeof(*h));
if (!h) {
return -ENOMEM;
}
TRACE("[%d] OPEN %s\n", handler->token, path);
h->fd = open(path, req->flags);
1b58: 6030 str r0, [r6, #0]
if (h->fd < 0) {
1b5a: da07 bge.n 1b6c <handle_open.isra.14+0xa4>
free(h);
1b5c: 4630 mov r0, r6
1b5e: f7ff ea3e blx fdc <free@plt>
return -errno;
1b62: f7ff ea48 blx ff4 <__errno@plt>
1b66: 6803 ldr r3, [r0, #0]
1b68: 4258 negs r0, r3
1b6a: e017 b.n 1b9c <handle_open.isra.14+0xd4>
return (void *) (uintptr_t) nid;
}
static inline __u64 ptr_to_id(void *ptr)
{
return (__u64) (uintptr_t) ptr;
1b6c: 2200 movs r2, #0
h->fd = open(path, req->flags);
if (h->fd < 0) {
free(h);
return -errno;
}
out.fh = ptr_to_id(h);
1b6e: a902 add r1, sp, #8
out.open_flags = 0;
out.padding = 0;
fuse_reply(fuse, hdr->unique, &out, sizeof(out));
1b70: 2010 movs r0, #16
return (void *) (uintptr_t) nid;
}
static inline __u64 ptr_to_id(void *ptr)
{
return (__u64) (uintptr_t) ptr;
1b72: 9203 str r2, [sp, #12]
if (h->fd < 0) {
free(h);
return -errno;
}
out.fh = ptr_to_id(h);
out.open_flags = 0;
1b74: 9204 str r2, [sp, #16]
out.padding = 0;
1b76: 9205 str r2, [sp, #20]
fuse_reply(fuse, hdr->unique, &out, sizeof(out));
1b78: 9001 str r0, [sp, #4]
1b7a: 4620 mov r0, r4
1b7c: e9d5 2302 ldrd r2, r3, [r5, #8]
1b80: 9100 str r1, [sp, #0]
return (void *) (uintptr_t) nid;
}
static inline __u64 ptr_to_id(void *ptr)
{
return (__u64) (uintptr_t) ptr;
1b82: 9602 str r6, [sp, #8]
return -errno;
}
out.fh = ptr_to_id(h);
out.open_flags = 0;
out.padding = 0;
fuse_reply(fuse, hdr->unique, &out, sizeof(out));
1b84: f7ff fcd0 bl 1528 <fuse_reply>
return NO_STATUS;
1b88: 2001 movs r0, #1
1b8a: e007 b.n 1b9c <handle_open.isra.14+0xd4>
TRACE("[%d] OPEN 0%o @ %llx (%s)\n", handler->token,
req->flags, hdr->nodeid, node ? node->name : "?");
pthread_mutex_unlock(&fuse->lock);
if (!node) {
return -ENOENT;
1b8c: f06f 0001 mvn.w r0, #1
1b90: e004 b.n 1b9c <handle_open.isra.14+0xd4>
}
if (!check_caller_access_to_node(fuse, hdr, node,
open_flags_to_access_mode(req->flags), has_rw)) {
return -EACCES;
1b92: f06f 000c mvn.w r0, #12
1b96: e001 b.n 1b9c <handle_open.isra.14+0xd4>
}
h = malloc(sizeof(*h));
if (!h) {
return -ENOMEM;
1b98: f06f 000b mvn.w r0, #11
out.fh = ptr_to_id(h);
out.open_flags = 0;
out.padding = 0;
fuse_reply(fuse, hdr->unique, &out, sizeof(out));
return NO_STATUS;
}
1b9c: f50d 5180 add.w r1, sp, #4096 ; 0x1000
1ba0: 311c adds r1, #28
1ba2: 680a ldr r2, [r1, #0]
1ba4: f8d8 3000 ldr.w r3, [r8]
1ba8: 429a cmp r2, r3
1baa: d001 beq.n 1bb0 <handle_open.isra.14+0xe8>
1bac: f7ff ea4c blx 1048 <__stack_chk_fail@plt>
1bb0: b009 add sp, #36 ; 0x24
1bb2: f50d 5d80 add.w sp, sp, #4096 ; 0x1000
1bb6: e8bd 8ff0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, sl, fp, pc}
1bba: bf00 nop
1bbc: 000033e2 .word 0x000033e2
1bc0: fffffff4 .word 0xfffffff4
00001bc4 <handle_opendir.isra.10>:
{
TRACE("[%d] FLUSH\n", handler->token);
return 0;
}
static int handle_opendir(struct fuse* fuse, struct fuse_handler* handler,
1bc4: 4b32 ldr r3, [pc, #200] ; (1c90 <handle_opendir.isra.10+0xcc>)
1bc6: 4a33 ldr r2, [pc, #204] ; (1c94 <handle_opendir.isra.10+0xd0>)
1bc8: e92d 47f0 stmdb sp!, {r4, r5, r6, r7, r8, r9, sl, lr}
1bcc: f5ad 5d81 sub.w sp, sp, #4128 ; 0x1020
1bd0: 447b add r3, pc
1bd2: 460f mov r7, r1
1bd4: f50d 5180 add.w r1, sp, #4096 ; 0x1000
1bd8: 4604 mov r4, r0
1bda: 589d ldr r5, [r3, r2]
1bdc: 311c adds r1, #28
char path[PATH_MAX];
struct fuse_open_out out;
struct dirhandle *h;
pthread_mutex_lock(&fuse->lock);
node = lookup_node_and_path_by_id_locked(fuse, hdr->nodeid, path, sizeof(path));
1bde: f10d 091c add.w r9, sp, #28
{
TRACE("[%d] FLUSH\n", handler->token);
return 0;
}
static int handle_opendir(struct fuse* fuse, struct fuse_handler* handler,
1be2: 682b ldr r3, [r5, #0]
1be4: 46a8 mov r8, r5
1be6: 600b str r3, [r1, #0]
struct node* node;
char path[PATH_MAX];
struct fuse_open_out out;
struct dirhandle *h;
pthread_mutex_lock(&fuse->lock);
1be8: f7ff ea1c blx 1024 <pthread_mutex_lock@plt>
node = lookup_node_and_path_by_id_locked(fuse, hdr->nodeid, path, sizeof(path));
1bec: e9d7 2304 ldrd r2, r3, [r7, #16]
1bf0: 4620 mov r0, r4
1bf2: f8cd 9000 str.w r9, [sp]
1bf6: f7ff fe8f bl 1918 <lookup_node_and_path_by_id_locked.constprop.28>
1bfa: 4606 mov r6, r0
TRACE("[%d] OPENDIR @ %llx (%s)\n", handler->token,
hdr->nodeid, node ? node->name : "?");
pthread_mutex_unlock(&fuse->lock);
1bfc: 4620 mov r0, r4
1bfe: f7ff ea18 blx 1030 <pthread_mutex_unlock@plt>
if (!node) {
1c02: 2e00 cmp r6, #0
1c04: d02d beq.n 1c62 <handle_opendir.isra.10+0x9e>
return true;
}
static bool check_caller_access_to_node(struct fuse* fuse,
const struct fuse_in_header *hdr, const struct node* node, int mode, bool has_rw) {
return check_caller_access_to_name(fuse, hdr, node->parent, node->name, mode, has_rw);
1c06: f04f 0a04 mov.w sl, #4
1c0a: 2500 movs r5, #0
1c0c: f8cd a000 str.w sl, [sp]
1c10: 4620 mov r0, r4
1c12: 9501 str r5, [sp, #4]
1c14: 4639 mov r1, r7
1c16: 6b72 ldr r2, [r6, #52] ; 0x34
1c18: 6bf3 ldr r3, [r6, #60] ; 0x3c
1c1a: f7ff fc4d bl 14b8 <check_caller_access_to_name>
pthread_mutex_unlock(&fuse->lock);
if (!node) {
return -ENOENT;
}
if (!check_caller_access_to_node(fuse, hdr, node, R_OK, false)) {
1c1e: b318 cbz r0, 1c68 <handle_opendir.isra.10+0xa4>
return -EACCES;
}
h = malloc(sizeof(*h));
1c20: 4650 mov r0, sl
1c22: f7ff ea5a blx 10d8 <malloc@plt>
if (!h) {
1c26: 4606 mov r6, r0
1c28: b308 cbz r0, 1c6e <handle_opendir.isra.10+0xaa>
return -ENOMEM;
}
TRACE("[%d] OPENDIR %s\n", handler->token, path);
h->d = opendir(path);
1c2a: 4648 mov r0, r9
1c2c: f7ff ea3c blx 10a8 <opendir@plt>
1c30: 6030 str r0, [r6, #0]
if (!h->d) {
1c32: b938 cbnz r0, 1c44 <handle_opendir.isra.10+0x80>
free(h);
1c34: 4630 mov r0, r6
1c36: f7ff e9d2 blx fdc <free@plt>
return -errno;
1c3a: f7ff e9dc blx ff4 <__errno@plt>
1c3e: 6802 ldr r2, [r0, #0]
1c40: 4250 negs r0, r2
1c42: e016 b.n 1c72 <handle_opendir.isra.10+0xae>
}
out.fh = ptr_to_id(h);
1c44: a802 add r0, sp, #8
out.open_flags = 0;
out.padding = 0;
fuse_reply(fuse, hdr->unique, &out, sizeof(out));
1c46: 2110 movs r1, #16
1c48: e9d7 2302 ldrd r2, r3, [r7, #8]
1c4c: 9000 str r0, [sp, #0]
1c4e: 4620 mov r0, r4
1c50: 9101 str r1, [sp, #4]
return (void *) (uintptr_t) nid;
}
static inline __u64 ptr_to_id(void *ptr)
{
return (__u64) (uintptr_t) ptr;
1c52: 9602 str r6, [sp, #8]
1c54: 9503 str r5, [sp, #12]
if (!h->d) {
free(h);
return -errno;
}
out.fh = ptr_to_id(h);
out.open_flags = 0;
1c56: 9504 str r5, [sp, #16]
out.padding = 0;
1c58: 9505 str r5, [sp, #20]
fuse_reply(fuse, hdr->unique, &out, sizeof(out));
1c5a: f7ff fc65 bl 1528 <fuse_reply>
return NO_STATUS;
1c5e: 2001 movs r0, #1
1c60: e007 b.n 1c72 <handle_opendir.isra.10+0xae>
TRACE("[%d] OPENDIR @ %llx (%s)\n", handler->token,
hdr->nodeid, node ? node->name : "?");
pthread_mutex_unlock(&fuse->lock);
if (!node) {
return -ENOENT;
1c62: f06f 0001 mvn.w r0, #1
1c66: e004 b.n 1c72 <handle_opendir.isra.10+0xae>
}
if (!check_caller_access_to_node(fuse, hdr, node, R_OK, false)) {
return -EACCES;
1c68: f06f 000c mvn.w r0, #12
1c6c: e001 b.n 1c72 <handle_opendir.isra.10+0xae>
}
h = malloc(sizeof(*h));
if (!h) {
return -ENOMEM;
1c6e: f06f 000b mvn.w r0, #11
out.fh = ptr_to_id(h);
out.open_flags = 0;
out.padding = 0;
fuse_reply(fuse, hdr->unique, &out, sizeof(out));
return NO_STATUS;
}
1c72: f50d 5380 add.w r3, sp, #4096 ; 0x1000
1c76: 331c adds r3, #28
1c78: 6819 ldr r1, [r3, #0]
1c7a: f8d8 2000 ldr.w r2, [r8]
1c7e: 4291 cmp r1, r2
1c80: d001 beq.n 1c86 <handle_opendir.isra.10+0xc2>
1c82: f7ff e9e2 blx 1048 <__stack_chk_fail@plt>
1c86: b008 add sp, #32
1c88: f50d 5d80 add.w sp, sp, #4096 ; 0x1000
1c8c: e8bd 87f0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, sl, pc}
1c90: 000032e8 .word 0x000032e8
1c94: fffffff4 .word 0xfffffff4
00001c98 <fuse_reply_attr>:
return NO_STATUS;
}
static int fuse_reply_attr(struct fuse* fuse, __u64 unique, const struct node* node,
const char* path)
{
1c98: e92d 43f0 stmdb sp!, {r4, r5, r6, r7, r8, r9, lr}
1c9c: b0b7 sub sp, #220 ; 0xdc
1c9e: 4681 mov r9, r0
struct fuse_attr_out out;
struct stat s;
if (lstat(path, &s) < 0) {
1ca0: a91c add r1, sp, #112 ; 0x70
return NO_STATUS;
}
static int fuse_reply_attr(struct fuse* fuse, __u64 unique, const struct node* node,
const char* path)
{
1ca2: 4614 mov r4, r2
1ca4: 461d mov r5, r3
struct fuse_attr_out out;
struct stat s;
if (lstat(path, &s) < 0) {
1ca6: 983f ldr r0, [sp, #252] ; 0xfc
return NO_STATUS;
}
static int fuse_reply_attr(struct fuse* fuse, __u64 unique, const struct node* node,
const char* path)
{
1ca8: f8dd 80f8 ldr.w r8, [sp, #248] ; 0xf8
struct fuse_attr_out out;
struct stat s;
if (lstat(path, &s) < 0) {
1cac: f7ff ea20 blx 10f0 <lstat@plt>
1cb0: 2800 cmp r0, #0
1cb2: da04 bge.n 1cbe <fuse_reply_attr+0x26>
return -errno;
1cb4: f7ff e99e blx ff4 <__errno@plt>
1cb8: 6803 ldr r3, [r0, #0]
1cba: 4258 negs r0, r3
1cbc: e047 b.n 1d4e <fuse_reply_attr+0xb6>
}
memset(&out, 0, sizeof(out));
1cbe: af02 add r7, sp, #8
return __builtin___strncat_chk(dest, src, n, __bos(dest));
}
__BIONIC_FORTIFY_INLINE
void* memset(void *s, int c, size_t n) {
return __builtin___memset_chk(s, c, n, __builtin_object_size (s, 0));
1cc0: 2668 movs r6, #104 ; 0x68
1cc2: 2100 movs r1, #0
1cc4: 4632 mov r2, r6
1cc6: 4638 mov r0, r7
1cc8: f7ff e99a blx 1000 <memset@plt>
return actual;
}
static void attr_from_stat(struct fuse_attr *attr, const struct stat *s, const struct node* node)
{
attr->ino = node->nid;
1ccc: e9d8 2302 ldrd r2, r3, [r8, #8]
attr->size = s->st_size;
1cd0: e9dd 0128 ldrd r0, r1, [sp, #160] ; 0xa0
return actual;
}
static void attr_from_stat(struct fuse_attr *attr, const struct stat *s, const struct node* node)
{
attr->ino = node->nid;
1cd4: e9cd 2306 strd r2, r3, [sp, #24]
attr->size = s->st_size;
attr->blocks = s->st_blocks;
1cd8: e9dd 232c ldrd r2, r3, [sp, #176] ; 0xb0
}
static void attr_from_stat(struct fuse_attr *attr, const struct stat *s, const struct node* node)
{
attr->ino = node->nid;
attr->size = s->st_size;
1cdc: e9cd 0108 strd r0, r1, [sp, #32]
attr->blocks = s->st_blocks;
attr->atime = s->st_atime;
1ce0: 992e ldr r1, [sp, #184] ; 0xb8
static void attr_from_stat(struct fuse_attr *attr, const struct stat *s, const struct node* node)
{
attr->ino = node->nid;
attr->size = s->st_size;
attr->blocks = s->st_blocks;
1ce2: e9cd 230a strd r2, r3, [sp, #40] ; 0x28
attr->atime = s->st_atime;
1ce6: 2300 movs r3, #0
attr->mtime = s->st_mtime;
1ce8: 9830 ldr r0, [sp, #192] ; 0xc0
attr->ctime = s->st_ctime;
1cea: 9a32 ldr r2, [sp, #200] ; 0xc8
static void attr_from_stat(struct fuse_attr *attr, const struct stat *s, const struct node* node)
{
attr->ino = node->nid;
attr->size = s->st_size;
attr->blocks = s->st_blocks;
attr->atime = s->st_atime;
1cec: 930d str r3, [sp, #52] ; 0x34
attr->mtime = s->st_mtime;
1cee: 930f str r3, [sp, #60] ; 0x3c
attr->ctime = s->st_ctime;
1cf0: 9311 str r3, [sp, #68] ; 0x44
attr->atimensec = s->st_atime_nsec;
1cf2: 9b2f ldr r3, [sp, #188] ; 0xbc
static void attr_from_stat(struct fuse_attr *attr, const struct stat *s, const struct node* node)
{
attr->ino = node->nid;
attr->size = s->st_size;
attr->blocks = s->st_blocks;
attr->atime = s->st_atime;
1cf4: 910c str r1, [sp, #48] ; 0x30
attr->mtime = s->st_mtime;
attr->ctime = s->st_ctime;
attr->atimensec = s->st_atime_nsec;
attr->mtimensec = s->st_mtime_nsec;
1cf6: 9931 ldr r1, [sp, #196] ; 0xc4
{
attr->ino = node->nid;
attr->size = s->st_size;
attr->blocks = s->st_blocks;
attr->atime = s->st_atime;
attr->mtime = s->st_mtime;
1cf8: 900e str r0, [sp, #56] ; 0x38
attr->ctime = s->st_ctime;
1cfa: 9210 str r2, [sp, #64] ; 0x40
attr->atimensec = s->st_atime_nsec;
attr->mtimensec = s->st_mtime_nsec;
attr->ctimensec = s->st_ctime_nsec;
1cfc: 9833 ldr r0, [sp, #204] ; 0xcc
attr->mode = s->st_mode;
1cfe: 9a20 ldr r2, [sp, #128] ; 0x80
attr->size = s->st_size;
attr->blocks = s->st_blocks;
attr->atime = s->st_atime;
attr->mtime = s->st_mtime;
attr->ctime = s->st_ctime;
attr->atimensec = s->st_atime_nsec;
1d00: 9312 str r3, [sp, #72] ; 0x48
attr->mtimensec = s->st_mtime_nsec;
attr->ctimensec = s->st_ctime_nsec;
attr->mode = s->st_mode;
attr->nlink = s->st_nlink;
1d02: 9b21 ldr r3, [sp, #132] ; 0x84
attr->blocks = s->st_blocks;
attr->atime = s->st_atime;
attr->mtime = s->st_mtime;
attr->ctime = s->st_ctime;
attr->atimensec = s->st_atime_nsec;
attr->mtimensec = s->st_mtime_nsec;
1d04: 9113 str r1, [sp, #76] ; 0x4c
attr->ctimensec = s->st_ctime_nsec;
attr->mode = s->st_mode;
attr->nlink = s->st_nlink;
attr->uid = node->uid;
1d06: f8d8 1020 ldr.w r1, [r8, #32]
attr->atime = s->st_atime;
attr->mtime = s->st_mtime;
attr->ctime = s->st_ctime;
attr->atimensec = s->st_atime_nsec;
attr->mtimensec = s->st_mtime_nsec;
attr->ctimensec = s->st_ctime_nsec;
1d0a: 9014 str r0, [sp, #80] ; 0x50
attr->mode = s->st_mode;
attr->nlink = s->st_nlink;
1d0c: 9316 str r3, [sp, #88] ; 0x58
attr->uid = node->uid;
attr->gid = node->gid;
/* Filter requested mode based on underlying file, and
* pass through file type. */
int owner_mode = s->st_mode & 0700;
1d0e: f402 73e0 and.w r3, r2, #448 ; 0x1c0
attr->ctimensec = s->st_ctime_nsec;
attr->mode = s->st_mode;
attr->nlink = s->st_nlink;
attr->uid = node->uid;
attr->gid = node->gid;
1d12: f8d8 0024 ldr.w r0, [r8, #36] ; 0x24
/* Filter requested mode based on underlying file, and
* pass through file type. */
int owner_mode = s->st_mode & 0700;
int filtered_mode = node->mode & (owner_mode | (owner_mode >> 3) | (owner_mode >> 6));
attr->mode = (attr->mode & S_IFMT) | filtered_mode;
1d16: f402 4270 and.w r2, r2, #61440 ; 0xf000
attr->mtimensec = s->st_mtime_nsec;
attr->ctimensec = s->st_ctime_nsec;
attr->mode = s->st_mode;
attr->nlink = s->st_nlink;
attr->uid = node->uid;
1d1a: 9117 str r1, [sp, #92] ; 0x5c
attr->gid = node->gid;
/* Filter requested mode based on underlying file, and
* pass through file type. */
int owner_mode = s->st_mode & 0700;
int filtered_mode = node->mode & (owner_mode | (owner_mode >> 3) | (owner_mode >> 6));
1d1c: 1199 asrs r1, r3, #6
attr->ctimensec = s->st_ctime_nsec;
attr->mode = s->st_mode;
attr->nlink = s->st_nlink;
attr->uid = node->uid;
attr->gid = node->gid;
1d1e: 9018 str r0, [sp, #96] ; 0x60
/* Filter requested mode based on underlying file, and
* pass through file type. */
int owner_mode = s->st_mode & 0700;
int filtered_mode = node->mode & (owner_mode | (owner_mode >> 3) | (owner_mode >> 6));
1d20: ea41 00d3 orr.w r0, r1, r3, lsr #3
1d24: ea40 0c03 orr.w ip, r0, r3
1d28: f8b8 3028 ldrh.w r3, [r8, #40] ; 0x28
return -errno;
}
memset(&out, 0, sizeof(out));
attr_from_stat(&out.attr, &s, node);
out.attr_valid = 10;
fuse_reply(fuse, unique, &out, sizeof(out));
1d2c: 9700 str r7, [sp, #0]
1d2e: 9601 str r6, [sp, #4]
attr->gid = node->gid;
/* Filter requested mode based on underlying file, and
* pass through file type. */
int owner_mode = s->st_mode & 0700;
int filtered_mode = node->mode & (owner_mode | (owner_mode >> 3) | (owner_mode >> 6));
1d30: ea0c 0103 and.w r1, ip, r3
if (lstat(path, &s) < 0) {
return -errno;
}
memset(&out, 0, sizeof(out));
attr_from_stat(&out.attr, &s, node);
out.attr_valid = 10;
1d34: 2300 movs r3, #0
/* Filter requested mode based on underlying file, and
* pass through file type. */
int owner_mode = s->st_mode & 0700;
int filtered_mode = node->mode & (owner_mode | (owner_mode >> 3) | (owner_mode >> 6));
attr->mode = (attr->mode & S_IFMT) | filtered_mode;
1d36: ea41 0002 orr.w r0, r1, r2
if (lstat(path, &s) < 0) {
return -errno;
}
memset(&out, 0, sizeof(out));
attr_from_stat(&out.attr, &s, node);
out.attr_valid = 10;
1d3a: 220a movs r2, #10
1d3c: e9cd 2302 strd r2, r3, [sp, #8]
fuse_reply(fuse, unique, &out, sizeof(out));
1d40: 4622 mov r2, r4
/* Filter requested mode based on underlying file, and
* pass through file type. */
int owner_mode = s->st_mode & 0700;
int filtered_mode = node->mode & (owner_mode | (owner_mode >> 3) | (owner_mode >> 6));
attr->mode = (attr->mode & S_IFMT) | filtered_mode;
1d42: 9015 str r0, [sp, #84] ; 0x54
return -errno;
}
memset(&out, 0, sizeof(out));
attr_from_stat(&out.attr, &s, node);
out.attr_valid = 10;
fuse_reply(fuse, unique, &out, sizeof(out));
1d44: 462b mov r3, r5
1d46: 4648 mov r0, r9
1d48: f7ff fbee bl 1528 <fuse_reply>
return NO_STATUS;
1d4c: 2001 movs r0, #1
}
1d4e: b037 add sp, #220 ; 0xdc
1d50: e8bd 83f0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, pc}
00001d54 <handle_getattr.isra.5>:
}
pthread_mutex_unlock(&fuse->lock);
return NO_STATUS; /* no reply */
}
static int handle_getattr(struct fuse* fuse, struct fuse_handler* handler,
1d54: 4b23 ldr r3, [pc, #140] ; (1de4 <handle_getattr.isra.5+0x90>)
1d56: 4a24 ldr r2, [pc, #144] ; (1de8 <handle_getattr.isra.5+0x94>)
1d58: e92d 41f0 stmdb sp!, {r4, r5, r6, r7, r8, lr}
1d5c: f5ad 5d80 sub.w sp, sp, #4096 ; 0x1000
1d60: 447b add r3, pc
1d62: b084 sub sp, #16
1d64: 460f mov r7, r1
1d66: f50d 5180 add.w r1, sp, #4096 ; 0x1000
1d6a: f853 8002 ldr.w r8, [r3, r2]
1d6e: 4605 mov r5, r0
1d70: 310c adds r1, #12
{
struct node* node;
char path[PATH_MAX];
pthread_mutex_lock(&fuse->lock);
node = lookup_node_and_path_by_id_locked(fuse, hdr->nodeid, path, sizeof(path));
1d72: ac03 add r4, sp, #12
}
pthread_mutex_unlock(&fuse->lock);
return NO_STATUS; /* no reply */
}
static int handle_getattr(struct fuse* fuse, struct fuse_handler* handler,
1d74: f8d8 3000 ldr.w r3, [r8]
1d78: 600b str r3, [r1, #0]
const struct fuse_in_header *hdr, const struct fuse_getattr_in *req)
{
struct node* node;
char path[PATH_MAX];
pthread_mutex_lock(&fuse->lock);
1d7a: f7ff e954 blx 1024 <pthread_mutex_lock@plt>
node = lookup_node_and_path_by_id_locked(fuse, hdr->nodeid, path, sizeof(path));
1d7e: e9d7 2304 ldrd r2, r3, [r7, #16]
1d82: 4628 mov r0, r5
1d84: 9400 str r4, [sp, #0]
1d86: f7ff fdc7 bl 1918 <lookup_node_and_path_by_id_locked.constprop.28>
1d8a: 4606 mov r6, r0
TRACE("[%d] GETATTR flags=%x fh=%llx @ %llx (%s)\n", handler->token,
req->getattr_flags, req->fh, hdr->nodeid, node ? node->name : "?");
pthread_mutex_unlock(&fuse->lock);
1d8c: 4628 mov r0, r5
1d8e: f7ff e950 blx 1030 <pthread_mutex_unlock@plt>
if (!node) {
1d92: b196 cbz r6, 1dba <handle_getattr.isra.5+0x66>
return true;
}
static bool check_caller_access_to_node(struct fuse* fuse,
const struct fuse_in_header *hdr, const struct node* node, int mode, bool has_rw) {
return check_caller_access_to_name(fuse, hdr, node->parent, node->name, mode, has_rw);
1d94: 2004 movs r0, #4
1d96: 2300 movs r3, #0
1d98: e88d 0009 stmia.w sp, {r0, r3}
1d9c: 4639 mov r1, r7
1d9e: 4628 mov r0, r5
1da0: 6b72 ldr r2, [r6, #52] ; 0x34
1da2: 6bf3 ldr r3, [r6, #60] ; 0x3c
1da4: f7ff fb88 bl 14b8 <check_caller_access_to_name>
pthread_mutex_unlock(&fuse->lock);
if (!node) {
return -ENOENT;
}
if (!check_caller_access_to_node(fuse, hdr, node, R_OK, false)) {
1da8: b150 cbz r0, 1dc0 <handle_getattr.isra.5+0x6c>
return -EACCES;
}
return fuse_reply_attr(fuse, hdr->unique, node, path);
1daa: e9d7 2302 ldrd r2, r3, [r7, #8]
1dae: 4628 mov r0, r5
1db0: 9600 str r6, [sp, #0]
1db2: 9401 str r4, [sp, #4]
1db4: f7ff ff70 bl 1c98 <fuse_reply_attr>
1db8: e004 b.n 1dc4 <handle_getattr.isra.5+0x70>
TRACE("[%d] GETATTR flags=%x fh=%llx @ %llx (%s)\n", handler->token,
req->getattr_flags, req->fh, hdr->nodeid, node ? node->name : "?");
pthread_mutex_unlock(&fuse->lock);
if (!node) {
return -ENOENT;
1dba: f06f 0001 mvn.w r0, #1
1dbe: e001 b.n 1dc4 <handle_getattr.isra.5+0x70>
}
if (!check_caller_access_to_node(fuse, hdr, node, R_OK, false)) {
return -EACCES;
1dc0: f06f 000c mvn.w r0, #12
}
return fuse_reply_attr(fuse, hdr->unique, node, path);
}
1dc4: f50d 5280 add.w r2, sp, #4096 ; 0x1000
1dc8: 320c adds r2, #12
1dca: 6811 ldr r1, [r2, #0]
1dcc: f8d8 3000 ldr.w r3, [r8]
1dd0: 4299 cmp r1, r3
1dd2: d001 beq.n 1dd8 <handle_getattr.isra.5+0x84>
1dd4: f7ff e938 blx 1048 <__stack_chk_fail@plt>
1dd8: b004 add sp, #16
1dda: f50d 5d80 add.w sp, sp, #4096 ; 0x1000
1dde: e8bd 81f0 ldmia.w sp!, {r4, r5, r6, r7, r8, pc}
1de2: bf00 nop
1de4: 00003158 .word 0x00003158
1de8: fffffff4 .word 0xfffffff4
00001dec <handle_setattr.isra.13>:
static int handle_setattr(struct fuse* fuse, struct fuse_handler* handler,
1dec: 4b40 ldr r3, [pc, #256] ; (1ef0 <handle_setattr.isra.13+0x104>)
1dee: e92d 47f0 stmdb sp!, {r4, r5, r6, r7, r8, r9, sl, lr}
1df2: 4614 mov r4, r2
1df4: 4a3f ldr r2, [pc, #252] ; (1ef4 <handle_setattr.isra.13+0x108>)
1df6: f5ad 5d81 sub.w sp, sp, #4128 ; 0x1020
1dfa: 447b add r3, pc
1dfc: 4688 mov r8, r1
1dfe: f50d 5180 add.w r1, sp, #4096 ; 0x1000
1e02: 4606 mov r6, r0
1e04: f853 9002 ldr.w r9, [r3, r2]
1e08: 311c adds r1, #28
char path[PATH_MAX];
struct timespec times[2];
pthread_mutex_lock(&fuse->lock);
has_rw = get_caller_has_rw_locked(fuse, hdr);
node = lookup_node_and_path_by_id_locked(fuse, hdr->nodeid, path, sizeof(path));
1e0a: ad07 add r5, sp, #28
}
return fuse_reply_attr(fuse, hdr->unique, node, path);
}
static int handle_setattr(struct fuse* fuse, struct fuse_handler* handler,
1e0c: f8d9 3000 ldr.w r3, [r9]
1e10: 600b str r3, [r1, #0]
bool has_rw;
struct node* node;
char path[PATH_MAX];
struct timespec times[2];
pthread_mutex_lock(&fuse->lock);
1e12: f7ff e908 blx 1024 <pthread_mutex_lock@plt>
has_rw = get_caller_has_rw_locked(fuse, hdr);
1e16: 4641 mov r1, r8
1e18: 4630 mov r0, r6
1e1a: f7ff fbfc bl 1616 <get_caller_has_rw_locked>
node = lookup_node_and_path_by_id_locked(fuse, hdr->nodeid, path, sizeof(path));
1e1e: e9d8 2304 ldrd r2, r3, [r8, #16]
struct node* node;
char path[PATH_MAX];
struct timespec times[2];
pthread_mutex_lock(&fuse->lock);
has_rw = get_caller_has_rw_locked(fuse, hdr);
1e22: 4682 mov sl, r0
node = lookup_node_and_path_by_id_locked(fuse, hdr->nodeid, path, sizeof(path));
1e24: 9500 str r5, [sp, #0]
1e26: 4630 mov r0, r6
1e28: f7ff fd76 bl 1918 <lookup_node_and_path_by_id_locked.constprop.28>
1e2c: 4607 mov r7, r0
TRACE("[%d] SETATTR fh=%llx valid=%x @ %llx (%s)\n", handler->token,
req->fh, req->valid, hdr->nodeid, node ? node->name : "?");
pthread_mutex_unlock(&fuse->lock);
1e2e: 4630 mov r0, r6
1e30: f7ff e8fe blx 1030 <pthread_mutex_unlock@plt>
if (!node) {
1e34: 2f00 cmp r7, #0
1e36: d045 beq.n 1ec4 <handle_setattr.isra.13+0xd8>
return true;
}
static bool check_caller_access_to_node(struct fuse* fuse,
const struct fuse_in_header *hdr, const struct node* node, int mode, bool has_rw) {
return check_caller_access_to_name(fuse, hdr, node->parent, node->name, mode, has_rw);
1e38: 2302 movs r3, #2
1e3a: 4630 mov r0, r6
1e3c: e88d 0408 stmia.w sp, {r3, sl}
1e40: 4641 mov r1, r8
1e42: 6b7a ldr r2, [r7, #52] ; 0x34
1e44: 6bfb ldr r3, [r7, #60] ; 0x3c
1e46: f7ff fb37 bl 14b8 <check_caller_access_to_name>
pthread_mutex_unlock(&fuse->lock);
if (!node) {
return -ENOENT;
}
if (!check_caller_access_to_node(fuse, hdr, node, W_OK, has_rw)) {
1e4a: 2800 cmp r0, #0
1e4c: d03d beq.n 1eca <handle_setattr.isra.13+0xde>
}
/* XXX: incomplete implementation on purpose.
* chmod/chown should NEVER be implemented.*/
if ((req->valid & FATTR_SIZE) && truncate(path, req->size) < 0) {
1e4e: 6820 ldr r0, [r4, #0]
1e50: 0703 lsls r3, r0, #28
1e52: d506 bpl.n 1e62 <handle_setattr.isra.13+0x76>
1e54: 4628 mov r0, r5
1e56: 6921 ldr r1, [r4, #16]
1e58: f7ff e950 blx 10fc <truncate@plt>
1e5c: 2800 cmp r0, #0
1e5e: da00 bge.n 1e62 <handle_setattr.isra.13+0x76>
1e60: e023 b.n 1eaa <handle_setattr.isra.13+0xbe>
* are both set, then set it to the current time. Else, set it to the
* time specified in the request. Same goes for mtime. Use utimensat(2)
* as it allows ATIME and MTIME to be changed independently, and has
* nanosecond resolution which fuse also has.
*/
if (req->valid & (FATTR_ATIME | FATTR_MTIME)) {
1e62: 6823 ldr r3, [r4, #0]
1e64: f013 0f30 tst.w r3, #48 ; 0x30
1e68: d024 beq.n 1eb4 <handle_setattr.isra.13+0xc8>
times[0].tv_nsec = UTIME_OMIT;
1e6a: 4a20 ldr r2, [pc, #128] ; (1eec <handle_setattr.isra.13+0x100>)
times[1].tv_nsec = UTIME_OMIT;
if (req->valid & FATTR_ATIME) {
1e6c: 06d8 lsls r0, r3, #27
* time specified in the request. Same goes for mtime. Use utimensat(2)
* as it allows ATIME and MTIME to be changed independently, and has
* nanosecond resolution which fuse also has.
*/
if (req->valid & (FATTR_ATIME | FATTR_MTIME)) {
times[0].tv_nsec = UTIME_OMIT;
1e6e: 9204 str r2, [sp, #16]
times[1].tv_nsec = UTIME_OMIT;
1e70: 9206 str r2, [sp, #24]
if (req->valid & FATTR_ATIME) {
1e72: d507 bpl.n 1e84 <handle_setattr.isra.13+0x98>
if (req->valid & FATTR_ATIME_NOW) {
1e74: 0619 lsls r1, r3, #24
times[0].tv_nsec = UTIME_NOW;
} else {
times[0].tv_sec = req->atime;
1e76: bf57 itett pl
1e78: 6a22 ldrpl r2, [r4, #32]
if (req->valid & (FATTR_ATIME | FATTR_MTIME)) {
times[0].tv_nsec = UTIME_OMIT;
times[1].tv_nsec = UTIME_OMIT;
if (req->valid & FATTR_ATIME) {
if (req->valid & FATTR_ATIME_NOW) {
times[0].tv_nsec = UTIME_NOW;
1e7a: f06f 4240 mvnmi.w r2, #3221225472 ; 0xc0000000
} else {
times[0].tv_sec = req->atime;
1e7e: 9203 strpl r2, [sp, #12]
times[0].tv_nsec = req->atimensec;
1e80: 6ba2 ldrpl r2, [r4, #56] ; 0x38
1e82: 9204 str r2, [sp, #16]
}
}
if (req->valid & FATTR_MTIME) {
1e84: 069a lsls r2, r3, #26
1e86: d507 bpl.n 1e98 <handle_setattr.isra.13+0xac>
if (req->valid & FATTR_MTIME_NOW) {
1e88: 05d9 lsls r1, r3, #23
times[1].tv_nsec = UTIME_NOW;
} else {
times[1].tv_sec = req->mtime;
1e8a: bf57 itett pl
1e8c: 6aa1 ldrpl r1, [r4, #40] ; 0x28
times[0].tv_nsec = req->atimensec;
}
}
if (req->valid & FATTR_MTIME) {
if (req->valid & FATTR_MTIME_NOW) {
times[1].tv_nsec = UTIME_NOW;
1e8e: f06f 4140 mvnmi.w r1, #3221225472 ; 0xc0000000
} else {
times[1].tv_sec = req->mtime;
1e92: 9105 strpl r1, [sp, #20]
times[1].tv_nsec = req->mtimensec;
1e94: 6be1 ldrpl r1, [r4, #60] ; 0x3c
1e96: 9106 str r1, [sp, #24]
}
}
TRACE("[%d] Calling utimensat on %s with atime %ld, mtime=%ld\n",
handler->token, path, times[0].tv_sec, times[1].tv_sec);
if (utimensat(-1, path, times, 0) < 0) {
1e98: 2300 movs r3, #0
1e9a: f04f 30ff mov.w r0, #4294967295 ; 0xffffffff
1e9e: 4629 mov r1, r5
1ea0: aa03 add r2, sp, #12
1ea2: f7ff e932 blx 1108 <utimensat@plt>
1ea6: 2800 cmp r0, #0
1ea8: da04 bge.n 1eb4 <handle_setattr.isra.13+0xc8>
return -errno;
1eaa: f7ff e8a4 blx ff4 <__errno@plt>
1eae: 6800 ldr r0, [r0, #0]
1eb0: 4240 negs r0, r0
1eb2: e00c b.n 1ece <handle_setattr.isra.13+0xe2>
}
}
return fuse_reply_attr(fuse, hdr->unique, node, path);
1eb4: e9d8 2302 ldrd r2, r3, [r8, #8]
1eb8: 4630 mov r0, r6
1eba: 9700 str r7, [sp, #0]
1ebc: 9501 str r5, [sp, #4]
1ebe: f7ff feeb bl 1c98 <fuse_reply_attr>
1ec2: e004 b.n 1ece <handle_setattr.isra.13+0xe2>
TRACE("[%d] SETATTR fh=%llx valid=%x @ %llx (%s)\n", handler->token,
req->fh, req->valid, hdr->nodeid, node ? node->name : "?");
pthread_mutex_unlock(&fuse->lock);
if (!node) {
return -ENOENT;
1ec4: f06f 0001 mvn.w r0, #1
1ec8: e001 b.n 1ece <handle_setattr.isra.13+0xe2>
}
if (!check_caller_access_to_node(fuse, hdr, node, W_OK, has_rw)) {
return -EACCES;
1eca: f06f 000c mvn.w r0, #12
if (utimensat(-1, path, times, 0) < 0) {
return -errno;
}
}
return fuse_reply_attr(fuse, hdr->unique, node, path);
}
1ece: f50d 5380 add.w r3, sp, #4096 ; 0x1000
1ed2: 331c adds r3, #28
1ed4: 681a ldr r2, [r3, #0]
1ed6: f8d9 1000 ldr.w r1, [r9]
1eda: 428a cmp r2, r1
1edc: d001 beq.n 1ee2 <handle_setattr.isra.13+0xf6>
1ede: f7ff e8b4 blx 1048 <__stack_chk_fail@plt>
1ee2: b008 add sp, #32
1ee4: f50d 5d80 add.w sp, sp, #4096 ; 0x1000
1ee8: e8bd 87f0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, sl, pc}
1eec: 3ffffffe .word 0x3ffffffe
1ef0: 000030be .word 0x000030be
1ef4: fffffff4 .word 0xfffffff4
00001ef8 <handle_rename.isra.17>:
return -errno;
}
return 0;
}
static int handle_rename(struct fuse* fuse, struct fuse_handler* handler,
1ef8: e92d 4ff0 stmdb sp!, {r4, r5, r6, r7, r8, r9, sl, fp, lr}
1efc: 4699 mov r9, r3
1efe: 4b8d ldr r3, [pc, #564] ; (2134 <handle_rename.isra.17+0x23c>)
1f00: 4615 mov r5, r2
1f02: f5ad 4d80 sub.w sp, sp, #16384 ; 0x4000
1f06: 4688 mov r8, r1
1f08: 4a8b ldr r2, [pc, #556] ; (2138 <handle_rename.isra.17+0x240>)
1f0a: b087 sub sp, #28
1f0c: 447b add r3, pc
1f0e: f50d 4180 add.w r1, sp, #16384 ; 0x4000
1f12: 3140 adds r1, #64 ; 0x40
1f14: 4604 mov r4, r0
1f16: 589b ldr r3, [r3, r2]
pthread_mutex_lock(&fuse->lock);
has_rw = get_caller_has_rw_locked(fuse, hdr);
old_parent_node = lookup_node_and_path_by_id_locked(fuse, hdr->nodeid,
old_parent_path, sizeof(old_parent_path));
new_parent_node = lookup_node_and_path_by_id_locked(fuse, req->newdir,
new_parent_path, sizeof(new_parent_path));
1f18: f50d 5a80 add.w sl, sp, #4096 ; 0x1000
return -errno;
}
return 0;
}
static int handle_rename(struct fuse* fuse, struct fuse_handler* handler,
1f1c: 680e ldr r6, [r1, #0]
1f1e: f50d 4180 add.w r1, sp, #16384 ; 0x4000
1f22: 3114 adds r1, #20
pthread_mutex_lock(&fuse->lock);
has_rw = get_caller_has_rw_locked(fuse, hdr);
old_parent_node = lookup_node_and_path_by_id_locked(fuse, hdr->nodeid,
old_parent_path, sizeof(old_parent_path));
new_parent_node = lookup_node_and_path_by_id_locked(fuse, req->newdir,
new_parent_path, sizeof(new_parent_path));
1f24: f10a 0a14 add.w sl, sl, #20
return -errno;
}
return 0;
}
static int handle_rename(struct fuse* fuse, struct fuse_handler* handler,
1f28: 681f ldr r7, [r3, #0]
1f2a: 9303 str r3, [sp, #12]
1f2c: 600f str r7, [r1, #0]
char old_child_path[PATH_MAX];
char new_child_path[PATH_MAX];
const char* new_actual_name;
int res;
pthread_mutex_lock(&fuse->lock);
1f2e: f7ff e87a blx 1024 <pthread_mutex_lock@plt>
has_rw = get_caller_has_rw_locked(fuse, hdr);
1f32: 4641 mov r1, r8
1f34: 4620 mov r0, r4
1f36: f7ff fb6e bl 1616 <get_caller_has_rw_locked>
1f3a: 4683 mov fp, r0
old_parent_node = lookup_node_and_path_by_id_locked(fuse, hdr->nodeid,
old_parent_path, sizeof(old_parent_path));
1f3c: a805 add r0, sp, #20
const char* new_actual_name;
int res;
pthread_mutex_lock(&fuse->lock);
has_rw = get_caller_has_rw_locked(fuse, hdr);
old_parent_node = lookup_node_and_path_by_id_locked(fuse, hdr->nodeid,
1f3e: e9d8 2304 ldrd r2, r3, [r8, #16]
1f42: 9000 str r0, [sp, #0]
1f44: 4620 mov r0, r4
1f46: f7ff fce7 bl 1918 <lookup_node_and_path_by_id_locked.constprop.28>
old_parent_path, sizeof(old_parent_path));
new_parent_node = lookup_node_and_path_by_id_locked(fuse, req->newdir,
1f4a: f8cd a000 str.w sl, [sp]
const char* new_actual_name;
int res;
pthread_mutex_lock(&fuse->lock);
has_rw = get_caller_has_rw_locked(fuse, hdr);
old_parent_node = lookup_node_and_path_by_id_locked(fuse, hdr->nodeid,
1f4e: 4607 mov r7, r0
old_parent_path, sizeof(old_parent_path));
new_parent_node = lookup_node_and_path_by_id_locked(fuse, req->newdir,
1f50: e9d5 2300 ldrd r2, r3, [r5]
1f54: 4620 mov r0, r4
1f56: f7ff fcdf bl 1918 <lookup_node_and_path_by_id_locked.constprop.28>
1f5a: 4605 mov r5, r0
new_parent_path, sizeof(new_parent_path));
TRACE("[%d] RENAME %s->%s @ %llx (%s) -> %llx (%s)\n", handler->token,
old_name, new_name,
hdr->nodeid, old_parent_node ? old_parent_node->name : "?",
req->newdir, new_parent_node ? new_parent_node->name : "?");
if (!old_parent_node || !new_parent_node) {
1f5c: b917 cbnz r7, 1f64 <handle_rename.isra.17+0x6c>
res = -ENOENT;
1f5e: f06f 0501 mvn.w r5, #1
1f62: e0c3 b.n 20ec <handle_rename.isra.17+0x1f4>
new_parent_path, sizeof(new_parent_path));
TRACE("[%d] RENAME %s->%s @ %llx (%s) -> %llx (%s)\n", handler->token,
old_name, new_name,
hdr->nodeid, old_parent_node ? old_parent_node->name : "?",
req->newdir, new_parent_node ? new_parent_node->name : "?");
if (!old_parent_node || !new_parent_node) {
1f64: 2800 cmp r0, #0
1f66: d0fa beq.n 1f5e <handle_rename.isra.17+0x66>
res = -ENOENT;
goto lookup_error;
}
if (!check_caller_access_to_name(fuse, hdr, old_parent_node, old_name, W_OK, has_rw)) {
1f68: f04f 0c02 mov.w ip, #2
1f6c: f8cd b004 str.w fp, [sp, #4]
1f70: f8cd c000 str.w ip, [sp]
1f74: 4620 mov r0, r4
1f76: 4641 mov r1, r8
1f78: 463a mov r2, r7
1f7a: 464b mov r3, r9
1f7c: f8cd c008 str.w ip, [sp, #8]
1f80: f7ff fa9a bl 14b8 <check_caller_access_to_name>
1f84: f8dd c008 ldr.w ip, [sp, #8]
1f88: 2800 cmp r0, #0
1f8a: f000 80ad beq.w 20e8 <handle_rename.isra.17+0x1f0>
res = -EACCES;
goto lookup_error;
}
if (!check_caller_access_to_name(fuse, hdr, new_parent_node, new_name, W_OK, has_rw)) {
1f8e: f8cd c000 str.w ip, [sp]
1f92: 4620 mov r0, r4
1f94: f8cd b004 str.w fp, [sp, #4]
1f98: 4641 mov r1, r8
1f9a: 462a mov r2, r5
1f9c: 4633 mov r3, r6
1f9e: f7ff fa8b bl 14b8 <check_caller_access_to_name>
1fa2: 2800 cmp r0, #0
1fa4: f000 80a0 beq.w 20e8 <handle_rename.isra.17+0x1f0>
return node;
}
static struct node *lookup_child_by_name_locked(struct node *node, const char *name)
{
for (node = node->child; node; node = node->next) {
1fa8: f8d7 8030 ldr.w r8, [r7, #48] ; 0x30
1fac: e009 b.n 1fc2 <handle_rename.isra.17+0xca>
/* use exact string comparison, nodes that differ by case
* must be considered distinct even if they refer to the same
* underlying file as otherwise operations such as "mv x x"
* will not work because the source and target nodes are the same. */
if (!strcmp(name, node->name)) {
1fae: 4648 mov r0, r9
1fb0: f8d8 103c ldr.w r1, [r8, #60] ; 0x3c
1fb4: f7ff e8ae blx 1114 <strcmp@plt>
1fb8: 2800 cmp r0, #0
1fba: f000 80a4 beq.w 2106 <handle_rename.isra.17+0x20e>
return node;
}
static struct node *lookup_child_by_name_locked(struct node *node, const char *name)
{
for (node = node->child; node; node = node->next) {
1fbe: f8d8 802c ldr.w r8, [r8, #44] ; 0x2c
1fc2: f1b8 0f00 cmp.w r8, #0
1fc6: d1f2 bne.n 1fae <handle_rename.isra.17+0xb6>
1fc8: e7c9 b.n 1f5e <handle_rename.isra.17+0x66>
return (__u64) (uintptr_t) ptr;
}
static void acquire_node_locked(struct node* node)
{
node->refcount++;
1fca: f8d8 2000 ldr.w r2, [r8]
old_child_path, sizeof(old_child_path)) < 0) {
res = -ENOENT;
goto lookup_error;
}
acquire_node_locked(child_node);
pthread_mutex_unlock(&fuse->lock);
1fce: 4620 mov r0, r4
return (__u64) (uintptr_t) ptr;
}
static void acquire_node_locked(struct node* node)
{
node->refcount++;
1fd0: 1c53 adds r3, r2, #1
1fd2: f8c8 3000 str.w r3, [r8]
old_child_path, sizeof(old_child_path)) < 0) {
res = -ENOENT;
goto lookup_error;
}
acquire_node_locked(child_node);
pthread_mutex_unlock(&fuse->lock);
1fd6: f7ff e82c blx 1030 <pthread_mutex_unlock@plt>
/* Special case for renaming a file where destination is same path
* differing only by case. In this case we don't want to look for a case
* insensitive match. This allows commands like "mv foo FOO" to work as expected.
*/
int search = old_parent_node != new_parent_node
|| strcasecmp(old_name, new_name);
1fda: 42af cmp r7, r5
1fdc: d107 bne.n 1fee <handle_rename.isra.17+0xf6>
1fde: 4648 mov r0, r9
1fe0: 4631 mov r1, r6
1fe2: f7fe efde blx fa0 <strcasecmp@plt>
1fe6: 1c03 adds r3, r0, #0
1fe8: bf18 it ne
1fea: 2301 movne r3, #1
1fec: e000 b.n 1ff0 <handle_rename.isra.17+0xf8>
1fee: 2301 movs r3, #1
if (!(new_actual_name = find_file_within(new_parent_path, new_name,
1ff0: f50d 5240 add.w r2, sp, #12288 ; 0x3000
1ff4: 4650 mov r0, sl
1ff6: 4631 mov r1, r6
1ff8: 3214 adds r2, #20
1ffa: f7ff fc2b bl 1854 <find_file_within.constprop.27>
1ffe: 4681 mov r9, r0
2000: 2800 cmp r0, #0
2002: d068 beq.n 20d6 <handle_rename.isra.17+0x1de>
res = -ENOENT;
goto io_error;
}
TRACE("[%d] RENAME %s->%s\n", handler->token, old_child_path, new_child_path);
res = rename(old_child_path, new_child_path);
2004: f50d 5000 add.w r0, sp, #8192 ; 0x2000
2008: f50d 5140 add.w r1, sp, #12288 ; 0x3000
200c: 3014 adds r0, #20
200e: 3114 adds r1, #20
2010: f7ff e886 blx 1120 <rename@plt>
if (res < 0) {
2014: 2800 cmp r0, #0
2016: da04 bge.n 2022 <handle_rename.isra.17+0x12a>
res = -errno;
2018: f7fe efec blx ff4 <__errno@plt>
201c: 6805 ldr r5, [r0, #0]
201e: 426d negs r5, r5
2020: e05b b.n 20da <handle_rename.isra.17+0x1e2>
goto io_error;
}
pthread_mutex_lock(&fuse->lock);
2022: 4620 mov r0, r4
2024: f7fe effe blx 1024 <pthread_mutex_lock@plt>
size_t bos = __bos(s);
#if !defined(__clang__)
// Compiler doesn't know destination size. Don't call __strlen_chk
if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
return __builtin_strlen(s);
2028: 4630 mov r0, r6
202a: f7fe efc0 blx fac <strlen@plt>
static int rename_node_locked(struct node *node, const char *name,
const char* actual_name)
{
size_t namelen = strlen(name);
int need_actual_name = strcmp(name, actual_name);
202e: 4649 mov r1, r9
2030: 4607 mov r7, r0
2032: 4630 mov r0, r6
2034: f7ff e86e blx 1114 <strcmp@plt>
/* make the storage bigger without actually changing the name
* in case an error occurs part way */
if (namelen > node->namelen) {
2038: f8d8 1038 ldr.w r1, [r8, #56] ; 0x38
static int rename_node_locked(struct node *node, const char *name,
const char* actual_name)
{
size_t namelen = strlen(name);
int need_actual_name = strcmp(name, actual_name);
203c: 4682 mov sl, r0
/* make the storage bigger without actually changing the name
* in case an error occurs part way */
if (namelen > node->namelen) {
203e: 428f cmp r7, r1
2040: d918 bls.n 2074 <handle_rename.isra.17+0x17c>
char* new_name = realloc(node->name, namelen + 1);
2042: f107 0b01 add.w fp, r7, #1
2046: f8d8 003c ldr.w r0, [r8, #60] ; 0x3c
204a: 4659 mov r1, fp
204c: f7ff e86e blx 112c <realloc@plt>
if (!new_name) {
2050: 2800 cmp r0, #0
2052: d064 beq.n 211e <handle_rename.isra.17+0x226>
return -ENOMEM;
}
node->name = new_name;
2054: f8c8 003c str.w r0, [r8, #60] ; 0x3c
if (need_actual_name && node->actual_name) {
2058: f1ba 0f00 cmp.w sl, #0
205c: d01d beq.n 209a <handle_rename.isra.17+0x1a2>
205e: f8d8 0040 ldr.w r0, [r8, #64] ; 0x40
2062: b140 cbz r0, 2076 <handle_rename.isra.17+0x17e>
char* new_actual_name = realloc(node->actual_name, namelen + 1);
2064: 4659 mov r1, fp
2066: f7ff e862 blx 112c <realloc@plt>
if (!new_actual_name) {
206a: 2800 cmp r0, #0
206c: d057 beq.n 211e <handle_rename.isra.17+0x226>
return -ENOMEM;
}
node->actual_name = new_actual_name;
206e: f8c8 0040 str.w r0, [r8, #64] ; 0x40
2072: e000 b.n 2076 <handle_rename.isra.17+0x17e>
}
}
/* update the name, taking care to allocate storage before overwriting the old name */
if (need_actual_name) {
2074: b188 cbz r0, 209a <handle_rename.isra.17+0x1a2>
if (!node->actual_name) {
2076: f8d8 2040 ldr.w r2, [r8, #64] ; 0x40
207a: b132 cbz r2, 208a <handle_rename.isra.17+0x192>
if (__builtin_constant_p(copy_amount) && (copy_amount > s_len)) {
__memcpy_src_size_error();
}
return __builtin___memcpy_chk(dest, src, copy_amount, d_len);
207c: f8d8 0040 ldr.w r0, [r8, #64] ; 0x40
2080: 4649 mov r1, r9
2082: 1c7a adds r2, r7, #1
2084: f7fe ef9e blx fc4 <memcpy@plt>
2088: e00e b.n 20a8 <handle_rename.isra.17+0x1b0>
node->actual_name = malloc(namelen + 1);
208a: 1c78 adds r0, r7, #1
208c: f7ff e824 blx 10d8 <malloc@plt>
2090: f8c8 0040 str.w r0, [r8, #64] ; 0x40
if (!node->actual_name) {
2094: 2800 cmp r0, #0
2096: d1f1 bne.n 207c <handle_rename.isra.17+0x184>
2098: e041 b.n 211e <handle_rename.isra.17+0x226>
return -ENOMEM;
}
}
memcpy(node->actual_name, actual_name, namelen + 1);
} else {
free(node->actual_name);
209a: f8d8 0040 ldr.w r0, [r8, #64] ; 0x40
209e: f7fe ef9e blx fdc <free@plt>
node->actual_name = NULL;
20a2: 2000 movs r0, #0
20a4: f8c8 0040 str.w r0, [r8, #64] ; 0x40
20a8: 4631 mov r1, r6
20aa: 1c7a adds r2, r7, #1
20ac: f8d8 003c ldr.w r0, [r8, #60] ; 0x3c
20b0: f7fe ef88 blx fc4 <memcpy@plt>
}
pthread_mutex_lock(&fuse->lock);
res = rename_node_locked(child_node, new_name, new_actual_name);
if (!res) {
remove_node_from_parent_locked(child_node);
20b4: 4640 mov r0, r8
} else {
free(node->actual_name);
node->actual_name = NULL;
}
memcpy(node->name, name, namelen + 1);
node->namelen = namelen;
20b6: f8c8 7038 str.w r7, [r8, #56] ; 0x38
}
pthread_mutex_lock(&fuse->lock);
res = rename_node_locked(child_node, new_name, new_actual_name);
if (!res) {
remove_node_from_parent_locked(child_node);
20ba: f7ff fa95 bl 15e8 <remove_node_from_parent_locked>
ERROR("Zero refcnt %p\n", node);
}
}
static void add_node_to_parent_locked(struct node *node, struct node *parent) {
node->parent = parent;
20be: f8c8 5034 str.w r5, [r8, #52] ; 0x34
node->next = parent->child;
20c2: 6b2b ldr r3, [r5, #48] ; 0x30
20c4: f8c8 302c str.w r3, [r8, #44] ; 0x2c
return (__u64) (uintptr_t) ptr;
}
static void acquire_node_locked(struct node* node)
{
node->refcount++;
20c8: 6829 ldr r1, [r5, #0]
}
static void add_node_to_parent_locked(struct node *node, struct node *parent) {
node->parent = parent;
node->next = parent->child;
parent->child = node;
20ca: f8c5 8030 str.w r8, [r5, #48] ; 0x30
return (__u64) (uintptr_t) ptr;
}
static void acquire_node_locked(struct node* node)
{
node->refcount++;
20ce: 1c48 adds r0, r1, #1
20d0: 6028 str r0, [r5, #0]
20d2: 2500 movs r5, #0
20d4: e004 b.n 20e0 <handle_rename.isra.17+0x1e8>
*/
int search = old_parent_node != new_parent_node
|| strcasecmp(old_name, new_name);
if (!(new_actual_name = find_file_within(new_parent_path, new_name,
new_child_path, sizeof(new_child_path), search))) {
res = -ENOENT;
20d6: f06f 0501 mvn.w r5, #1
add_node_to_parent_locked(child_node, new_parent_node);
}
goto done;
io_error:
pthread_mutex_lock(&fuse->lock);
20da: 4620 mov r0, r4
20dc: f7fe efa2 blx 1024 <pthread_mutex_lock@plt>
done:
release_node_locked(child_node);
20e0: 4640 mov r0, r8
20e2: f7ff fa4f bl 1584 <release_node_locked>
20e6: e001 b.n 20ec <handle_rename.isra.17+0x1f4>
if (!old_parent_node || !new_parent_node) {
res = -ENOENT;
goto lookup_error;
}
if (!check_caller_access_to_name(fuse, hdr, old_parent_node, old_name, W_OK, has_rw)) {
res = -EACCES;
20e8: f06f 050c mvn.w r5, #12
io_error:
pthread_mutex_lock(&fuse->lock);
done:
release_node_locked(child_node);
lookup_error:
pthread_mutex_unlock(&fuse->lock);
20ec: 4620 mov r0, r4
20ee: f7fe efa0 blx 1030 <pthread_mutex_unlock@plt>
return res;
}
20f2: 9b03 ldr r3, [sp, #12]
20f4: f50d 4280 add.w r2, sp, #16384 ; 0x4000
20f8: 3214 adds r2, #20
20fa: 4628 mov r0, r5
20fc: 6812 ldr r2, [r2, #0]
20fe: 6819 ldr r1, [r3, #0]
2100: 428a cmp r2, r1
2102: d011 beq.n 2128 <handle_rename.isra.17+0x230>
2104: e00e b.n 2124 <handle_rename.isra.17+0x22c>
if (!check_caller_access_to_name(fuse, hdr, new_parent_node, new_name, W_OK, has_rw)) {
res = -EACCES;
goto lookup_error;
}
child_node = lookup_child_by_name_locked(old_parent_node, old_name);
if (!child_node || get_node_path_locked(child_node,
2106: f50d 5100 add.w r1, sp, #8192 ; 0x2000
210a: 4640 mov r0, r8
210c: 3114 adds r1, #20
210e: f44f 5280 mov.w r2, #4096 ; 0x1000
2112: f7ff f991 bl 1438 <get_node_path_locked>
2116: 2800 cmp r0, #0
2118: f6bf af57 bge.w 1fca <handle_rename.isra.17+0xd2>
211c: e71f b.n 1f5e <handle_rename.isra.17+0x66>
*/
int search = old_parent_node != new_parent_node
|| strcasecmp(old_name, new_name);
if (!(new_actual_name = find_file_within(new_parent_path, new_name,
new_child_path, sizeof(new_child_path), search))) {
res = -ENOENT;
211e: f06f 050b mvn.w r5, #11
2122: e7dd b.n 20e0 <handle_rename.isra.17+0x1e8>
done:
release_node_locked(child_node);
lookup_error:
pthread_mutex_unlock(&fuse->lock);
return res;
}
2124: f7fe ef90 blx 1048 <__stack_chk_fail@plt>
2128: b007 add sp, #28
212a: f50d 4d80 add.w sp, sp, #16384 ; 0x4000
212e: e8bd 8ff0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, sl, fp, pc}
2132: bf00 nop
2134: 00002fac .word 0x00002fac
2138: fffffff4 .word 0xfffffff4
213c: 00000000 .word 0x00000000
00002140 <create_node_locked>:
return check_caller_access_to_name(fuse, hdr, node->parent, node->name, mode, has_rw);
}
struct node *create_node_locked(struct fuse* fuse,
struct node *parent, const char *name, const char* actual_name)
{
2140: e92d 4ff8 stmdb sp!, {r3, r4, r5, r6, r7, r8, r9, sl, fp, lr}
2144: 4607 mov r7, r0
size_t bos = __bos(s);
#if !defined(__clang__)
// Compiler doesn't know destination size. Don't call __strlen_chk
if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
return __builtin_strlen(s);
2146: 4610 mov r0, r2
2148: 460d mov r5, r1
214a: 4691 mov r9, r2
214c: 469b mov fp, r3
214e: f7fe ef2e blx fac <strlen@plt>
struct node *node;
size_t namelen = strlen(name);
node = calloc(1, sizeof(struct node));
2152: 2150 movs r1, #80 ; 0x50
2154: 4682 mov sl, r0
2156: 2001 movs r0, #1
2158: f7fe efee blx 1138 <calloc@plt>
if (!node) {
215c: 4604 mov r4, r0
215e: 2800 cmp r0, #0
2160: f000 80f1 beq.w 2346 <create_node_locked+0x206>
return NULL;
}
node->name = malloc(namelen + 1);
2164: f10a 0601 add.w r6, sl, #1
2168: 4630 mov r0, r6
216a: f7fe efb6 blx 10d8 <malloc@plt>
216e: 4680 mov r8, r0
2170: 63e0 str r0, [r4, #60] ; 0x3c
if (!node->name) {
2172: b920 cbnz r0, 217e <create_node_locked+0x3e>
free(node);
2174: 4620 mov r0, r4
return NULL;
2176: 4644 mov r4, r8
if (!node) {
return NULL;
}
node->name = malloc(namelen + 1);
if (!node->name) {
free(node);
2178: f7fe ef30 blx fdc <free@plt>
return NULL;
217c: e0e3 b.n 2346 <create_node_locked+0x206>
if (__builtin_constant_p(copy_amount) && (copy_amount > s_len)) {
__memcpy_src_size_error();
}
return __builtin___memcpy_chk(dest, src, copy_amount, d_len);
217e: 4649 mov r1, r9
2180: 4632 mov r2, r6
2182: f7fe ef20 blx fc4 <memcpy@plt>
}
memcpy(node->name, name, namelen + 1);
if (strcmp(name, actual_name)) {
2186: 4648 mov r0, r9
2188: 4659 mov r1, fp
218a: f7fe efc4 blx 1114 <strcmp@plt>
218e: b188 cbz r0, 21b4 <create_node_locked+0x74>
node->actual_name = malloc(namelen + 1);
2190: 4630 mov r0, r6
2192: f7fe efa2 blx 10d8 <malloc@plt>
2196: 4681 mov r9, r0
2198: 6420 str r0, [r4, #64] ; 0x40
if (!node->actual_name) {
219a: b938 cbnz r0, 21ac <create_node_locked+0x6c>
free(node->name);
219c: 4640 mov r0, r8
219e: f7fe ef1e blx fdc <free@plt>
free(node);
21a2: 4620 mov r0, r4
return NULL;
21a4: 464c mov r4, r9
memcpy(node->name, name, namelen + 1);
if (strcmp(name, actual_name)) {
node->actual_name = malloc(namelen + 1);
if (!node->actual_name) {
free(node->name);
free(node);
21a6: f7fe ef1a blx fdc <free@plt>
return NULL;
21aa: e0cc b.n 2346 <create_node_locked+0x206>
21ac: 4659 mov r1, fp
21ae: 4632 mov r2, r6
21b0: f7fe ef08 blx fc4 <memcpy@plt>
return (void *) (uintptr_t) nid;
}
static inline __u64 ptr_to_id(void *ptr)
{
return (__u64) (uintptr_t) ptr;
21b4: 2300 movs r3, #0
free(node);
return NULL;
}
memcpy(node->actual_name, actual_name, namelen + 1);
}
node->namelen = namelen;
21b6: f8c4 a038 str.w sl, [r4, #56] ; 0x38
return (void *) (uintptr_t) nid;
}
static inline __u64 ptr_to_id(void *ptr)
{
return (__u64) (uintptr_t) ptr;
21ba: 60a4 str r4, [r4, #8]
21bc: 60e3 str r3, [r4, #12]
}
memcpy(node->actual_name, actual_name, namelen + 1);
}
node->namelen = namelen;
node->nid = ptr_to_id(node);
node->gen = fuse->next_generation++;
21be: edd7 0b02 vldr d16, [r7, #8]
21c2: eddf 1b63 vldr d17, [pc, #396] ; 2350 <create_node_locked+0x210>
21c6: edc4 0b04 vstr d16, [r4, #16]
21ca: ef30 08a1 vadd.i64 d0, d16, d17
21ce: ed87 0b02 vstr d0, [r7, #8]
static void derive_permissions_locked(struct fuse* fuse, struct node *parent,
struct node *node) {
appid_t appid;
/* By default, each node inherits from its parent */
node->perm = PERM_INHERIT;
21d2: 61a3 str r3, [r4, #24]
node->userid = parent->userid;
21d4: 69e8 ldr r0, [r5, #28]
21d6: 61e0 str r0, [r4, #28]
node->uid = parent->uid;
21d8: 6a29 ldr r1, [r5, #32]
21da: 6221 str r1, [r4, #32]
node->gid = parent->gid;
21dc: 6a6a ldr r2, [r5, #36] ; 0x24
21de: 6262 str r2, [r4, #36] ; 0x24
node->mode = parent->mode;
21e0: f8b5 c028 ldrh.w ip, [r5, #40] ; 0x28
21e4: f8a4 c028 strh.w ip, [r4, #40] ; 0x28
if (fuse->derive == DERIVE_NONE) {
21e8: 697b ldr r3, [r7, #20]
21ea: 2b00 cmp r3, #0
21ec: f000 80a1 beq.w 2332 <create_node_locked+0x1f2>
return;
}
/* Derive custom permissions based on parent and current node */
switch (parent->perm) {
21f0: 69a8 ldr r0, [r5, #24]
21f2: 1e42 subs r2, r0, #1
21f4: 2a05 cmp r2, #5
21f6: f200 809c bhi.w 2332 <create_node_locked+0x1f2>
21fa: e8df f002 tbb [pc, r2]
21fe: 0c03 .short 0x0c03
2200: 8c7d7d53 .word 0x8c7d7d53
case PERM_INHERIT:
/* Already inherited above */
break;
case PERM_LEGACY_PRE_ROOT:
/* Legacy internal layout places users at top level */
node->perm = PERM_ROOT;
2204: 2202 movs r2, #2
node->userid = strtoul(node->name, NULL, 10);
2206: 6be0 ldr r0, [r4, #60] ; 0x3c
case PERM_INHERIT:
/* Already inherited above */
break;
case PERM_LEGACY_PRE_ROOT:
/* Legacy internal layout places users at top level */
node->perm = PERM_ROOT;
2208: 61a2 str r2, [r4, #24]
node->userid = strtoul(node->name, NULL, 10);
220a: 2100 movs r1, #0
220c: 220a movs r2, #10
220e: f7fe ef9a blx 1144 <strtoul@plt>
2212: 61e0 str r0, [r4, #28]
2214: e08d b.n 2332 <create_node_locked+0x1f2>
break;
case PERM_ROOT:
/* Assume masked off by default. */
node->mode = 0770;
2216: f44f 76fc mov.w r6, #504 ; 0x1f8
if (!strcasecmp(node->name, "Android")) {
221a: 494f ldr r1, [pc, #316] ; (2358 <create_node_locked+0x218>)
node->perm = PERM_ROOT;
node->userid = strtoul(node->name, NULL, 10);
break;
case PERM_ROOT:
/* Assume masked off by default. */
node->mode = 0770;
221c: 8526 strh r6, [r4, #40] ; 0x28
if (!strcasecmp(node->name, "Android")) {
221e: 6be6 ldr r6, [r4, #60] ; 0x3c
2220: 4479 add r1, pc
2222: 4630 mov r0, r6
2224: f7fe eebc blx fa0 <strcasecmp@plt>
2228: b908 cbnz r0, 222e <create_node_locked+0xee>
/* App-specific directories inside; let anyone traverse */
node->perm = PERM_ANDROID;
222a: 2103 movs r1, #3
222c: e042 b.n 22b4 <create_node_locked+0x174>
node->mode = 0771;
} else if (fuse->split_perms) {
222e: 7e3b ldrb r3, [r7, #24]
2230: 2b00 cmp r3, #0
2232: d07e beq.n 2332 <create_node_locked+0x1f2>
if (!strcasecmp(node->name, "DCIM")
2234: 4949 ldr r1, [pc, #292] ; (235c <create_node_locked+0x21c>)
2236: 4630 mov r0, r6
2238: 4479 add r1, pc
223a: f7fe eeb2 blx fa0 <strcasecmp@plt>
223e: b128 cbz r0, 224c <create_node_locked+0x10c>
|| !strcasecmp(node->name, "Pictures")) {
2240: 4947 ldr r1, [pc, #284] ; (2360 <create_node_locked+0x220>)
2242: 4630 mov r0, r6
2244: 4479 add r1, pc
2246: f7fe eeac blx fa0 <strcasecmp@plt>
224a: b910 cbnz r0, 2252 <create_node_locked+0x112>
node->gid = AID_SDCARD_PICS;
224c: f240 4009 movw r0, #1033 ; 0x409
2250: e026 b.n 22a0 <create_node_locked+0x160>
} else if (!strcasecmp(node->name, "Alarms")
2252: 4944 ldr r1, [pc, #272] ; (2364 <create_node_locked+0x224>)
2254: 4630 mov r0, r6
2256: 4479 add r1, pc
2258: f7fe eea2 blx fa0 <strcasecmp@plt>
225c: b1f0 cbz r0, 229c <create_node_locked+0x15c>
|| !strcasecmp(node->name, "Movies")
225e: 4942 ldr r1, [pc, #264] ; (2368 <create_node_locked+0x228>)
2260: 4630 mov r0, r6
2262: 4479 add r1, pc
2264: f7fe ee9c blx fa0 <strcasecmp@plt>
2268: b1c0 cbz r0, 229c <create_node_locked+0x15c>
|| !strcasecmp(node->name, "Music")
226a: 4940 ldr r1, [pc, #256] ; (236c <create_node_locked+0x22c>)
226c: 4630 mov r0, r6
226e: 4479 add r1, pc
2270: f7fe ee96 blx fa0 <strcasecmp@plt>
2274: b190 cbz r0, 229c <create_node_locked+0x15c>
|| !strcasecmp(node->name, "Notifications")
2276: 493e ldr r1, [pc, #248] ; (2370 <create_node_locked+0x230>)
2278: 4630 mov r0, r6
227a: 4479 add r1, pc
227c: f7fe ee90 blx fa0 <strcasecmp@plt>
2280: b160 cbz r0, 229c <create_node_locked+0x15c>
|| !strcasecmp(node->name, "Podcasts")
2282: 493c ldr r1, [pc, #240] ; (2374 <create_node_locked+0x234>)
2284: 4630 mov r0, r6
2286: 4479 add r1, pc
2288: f7fe ee8a blx fa0 <strcasecmp@plt>
228c: b130 cbz r0, 229c <create_node_locked+0x15c>
|| !strcasecmp(node->name, "Ringtones")) {
228e: 493a ldr r1, [pc, #232] ; (2378 <create_node_locked+0x238>)
2290: 4630 mov r0, r6
2292: 4479 add r1, pc
2294: f7fe ee84 blx fa0 <strcasecmp@plt>
2298: 2800 cmp r0, #0
229a: d14a bne.n 2332 <create_node_locked+0x1f2>
node->gid = AID_SDCARD_AV;
229c: f240 400a movw r0, #1034 ; 0x40a
22a0: 6260 str r0, [r4, #36] ; 0x24
22a2: e046 b.n 2332 <create_node_locked+0x1f2>
}
}
break;
case PERM_ANDROID:
if (!strcasecmp(node->name, "data")) {
22a4: 6be6 ldr r6, [r4, #60] ; 0x3c
22a6: 4935 ldr r1, [pc, #212] ; (237c <create_node_locked+0x23c>)
22a8: 4630 mov r0, r6
22aa: 4479 add r1, pc
22ac: f7fe ee78 blx fa0 <strcasecmp@plt>
22b0: b910 cbnz r0, 22b8 <create_node_locked+0x178>
/* App-specific directories inside; let anyone traverse */
node->perm = PERM_ANDROID_DATA;
22b2: 2104 movs r1, #4
22b4: 61a1 str r1, [r4, #24]
22b6: e039 b.n 232c <create_node_locked+0x1ec>
node->mode = 0771;
} else if (!strcasecmp(node->name, "obb")) {
22b8: 4931 ldr r1, [pc, #196] ; (2380 <create_node_locked+0x240>)
22ba: 4630 mov r0, r6
22bc: 4479 add r1, pc
22be: f7fe ee70 blx fa0 <strcasecmp@plt>
22c2: b968 cbnz r0, 22e0 <create_node_locked+0x1a0>
/* App-specific directories inside; let anyone traverse */
node->perm = PERM_ANDROID_OBB;
22c4: 2005 movs r0, #5
if (__builtin_constant_p(slen)) {
return slen;
}
#endif /* !defined(__clang__) */
return __strlen_chk(s, bos);
22c6: f44f 5180 mov.w r1, #4096 ; 0x1000
node->mode = 0771;
22ca: f500 72fa add.w r2, r0, #500 ; 0x1f4
/* App-specific directories inside; let anyone traverse */
node->perm = PERM_ANDROID_DATA;
node->mode = 0771;
} else if (!strcasecmp(node->name, "obb")) {
/* App-specific directories inside; let anyone traverse */
node->perm = PERM_ANDROID_OBB;
22ce: 61a0 str r0, [r4, #24]
node->mode = 0771;
/* Single OBB directory is always shared */
node->graft_path = fuse->obbpath;
22d0: f107 0070 add.w r0, r7, #112 ; 0x70
node->perm = PERM_ANDROID_DATA;
node->mode = 0771;
} else if (!strcasecmp(node->name, "obb")) {
/* App-specific directories inside; let anyone traverse */
node->perm = PERM_ANDROID_OBB;
node->mode = 0771;
22d4: 8522 strh r2, [r4, #40] ; 0x28
/* Single OBB directory is always shared */
node->graft_path = fuse->obbpath;
22d6: 6460 str r0, [r4, #68] ; 0x44
22d8: f7fe ef3a blx 1150 <__strlen_chk@plt>
node->graft_pathlen = strlen(fuse->obbpath);
22dc: 64a0 str r0, [r4, #72] ; 0x48
22de: e028 b.n 2332 <create_node_locked+0x1f2>
} else if (!strcasecmp(node->name, "user")) {
22e0: 4928 ldr r1, [pc, #160] ; (2384 <create_node_locked+0x244>)
22e2: 4630 mov r0, r6
22e4: 4479 add r1, pc
22e6: f7fe ee5c blx fa0 <strcasecmp@plt>
22ea: bb10 cbnz r0, 2332 <create_node_locked+0x1f2>
/* User directories must only be accessible to system, protected
* by sdcard_all. Zygote will bind mount the appropriate user-
* specific path. */
node->perm = PERM_ANDROID_USER;
22ec: 2106 movs r1, #6
node->gid = AID_SDCARD_ALL;
22ee: f240 430b movw r3, #1035 ; 0x40b
node->graft_pathlen = strlen(fuse->obbpath);
} else if (!strcasecmp(node->name, "user")) {
/* User directories must only be accessible to system, protected
* by sdcard_all. Zygote will bind mount the appropriate user-
* specific path. */
node->perm = PERM_ANDROID_USER;
22f2: 61a1 str r1, [r4, #24]
node->gid = AID_SDCARD_ALL;
22f4: 6263 str r3, [r4, #36] ; 0x24
22f6: e00b b.n 2310 <create_node_locked+0x1d0>
node->mode = 0770;
}
break;
case PERM_ANDROID_DATA:
case PERM_ANDROID_OBB:
appid = (appid_t) hashmapGet(fuse->package_to_appid, node->name);
22f8: f507 5783 add.w r7, r7, #4192 ; 0x1060
22fc: 6be1 ldr r1, [r4, #60] ; 0x3c
22fe: 6938 ldr r0, [r7, #16]
2300: f7fe ef2c blx 115c <hashmapGet@plt>
if (appid != 0) {
2304: 4601 mov r1, r0
2306: b118 cbz r0, 2310 <create_node_locked+0x1d0>
node->uid = multiuser_get_uid(parent->userid, appid);
2308: 69e8 ldr r0, [r5, #28]
230a: f7fe ef2e blx 1168 <multiuser_get_uid@plt>
230e: 6220 str r0, [r4, #32]
}
node->mode = 0770;
2310: f44f 70fc mov.w r0, #504 ; 0x1f8
2314: e00c b.n 2330 <create_node_locked+0x1f0>
break;
case PERM_ANDROID_USER:
/* Root of a secondary user */
node->perm = PERM_ROOT;
2316: 2102 movs r1, #2
node->userid = strtoul(node->name, NULL, 10);
2318: 6be0 ldr r0, [r4, #60] ; 0x3c
}
node->mode = 0770;
break;
case PERM_ANDROID_USER:
/* Root of a secondary user */
node->perm = PERM_ROOT;
231a: 61a1 str r1, [r4, #24]
node->userid = strtoul(node->name, NULL, 10);
231c: 220a movs r2, #10
231e: 2100 movs r1, #0
2320: f7fe ef10 blx 1144 <strtoul@plt>
node->gid = AID_SDCARD_R;
2324: f240 4304 movw r3, #1028 ; 0x404
node->mode = 0770;
break;
case PERM_ANDROID_USER:
/* Root of a secondary user */
node->perm = PERM_ROOT;
node->userid = strtoul(node->name, NULL, 10);
2328: 61e0 str r0, [r4, #28]
node->gid = AID_SDCARD_R;
232a: 6263 str r3, [r4, #36] ; 0x24
node->mode = 0771;
232c: f240 10f9 movw r0, #505 ; 0x1f9
2330: 8520 strh r0, [r4, #40] ; 0x28
return (__u64) (uintptr_t) ptr;
}
static void acquire_node_locked(struct node* node)
{
node->refcount++;
2332: 6822 ldr r2, [r4, #0]
ERROR("Zero refcnt %p\n", node);
}
}
static void add_node_to_parent_locked(struct node *node, struct node *parent) {
node->parent = parent;
2334: 6365 str r5, [r4, #52] ; 0x34
return (__u64) (uintptr_t) ptr;
}
static void acquire_node_locked(struct node* node)
{
node->refcount++;
2336: 1c51 adds r1, r2, #1
2338: 6021 str r1, [r4, #0]
}
}
static void add_node_to_parent_locked(struct node *node, struct node *parent) {
node->parent = parent;
node->next = parent->child;
233a: 6b2b ldr r3, [r5, #48] ; 0x30
233c: 62e3 str r3, [r4, #44] ; 0x2c
return (__u64) (uintptr_t) ptr;
}
static void acquire_node_locked(struct node* node)
{
node->refcount++;
233e: 6828 ldr r0, [r5, #0]
}
static void add_node_to_parent_locked(struct node *node, struct node *parent) {
node->parent = parent;
node->next = parent->child;
parent->child = node;
2340: 632c str r4, [r5, #48] ; 0x30
return (__u64) (uintptr_t) ptr;
}
static void acquire_node_locked(struct node* node)
{
node->refcount++;
2342: 1c42 adds r2, r0, #1
2344: 602a str r2, [r5, #0]
derive_permissions_locked(fuse, parent, node);
acquire_node_locked(node);
add_node_to_parent_locked(node, parent);
return node;
}
2346: 4620 mov r0, r4
2348: e8bd 8ff8 ldmia.w sp!, {r3, r4, r5, r6, r7, r8, r9, sl, fp, pc}
234c: f3af 8000 nop.w
2350: 00000001 .word 0x00000001
2354: 00000000 .word 0x00000000
2358: 000014d0 .word 0x000014d0
235c: 000014c0 .word 0x000014c0
2360: 000014b9 .word 0x000014b9
2364: 000014b0 .word 0x000014b0
2368: 000014ab .word 0x000014ab
236c: 000014a6 .word 0x000014a6
2370: 000014a0 .word 0x000014a0
2374: 000014a2 .word 0x000014a2
2378: 0000149f .word 0x0000149f
237c: 00001491 .word 0x00001491
2380: 00001484 .word 0x00001484
2384: 00001460 .word 0x00001460
00002388 <fuse_reply_entry>:
}
static int fuse_reply_entry(struct fuse* fuse, __u64 unique,
struct node* parent, const char* name, const char* actual_name,
const char* path)
{
2388: e92d 45f0 stmdb sp!, {r4, r5, r6, r7, r8, sl, lr}
238c: 4680 mov r8, r0
238e: ed2d 8b02 vpush {d8}
2392: b0bd sub sp, #244 ; 0xf4
struct node* node;
struct fuse_entry_out out;
struct stat s;
if (lstat(path, &s) < 0) {
2394: a902 add r1, sp, #8
2396: 9849 ldr r0, [sp, #292] ; 0x124
}
static int fuse_reply_entry(struct fuse* fuse, __u64 unique,
struct node* parent, const char* name, const char* actual_name,
const char* path)
{
2398: ec43 2b18 vmov d8, r2, r3
239c: 9d46 ldr r5, [sp, #280] ; 0x118
239e: 9c47 ldr r4, [sp, #284] ; 0x11c
struct node* node;
struct fuse_entry_out out;
struct stat s;
if (lstat(path, &s) < 0) {
23a0: f7fe eea6 blx 10f0 <lstat@plt>
23a4: 2800 cmp r0, #0
23a6: da04 bge.n 23b2 <fuse_reply_entry+0x2a>
return -errno;
23a8: f7fe ee24 blx ff4 <__errno@plt>
23ac: 6801 ldr r1, [r0, #0]
23ae: 4248 negs r0, r1
23b0: e078 b.n 24a4 <fuse_reply_entry+0x11c>
}
pthread_mutex_lock(&fuse->lock);
23b2: 4640 mov r0, r8
23b4: f7fe ee36 blx 1024 <pthread_mutex_lock@plt>
return node;
}
static struct node *lookup_child_by_name_locked(struct node *node, const char *name)
{
for (node = node->child; node; node = node->next) {
23b8: 6b2e ldr r6, [r5, #48] ; 0x30
23ba: e006 b.n 23ca <fuse_reply_entry+0x42>
/* use exact string comparison, nodes that differ by case
* must be considered distinct even if they refer to the same
* underlying file as otherwise operations such as "mv x x"
* will not work because the source and target nodes are the same. */
if (!strcmp(name, node->name)) {
23bc: 4620 mov r0, r4
23be: 6bf1 ldr r1, [r6, #60] ; 0x3c
23c0: f7fe eea8 blx 1114 <strcmp@plt>
23c4: 2800 cmp r0, #0
23c6: d05f beq.n 2488 <fuse_reply_entry+0x100>
return node;
}
static struct node *lookup_child_by_name_locked(struct node *node, const char *name)
{
for (node = node->child; node; node = node->next) {
23c8: 6af6 ldr r6, [r6, #44] ; 0x2c
23ca: 2e00 cmp r6, #0
23cc: d1f6 bne.n 23bc <fuse_reply_entry+0x34>
23ce: e05f b.n 2490 <fuse_reply_entry+0x108>
}
pthread_mutex_lock(&fuse->lock);
node = acquire_or_create_child_locked(fuse, parent, name, actual_name);
if (!node) {
pthread_mutex_unlock(&fuse->lock);
23d0: 4640 mov r0, r8
23d2: f7fe ee2e blx 1030 <pthread_mutex_unlock@plt>
return -ENOMEM;
23d6: f06f 000b mvn.w r0, #11
23da: e063 b.n 24a4 <fuse_reply_entry+0x11c>
}
memset(&out, 0, sizeof(out));
23dc: f10d 0a70 add.w sl, sp, #112 ; 0x70
return __builtin___strncat_chk(dest, src, n, __bos(dest));
}
__BIONIC_FORTIFY_INLINE
void* memset(void *s, int c, size_t n) {
return __builtin___memset_chk(s, c, n, __builtin_object_size (s, 0));
23e0: 2780 movs r7, #128 ; 0x80
23e2: 2100 movs r1, #0
23e4: 463a mov r2, r7
23e6: 4650 mov r0, sl
23e8: f7fe ee0a blx 1000 <memset@plt>
return actual;
}
static void attr_from_stat(struct fuse_attr *attr, const struct stat *s, const struct node* node)
{
attr->ino = node->nid;
23ec: e9d6 2302 ldrd r2, r3, [r6, #8]
attr->size = s->st_size;
23f0: e9dd 450e ldrd r4, r5, [sp, #56] ; 0x38
attr->blocks = s->st_blocks;
23f4: e9dd 0112 ldrd r0, r1, [sp, #72] ; 0x48
return actual;
}
static void attr_from_stat(struct fuse_attr *attr, const struct stat *s, const struct node* node)
{
attr->ino = node->nid;
23f8: e9cd 2326 strd r2, r3, [sp, #152] ; 0x98
attr->size = s->st_size;
23fc: e9cd 4528 strd r4, r5, [sp, #160] ; 0xa0
attr->blocks = s->st_blocks;
attr->atime = s->st_atime;
attr->mtime = s->st_mtime;
2400: 9b16 ldr r3, [sp, #88] ; 0x58
static void attr_from_stat(struct fuse_attr *attr, const struct stat *s, const struct node* node)
{
attr->ino = node->nid;
attr->size = s->st_size;
attr->blocks = s->st_blocks;
attr->atime = s->st_atime;
2402: 9d14 ldr r5, [sp, #80] ; 0x50
static void attr_from_stat(struct fuse_attr *attr, const struct stat *s, const struct node* node)
{
attr->ino = node->nid;
attr->size = s->st_size;
attr->blocks = s->st_blocks;
2404: e9cd 012a strd r0, r1, [sp, #168] ; 0xa8
attr->atime = s->st_atime;
2408: 2100 movs r1, #0
240a: 912d str r1, [sp, #180] ; 0xb4
240c: 952c str r5, [sp, #176] ; 0xb0
attr->mtime = s->st_mtime;
240e: 932e str r3, [sp, #184] ; 0xb8
2410: 912f str r1, [sp, #188] ; 0xbc
attr->ctime = s->st_ctime;
2412: 9131 str r1, [sp, #196] ; 0xc4
attr->atimensec = s->st_atime_nsec;
attr->mtimensec = s->st_mtime_nsec;
attr->ctimensec = s->st_ctime_nsec;
attr->mode = s->st_mode;
2414: 9d06 ldr r5, [sp, #24]
attr->ino = node->nid;
attr->size = s->st_size;
attr->blocks = s->st_blocks;
attr->atime = s->st_atime;
attr->mtime = s->st_mtime;
attr->ctime = s->st_ctime;
2416: 9a18 ldr r2, [sp, #96] ; 0x60
attr->atimensec = s->st_atime_nsec;
2418: 9c15 ldr r4, [sp, #84] ; 0x54
attr->mtimensec = s->st_mtime_nsec;
241a: 9817 ldr r0, [sp, #92] ; 0x5c
attr->ctimensec = s->st_ctime_nsec;
241c: 9919 ldr r1, [sp, #100] ; 0x64
attr->mode = s->st_mode;
attr->nlink = s->st_nlink;
241e: 9b07 ldr r3, [sp, #28]
attr->mtime = s->st_mtime;
attr->ctime = s->st_ctime;
attr->atimensec = s->st_atime_nsec;
attr->mtimensec = s->st_mtime_nsec;
attr->ctimensec = s->st_ctime_nsec;
attr->mode = s->st_mode;
2420: 9535 str r5, [sp, #212] ; 0xd4
attr->blocks = s->st_blocks;
attr->atime = s->st_atime;
attr->mtime = s->st_mtime;
attr->ctime = s->st_ctime;
attr->atimensec = s->st_atime_nsec;
attr->mtimensec = s->st_mtime_nsec;
2422: 9033 str r0, [sp, #204] ; 0xcc
attr->uid = node->uid;
attr->gid = node->gid;
/* Filter requested mode based on underlying file, and
* pass through file type. */
int owner_mode = s->st_mode & 0700;
2424: f405 70e0 and.w r0, r5, #448 ; 0x1c0
attr->atime = s->st_atime;
attr->mtime = s->st_mtime;
attr->ctime = s->st_ctime;
attr->atimensec = s->st_atime_nsec;
attr->mtimensec = s->st_mtime_nsec;
attr->ctimensec = s->st_ctime_nsec;
2428: 9134 str r1, [sp, #208] ; 0xd0
attr->gid = node->gid;
/* Filter requested mode based on underlying file, and
* pass through file type. */
int owner_mode = s->st_mode & 0700;
int filtered_mode = node->mode & (owner_mode | (owner_mode >> 3) | (owner_mode >> 6));
242a: 1181 asrs r1, r0, #6
attr->ctime = s->st_ctime;
attr->atimensec = s->st_atime_nsec;
attr->mtimensec = s->st_mtime_nsec;
attr->ctimensec = s->st_ctime_nsec;
attr->mode = s->st_mode;
attr->nlink = s->st_nlink;
242c: 9336 str r3, [sp, #216] ; 0xd8
/* Filter requested mode based on underlying file, and
* pass through file type. */
int owner_mode = s->st_mode & 0700;
int filtered_mode = node->mode & (owner_mode | (owner_mode >> 3) | (owner_mode >> 6));
attr->mode = (attr->mode & S_IFMT) | filtered_mode;
242e: f405 4570 and.w r5, r5, #61440 ; 0xf000
attr->ino = node->nid;
attr->size = s->st_size;
attr->blocks = s->st_blocks;
attr->atime = s->st_atime;
attr->mtime = s->st_mtime;
attr->ctime = s->st_ctime;
2432: 9230 str r2, [sp, #192] ; 0xc0
attr->gid = node->gid;
/* Filter requested mode based on underlying file, and
* pass through file type. */
int owner_mode = s->st_mode & 0700;
int filtered_mode = node->mode & (owner_mode | (owner_mode >> 3) | (owner_mode >> 6));
2434: ea41 03d0 orr.w r3, r1, r0, lsr #3
attr->size = s->st_size;
attr->blocks = s->st_blocks;
attr->atime = s->st_atime;
attr->mtime = s->st_mtime;
attr->ctime = s->st_ctime;
attr->atimensec = s->st_atime_nsec;
2438: 9432 str r4, [sp, #200] ; 0xc8
attr->mtimensec = s->st_mtime_nsec;
attr->ctimensec = s->st_ctime_nsec;
attr->mode = s->st_mode;
attr->nlink = s->st_nlink;
attr->uid = node->uid;
243a: 6a32 ldr r2, [r6, #32]
attr->gid = node->gid;
/* Filter requested mode based on underlying file, and
* pass through file type. */
int owner_mode = s->st_mode & 0700;
int filtered_mode = node->mode & (owner_mode | (owner_mode >> 3) | (owner_mode >> 6));
243c: ea43 0c00 orr.w ip, r3, r0
attr->mtimensec = s->st_mtime_nsec;
attr->ctimensec = s->st_ctime_nsec;
attr->mode = s->st_mode;
attr->nlink = s->st_nlink;
attr->uid = node->uid;
2440: 9237 str r2, [sp, #220] ; 0xdc
attr->gid = node->gid;
2442: 6a74 ldr r4, [r6, #36] ; 0x24
2444: 9438 str r4, [sp, #224] ; 0xe0
/* Filter requested mode based on underlying file, and
* pass through file type. */
int owner_mode = s->st_mode & 0700;
int filtered_mode = node->mode & (owner_mode | (owner_mode >> 3) | (owner_mode >> 6));
2446: 8d32 ldrh r2, [r6, #40] ; 0x28
2448: ea0c 0402 and.w r4, ip, r2
attr->mode = (attr->mode & S_IFMT) | filtered_mode;
244c: ea44 0005 orr.w r0, r4, r5
pthread_mutex_unlock(&fuse->lock);
return -ENOMEM;
}
memset(&out, 0, sizeof(out));
attr_from_stat(&out.attr, &s, node);
out.attr_valid = 10;
2450: 240a movs r4, #10
2452: 2500 movs r5, #0
/* Filter requested mode based on underlying file, and
* pass through file type. */
int owner_mode = s->st_mode & 0700;
int filtered_mode = node->mode & (owner_mode | (owner_mode >> 3) | (owner_mode >> 6));
attr->mode = (attr->mode & S_IFMT) | filtered_mode;
2454: 9035 str r0, [sp, #212] ; 0xd4
pthread_mutex_unlock(&fuse->lock);
return -ENOMEM;
}
memset(&out, 0, sizeof(out));
attr_from_stat(&out.attr, &s, node);
out.attr_valid = 10;
2456: e9cd 4522 strd r4, r5, [sp, #136] ; 0x88
out.entry_valid = 10;
out.nodeid = node->nid;
out.generation = node->gen;
pthread_mutex_unlock(&fuse->lock);
245a: 4640 mov r0, r8
return -ENOMEM;
}
memset(&out, 0, sizeof(out));
attr_from_stat(&out.attr, &s, node);
out.attr_valid = 10;
out.entry_valid = 10;
245c: e9cd 4520 strd r4, r5, [sp, #128] ; 0x80
out.nodeid = node->nid;
2460: e9d6 2302 ldrd r2, r3, [r6, #8]
2464: e9cd 231c strd r2, r3, [sp, #112] ; 0x70
out.generation = node->gen;
2468: e9d6 4504 ldrd r4, r5, [r6, #16]
246c: e9cd 451e strd r4, r5, [sp, #120] ; 0x78
pthread_mutex_unlock(&fuse->lock);
2470: f7fe edde blx 1030 <pthread_mutex_unlock@plt>
fuse_reply(fuse, unique, &out, sizeof(out));
2474: 4640 mov r0, r8
2476: f8cd a000 str.w sl, [sp]
247a: 9701 str r7, [sp, #4]
247c: ec53 2b18 vmov r2, r3, d8
2480: f7ff f852 bl 1528 <fuse_reply>
return NO_STATUS;
2484: 2001 movs r0, #1
2486: e00d b.n 24a4 <fuse_reply_entry+0x11c>
return (__u64) (uintptr_t) ptr;
}
static void acquire_node_locked(struct node* node)
{
node->refcount++;
2488: 6833 ldr r3, [r6, #0]
248a: 1c58 adds r0, r3, #1
248c: 6030 str r0, [r6, #0]
248e: e7a5 b.n 23dc <fuse_reply_entry+0x54>
{
struct node* child = lookup_child_by_name_locked(parent, name);
if (child) {
acquire_node_locked(child);
} else {
child = create_node_locked(fuse, parent, name, actual_name);
2490: 4640 mov r0, r8
2492: 4629 mov r1, r5
2494: 4622 mov r2, r4
2496: 9b48 ldr r3, [sp, #288] ; 0x120
2498: f7ff fe52 bl 2140 <create_node_locked>
return -errno;
}
pthread_mutex_lock(&fuse->lock);
node = acquire_or_create_child_locked(fuse, parent, name, actual_name);
if (!node) {
249c: 4606 mov r6, r0
249e: 2800 cmp r0, #0
24a0: d19c bne.n 23dc <fuse_reply_entry+0x54>
24a2: e795 b.n 23d0 <fuse_reply_entry+0x48>
out.nodeid = node->nid;
out.generation = node->gen;
pthread_mutex_unlock(&fuse->lock);
fuse_reply(fuse, unique, &out, sizeof(out));
return NO_STATUS;
}
24a4: b03d add sp, #244 ; 0xf4
24a6: ecbd 8b02 vpop {d8}
24aa: e8bd 85f0 ldmia.w sp!, {r4, r5, r6, r7, r8, sl, pc}
...
000024b0 <handle_lookup.isra.22>:
out.attr_valid = 10;
fuse_reply(fuse, unique, &out, sizeof(out));
return NO_STATUS;
}
static int handle_lookup(struct fuse* fuse, struct fuse_handler* handler,
24b0: 4b2d ldr r3, [pc, #180] ; (2568 <handle_lookup.isra.22+0xb8>)
24b2: e92d 47f0 stmdb sp!, {r4, r5, r6, r7, r8, r9, sl, lr}
24b6: 4615 mov r5, r2
24b8: 4a2c ldr r2, [pc, #176] ; (256c <handle_lookup.isra.22+0xbc>)
24ba: f5ad 5d00 sub.w sp, sp, #8192 ; 0x2000
24be: 447b add r3, pc
24c0: b086 sub sp, #24
24c2: 460f mov r7, r1
24c4: f50d 5100 add.w r1, sp, #8192 ; 0x2000
24c8: f853 8002 ldr.w r8, [r3, r2]
24cc: 4604 mov r4, r0
24ce: 3114 adds r1, #20
char child_path[PATH_MAX];
const char* actual_name;
pthread_mutex_lock(&fuse->lock);
parent_node = lookup_node_and_path_by_id_locked(fuse, hdr->nodeid,
parent_path, sizeof(parent_path));
24d0: f10d 0a14 add.w sl, sp, #20
out.attr_valid = 10;
fuse_reply(fuse, unique, &out, sizeof(out));
return NO_STATUS;
}
static int handle_lookup(struct fuse* fuse, struct fuse_handler* handler,
24d4: f8d8 3000 ldr.w r3, [r8]
24d8: 600b str r3, [r1, #0]
struct node* parent_node;
char parent_path[PATH_MAX];
char child_path[PATH_MAX];
const char* actual_name;
pthread_mutex_lock(&fuse->lock);
24da: f7fe eda4 blx 1024 <pthread_mutex_lock@plt>
parent_node = lookup_node_and_path_by_id_locked(fuse, hdr->nodeid,
24de: e9d7 2304 ldrd r2, r3, [r7, #16]
24e2: 4620 mov r0, r4
24e4: f8cd a000 str.w sl, [sp]
24e8: f7ff fa16 bl 1918 <lookup_node_and_path_by_id_locked.constprop.28>
24ec: 4606 mov r6, r0
parent_path, sizeof(parent_path));
TRACE("[%d] LOOKUP %s @ %llx (%s)\n", handler->token, name, hdr->nodeid,
parent_node ? parent_node->name : "?");
pthread_mutex_unlock(&fuse->lock);
24ee: 4620 mov r0, r4
24f0: f7fe ed9e blx 1030 <pthread_mutex_unlock@plt>
if (!parent_node || !(actual_name = find_file_within(parent_path, name,
24f4: b916 cbnz r6, 24fc <handle_lookup.isra.22+0x4c>
child_path, sizeof(child_path), 1))) {
return -ENOENT;
24f6: f06f 0001 mvn.w r0, #1
24fa: e025 b.n 2548 <handle_lookup.isra.22+0x98>
TRACE("[%d] LOOKUP %s @ %llx (%s)\n", handler->token, name, hdr->nodeid,
parent_node ? parent_node->name : "?");
pthread_mutex_unlock(&fuse->lock);
if (!parent_node || !(actual_name = find_file_within(parent_path, name,
child_path, sizeof(child_path), 1))) {
24fc: f50d 5980 add.w r9, sp, #4096 ; 0x1000
parent_path, sizeof(parent_path));
TRACE("[%d] LOOKUP %s @ %llx (%s)\n", handler->token, name, hdr->nodeid,
parent_node ? parent_node->name : "?");
pthread_mutex_unlock(&fuse->lock);
if (!parent_node || !(actual_name = find_file_within(parent_path, name,
2500: 4650 mov r0, sl
child_path, sizeof(child_path), 1))) {
2502: f109 0914 add.w r9, r9, #20
parent_path, sizeof(parent_path));
TRACE("[%d] LOOKUP %s @ %llx (%s)\n", handler->token, name, hdr->nodeid,
parent_node ? parent_node->name : "?");
pthread_mutex_unlock(&fuse->lock);
if (!parent_node || !(actual_name = find_file_within(parent_path, name,
2506: 4629 mov r1, r5
2508: 464a mov r2, r9
250a: 2301 movs r3, #1
250c: f7ff f9a2 bl 1854 <find_file_within.constprop.27>
2510: 4682 mov sl, r0
2512: 2800 cmp r0, #0
2514: d0ef beq.n 24f6 <handle_lookup.isra.22+0x46>
child_path, sizeof(child_path), 1))) {
return -ENOENT;
}
if (!check_caller_access_to_name(fuse, hdr, parent_node, name, R_OK, false)) {
2516: 2204 movs r2, #4
2518: 2300 movs r3, #0
251a: e88d 000c stmia.w sp, {r2, r3}
251e: 4620 mov r0, r4
2520: 4639 mov r1, r7
2522: 4632 mov r2, r6
2524: 462b mov r3, r5
2526: f7fe ffc7 bl 14b8 <check_caller_access_to_name>
252a: b158 cbz r0, 2544 <handle_lookup.isra.22+0x94>
return -EACCES;
}
return fuse_reply_entry(fuse, hdr->unique, parent_node, name, actual_name, child_path);
252c: e9d7 2302 ldrd r2, r3, [r7, #8]
2530: 4620 mov r0, r4
2532: 9600 str r6, [sp, #0]
2534: 9501 str r5, [sp, #4]
2536: f8cd a008 str.w sl, [sp, #8]
253a: f8cd 900c str.w r9, [sp, #12]
253e: f7ff ff23 bl 2388 <fuse_reply_entry>
2542: e001 b.n 2548 <handle_lookup.isra.22+0x98>
if (!parent_node || !(actual_name = find_file_within(parent_path, name,
child_path, sizeof(child_path), 1))) {
return -ENOENT;
}
if (!check_caller_access_to_name(fuse, hdr, parent_node, name, R_OK, false)) {
return -EACCES;
2544: f06f 000c mvn.w r0, #12
}
return fuse_reply_entry(fuse, hdr->unique, parent_node, name, actual_name, child_path);
}
2548: f50d 5200 add.w r2, sp, #8192 ; 0x2000
254c: 3214 adds r2, #20
254e: 6811 ldr r1, [r2, #0]
2550: f8d8 3000 ldr.w r3, [r8]
2554: 4299 cmp r1, r3
2556: d001 beq.n 255c <handle_lookup.isra.22+0xac>
2558: f7fe ed76 blx 1048 <__stack_chk_fail@plt>
255c: b006 add sp, #24
255e: f50d 5d00 add.w sp, sp, #8192 ; 0x2000
2562: e8bd 87f0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, sl, pc}
2566: bf00 nop
2568: 000029fa .word 0x000029fa
256c: fffffff4 .word 0xfffffff4
00002570 <handle_mknod.isra.23>:
}
}
return fuse_reply_attr(fuse, hdr->unique, node, path);
}
static int handle_mknod(struct fuse* fuse, struct fuse_handler* handler,
2570: e92d 4ff0 stmdb sp!, {r4, r5, r6, r7, r8, r9, sl, fp, lr}
2574: 461f mov r7, r3
2576: 4b37 ldr r3, [pc, #220] ; (2654 <handle_mknod.isra.23+0xe4>)
2578: 4692 mov sl, r2
257a: f5ad 5d00 sub.w sp, sp, #8192 ; 0x2000
257e: 460d mov r5, r1
2580: 4a35 ldr r2, [pc, #212] ; (2658 <handle_mknod.isra.23+0xe8>)
2582: b089 sub sp, #36 ; 0x24
2584: 447b add r3, pc
2586: f50d 5100 add.w r1, sp, #8192 ; 0x2000
258a: 4604 mov r4, r0
258c: 311c adds r1, #28
258e: 589e ldr r6, [r3, r2]
const char* actual_name;
pthread_mutex_lock(&fuse->lock);
has_rw = get_caller_has_rw_locked(fuse, hdr);
parent_node = lookup_node_and_path_by_id_locked(fuse, hdr->nodeid,
parent_path, sizeof(parent_path));
2590: f10d 091c add.w r9, sp, #28
}
}
return fuse_reply_attr(fuse, hdr->unique, node, path);
}
static int handle_mknod(struct fuse* fuse, struct fuse_handler* handler,
2594: 6833 ldr r3, [r6, #0]
2596: 600b str r3, [r1, #0]
struct node* parent_node;
char parent_path[PATH_MAX];
char child_path[PATH_MAX];
const char* actual_name;
pthread_mutex_lock(&fuse->lock);
2598: f7fe ed44 blx 1024 <pthread_mutex_lock@plt>
has_rw = get_caller_has_rw_locked(fuse, hdr);
259c: 4629 mov r1, r5
259e: 4620 mov r0, r4
25a0: f7ff f839 bl 1616 <get_caller_has_rw_locked>
parent_node = lookup_node_and_path_by_id_locked(fuse, hdr->nodeid,
25a4: e9d5 2304 ldrd r2, r3, [r5, #16]
char parent_path[PATH_MAX];
char child_path[PATH_MAX];
const char* actual_name;
pthread_mutex_lock(&fuse->lock);
has_rw = get_caller_has_rw_locked(fuse, hdr);
25a8: 4683 mov fp, r0
parent_node = lookup_node_and_path_by_id_locked(fuse, hdr->nodeid,
25aa: f8cd 9000 str.w r9, [sp]
25ae: 4620 mov r0, r4
25b0: f7ff f9b2 bl 1918 <lookup_node_and_path_by_id_locked.constprop.28>
25b4: 4680 mov r8, r0
parent_path, sizeof(parent_path));
TRACE("[%d] MKNOD %s 0%o @ %llx (%s)\n", handler->token,
name, req->mode, hdr->nodeid, parent_node ? parent_node->name : "?");
pthread_mutex_unlock(&fuse->lock);
25b6: 4620 mov r0, r4
25b8: f7fe ed3a blx 1030 <pthread_mutex_unlock@plt>
25bc: 9605 str r6, [sp, #20]
if (!parent_node || !(actual_name = find_file_within(parent_path, name,
25be: f1b8 0f00 cmp.w r8, #0
25c2: d102 bne.n 25ca <handle_mknod.isra.23+0x5a>
child_path, sizeof(child_path), 1))) {
return -ENOENT;
25c4: f06f 0001 mvn.w r0, #1
25c8: e035 b.n 2636 <handle_mknod.isra.23+0xc6>
TRACE("[%d] MKNOD %s 0%o @ %llx (%s)\n", handler->token,
name, req->mode, hdr->nodeid, parent_node ? parent_node->name : "?");
pthread_mutex_unlock(&fuse->lock);
if (!parent_node || !(actual_name = find_file_within(parent_path, name,
child_path, sizeof(child_path), 1))) {
25ca: f50d 5680 add.w r6, sp, #4096 ; 0x1000
parent_path, sizeof(parent_path));
TRACE("[%d] MKNOD %s 0%o @ %llx (%s)\n", handler->token,
name, req->mode, hdr->nodeid, parent_node ? parent_node->name : "?");
pthread_mutex_unlock(&fuse->lock);
if (!parent_node || !(actual_name = find_file_within(parent_path, name,
25ce: 4648 mov r0, r9
child_path, sizeof(child_path), 1))) {
25d0: 361c adds r6, #28
parent_path, sizeof(parent_path));
TRACE("[%d] MKNOD %s 0%o @ %llx (%s)\n", handler->token,
name, req->mode, hdr->nodeid, parent_node ? parent_node->name : "?");
pthread_mutex_unlock(&fuse->lock);
if (!parent_node || !(actual_name = find_file_within(parent_path, name,
25d2: 4639 mov r1, r7
25d4: 4632 mov r2, r6
25d6: 2301 movs r3, #1
25d8: f7ff f93c bl 1854 <find_file_within.constprop.27>
25dc: 4681 mov r9, r0
25de: 2800 cmp r0, #0
25e0: d0f0 beq.n 25c4 <handle_mknod.isra.23+0x54>
child_path, sizeof(child_path), 1))) {
return -ENOENT;
}
if (!check_caller_access_to_name(fuse, hdr, parent_node, name, W_OK, has_rw)) {
25e2: 2302 movs r3, #2
25e4: 4620 mov r0, r4
25e6: e88d 0808 stmia.w sp, {r3, fp}
25ea: 4629 mov r1, r5
25ec: 4642 mov r2, r8
25ee: 463b mov r3, r7
25f0: f7fe ff62 bl 14b8 <check_caller_access_to_name>
25f4: b1e8 cbz r0, 2632 <handle_mknod.isra.23+0xc2>
return -EACCES;
}
__u32 mode = (req->mode & (~0777)) | 0664;
25f6: f8da 0000 ldr.w r0, [sl]
25fa: f400 427e and.w r2, r0, #65024 ; 0xfe00
if (mknod(child_path, mode, req->rdev) < 0) {
25fe: 4630 mov r0, r6
2600: f442 71da orr.w r1, r2, #436 ; 0x1b4
2604: f8da 2004 ldr.w r2, [sl, #4]
2608: f7fe edb4 blx 1174 <mknod@plt>
260c: 2800 cmp r0, #0
260e: da04 bge.n 261a <handle_mknod.isra.23+0xaa>
return -errno;
2610: f7fe ecf0 blx ff4 <__errno@plt>
2614: 6803 ldr r3, [r0, #0]
2616: 4258 negs r0, r3
2618: e00d b.n 2636 <handle_mknod.isra.23+0xc6>
}
return fuse_reply_entry(fuse, hdr->unique, parent_node, name, actual_name, child_path);
261a: e9d5 2302 ldrd r2, r3, [r5, #8]
261e: 4620 mov r0, r4
2620: f8cd 8000 str.w r8, [sp]
2624: 9701 str r7, [sp, #4]
2626: f8cd 9008 str.w r9, [sp, #8]
262a: 9603 str r6, [sp, #12]
262c: f7ff feac bl 2388 <fuse_reply_entry>
2630: e001 b.n 2636 <handle_mknod.isra.23+0xc6>
if (!parent_node || !(actual_name = find_file_within(parent_path, name,
child_path, sizeof(child_path), 1))) {
return -ENOENT;
}
if (!check_caller_access_to_name(fuse, hdr, parent_node, name, W_OK, has_rw)) {
return -EACCES;
2632: f06f 000c mvn.w r0, #12
__u32 mode = (req->mode & (~0777)) | 0664;
if (mknod(child_path, mode, req->rdev) < 0) {
return -errno;
}
return fuse_reply_entry(fuse, hdr->unique, parent_node, name, actual_name, child_path);
}
2636: 9b05 ldr r3, [sp, #20]
2638: f50d 5100 add.w r1, sp, #8192 ; 0x2000
263c: 311c adds r1, #28
263e: 680a ldr r2, [r1, #0]
2640: 6819 ldr r1, [r3, #0]
2642: 428a cmp r2, r1
2644: d001 beq.n 264a <handle_mknod.isra.23+0xda>
2646: f7fe ed00 blx 1048 <__stack_chk_fail@plt>
264a: b009 add sp, #36 ; 0x24
264c: f50d 5d00 add.w sp, sp, #8192 ; 0x2000
2650: e8bd 8ff0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, sl, fp, pc}
2654: 00002934 .word 0x00002934
2658: fffffff4 .word 0xfffffff4
0000265c <handle_mkdir.isra.24>:
static int handle_mkdir(struct fuse* fuse, struct fuse_handler* handler,
265c: e92d 4ff0 stmdb sp!, {r4, r5, r6, r7, r8, r9, sl, fp, lr}
2660: 461d mov r5, r3
2662: f8df 9180 ldr.w r9, [pc, #384] ; 27e4 <handle_mkdir.isra.24+0x188>
2666: f5ad 5d40 sub.w sp, sp, #12288 ; 0x3000
266a: b089 sub sp, #36 ; 0x24
266c: 4688 mov r8, r1
266e: 4b5e ldr r3, [pc, #376] ; (27e8 <handle_mkdir.isra.24+0x18c>)
2670: f50d 5140 add.w r1, sp, #12288 ; 0x3000
2674: 44f9 add r9, pc
2676: 9204 str r2, [sp, #16]
2678: 4604 mov r4, r0
267a: 311c adds r1, #28
267c: f859 7003 ldr.w r7, [r9, r3]
const char* actual_name;
pthread_mutex_lock(&fuse->lock);
has_rw = get_caller_has_rw_locked(fuse, hdr);
parent_node = lookup_node_and_path_by_id_locked(fuse, hdr->nodeid,
parent_path, sizeof(parent_path));
2680: f10d 0a1c add.w sl, sp, #28
return -errno;
}
return fuse_reply_entry(fuse, hdr->unique, parent_node, name, actual_name, child_path);
}
static int handle_mkdir(struct fuse* fuse, struct fuse_handler* handler,
2684: 683a ldr r2, [r7, #0]
2686: 600a str r2, [r1, #0]
struct node* parent_node;
char parent_path[PATH_MAX];
char child_path[PATH_MAX];
const char* actual_name;
pthread_mutex_lock(&fuse->lock);
2688: f7fe eccc blx 1024 <pthread_mutex_lock@plt>
has_rw = get_caller_has_rw_locked(fuse, hdr);
268c: 4641 mov r1, r8
268e: 4620 mov r0, r4
2690: f7fe ffc1 bl 1616 <get_caller_has_rw_locked>
parent_node = lookup_node_and_path_by_id_locked(fuse, hdr->nodeid,
2694: e9d8 2304 ldrd r2, r3, [r8, #16]
char parent_path[PATH_MAX];
char child_path[PATH_MAX];
const char* actual_name;
pthread_mutex_lock(&fuse->lock);
has_rw = get_caller_has_rw_locked(fuse, hdr);
2698: 4683 mov fp, r0
parent_node = lookup_node_and_path_by_id_locked(fuse, hdr->nodeid,
269a: f8cd a000 str.w sl, [sp]
269e: 4620 mov r0, r4
26a0: f7ff f93a bl 1918 <lookup_node_and_path_by_id_locked.constprop.28>
26a4: 4606 mov r6, r0
parent_path, sizeof(parent_path));
TRACE("[%d] MKDIR %s 0%o @ %llx (%s)\n", handler->token,
name, req->mode, hdr->nodeid, parent_node ? parent_node->name : "?");
pthread_mutex_unlock(&fuse->lock);
26a6: 4620 mov r0, r4
26a8: f7fe ecc2 blx 1030 <pthread_mutex_unlock@plt>
26ac: 9705 str r7, [sp, #20]
if (!parent_node || !(actual_name = find_file_within(parent_path, name,
26ae: b906 cbnz r6, 26b2 <handle_mkdir.isra.24+0x56>
26b0: e079 b.n 27a6 <handle_mkdir.isra.24+0x14a>
child_path, sizeof(child_path), 1))) {
26b2: f50d 5780 add.w r7, sp, #4096 ; 0x1000
parent_path, sizeof(parent_path));
TRACE("[%d] MKDIR %s 0%o @ %llx (%s)\n", handler->token,
name, req->mode, hdr->nodeid, parent_node ? parent_node->name : "?");
pthread_mutex_unlock(&fuse->lock);
if (!parent_node || !(actual_name = find_file_within(parent_path, name,
26b6: 4650 mov r0, sl
child_path, sizeof(child_path), 1))) {
26b8: 371c adds r7, #28
parent_path, sizeof(parent_path));
TRACE("[%d] MKDIR %s 0%o @ %llx (%s)\n", handler->token,
name, req->mode, hdr->nodeid, parent_node ? parent_node->name : "?");
pthread_mutex_unlock(&fuse->lock);
if (!parent_node || !(actual_name = find_file_within(parent_path, name,
26ba: 4629 mov r1, r5
26bc: 463a mov r2, r7
26be: 2301 movs r3, #1
26c0: f7ff f8c8 bl 1854 <find_file_within.constprop.27>
26c4: 4682 mov sl, r0
26c6: 2800 cmp r0, #0
26c8: d06d beq.n 27a6 <handle_mkdir.isra.24+0x14a>
child_path, sizeof(child_path), 1))) {
return -ENOENT;
}
if (!check_caller_access_to_name(fuse, hdr, parent_node, name, W_OK, has_rw)) {
26ca: 2302 movs r3, #2
26cc: 4620 mov r0, r4
26ce: e88d 0808 stmia.w sp, {r3, fp}
26d2: 4641 mov r1, r8
26d4: 4632 mov r2, r6
26d6: 462b mov r3, r5
26d8: f7fe feee bl 14b8 <check_caller_access_to_name>
26dc: 2800 cmp r0, #0
26de: d070 beq.n 27c2 <handle_mkdir.isra.24+0x166>
return -EACCES;
}
__u32 mode = (req->mode & (~0777)) | 0775;
26e0: 9804 ldr r0, [sp, #16]
26e2: 6803 ldr r3, [r0, #0]
if (mkdir(child_path, mode) < 0) {
26e4: 4638 mov r0, r7
return -ENOENT;
}
if (!check_caller_access_to_name(fuse, hdr, parent_node, name, W_OK, has_rw)) {
return -EACCES;
}
__u32 mode = (req->mode & (~0777)) | 0775;
26e6: f403 427e and.w r2, r3, #65024 ; 0xfe00
if (mkdir(child_path, mode) < 0) {
26ea: f442 7cfe orr.w ip, r2, #508 ; 0x1fc
26ee: f04c 0101 orr.w r1, ip, #1
26f2: f7fe ed46 blx 1180 <mkdir@plt>
26f6: 2800 cmp r0, #0
26f8: da04 bge.n 2704 <handle_mkdir.isra.24+0xa8>
return -errno;
26fa: f7fe ec7c blx ff4 <__errno@plt>
26fe: 6803 ldr r3, [r0, #0]
2700: 4258 negs r0, r3
2702: e060 b.n 27c6 <handle_mkdir.isra.24+0x16a>
}
/* When creating /Android/data and /Android/obb, mark them as .nomedia */
if (parent_node->perm == PERM_ANDROID && !strcasecmp(name, "data")) {
2704: 69b1 ldr r1, [r6, #24]
2706: 2903 cmp r1, #3
2708: d122 bne.n 2750 <handle_mkdir.isra.24+0xf4>
270a: 4938 ldr r1, [pc, #224] ; (27ec <handle_mkdir.isra.24+0x190>)
270c: 4628 mov r0, r5
270e: 4479 add r1, pc
2710: f7fe ec46 blx fa0 <strcasecmp@plt>
2714: b9e0 cbnz r0, 2750 <handle_mkdir.isra.24+0xf4>
#else
__BIONIC_FORTIFY_INLINE
__printflike(3, 4)
int snprintf(char *dest, size_t size, const char *format, ...)
{
return __builtin___snprintf_chk(dest, size, 0,
2716: 4a36 ldr r2, [pc, #216] ; (27f0 <handle_mkdir.isra.24+0x194>)
2718: f50d 5000 add.w r0, sp, #8192 ; 0x2000
271c: 301c adds r0, #28
271e: f44f 5180 mov.w r1, #4096 ; 0x1000
2722: 463b mov r3, r7
2724: 447a add r2, pc
2726: f7fe ed32 blx 118c <snprintf@plt>
char nomedia[PATH_MAX];
snprintf(nomedia, PATH_MAX, "%s/.nomedia", child_path);
if (touch(nomedia, 0664) != 0) {
272a: f50d 5000 add.w r0, sp, #8192 ; 0x2000
272e: 301c adds r0, #28
2730: f7ff f866 bl 1800 <touch.constprop.26>
2734: b160 cbz r0, 2750 <handle_mkdir.isra.24+0xf4>
ERROR("Failed to touch(%s): %s\n", nomedia, strerror(errno));
2736: f7fe ec5e blx ff4 <__errno@plt>
273a: 6800 ldr r0, [r0, #0]
273c: f7fe eca2 blx 1084 <strerror@plt>
2740: 492c ldr r1, [pc, #176] ; (27f4 <handle_mkdir.isra.24+0x198>)
2742: 4603 mov r3, r0
2744: f859 0001 ldr.w r0, [r9, r1]
2748: 492b ldr r1, [pc, #172] ; (27f8 <handle_mkdir.isra.24+0x19c>)
274a: 30a8 adds r0, #168 ; 0xa8
274c: 4479 add r1, pc
274e: e025 b.n 279c <handle_mkdir.isra.24+0x140>
return -ENOENT;
}
}
if (parent_node->perm == PERM_ANDROID && !strcasecmp(name, "obb")) {
2750: 69b0 ldr r0, [r6, #24]
2752: 2803 cmp r0, #3
2754: d12a bne.n 27ac <handle_mkdir.isra.24+0x150>
2756: 4929 ldr r1, [pc, #164] ; (27fc <handle_mkdir.isra.24+0x1a0>)
2758: 4628 mov r0, r5
275a: 4479 add r1, pc
275c: f7fe ec20 blx fa0 <strcasecmp@plt>
2760: bb20 cbnz r0, 27ac <handle_mkdir.isra.24+0x150>
2762: 4a27 ldr r2, [pc, #156] ; (2800 <handle_mkdir.isra.24+0x1a4>)
2764: f50d 5000 add.w r0, sp, #8192 ; 0x2000
2768: 301c adds r0, #28
276a: f44f 5180 mov.w r1, #4096 ; 0x1000
276e: f104 0370 add.w r3, r4, #112 ; 0x70
2772: 447a add r2, pc
2774: f7fe ed0a blx 118c <snprintf@plt>
char nomedia[PATH_MAX];
snprintf(nomedia, PATH_MAX, "%s/.nomedia", fuse->obbpath);
if (touch(nomedia, 0664) != 0) {
2778: f50d 5000 add.w r0, sp, #8192 ; 0x2000
277c: 301c adds r0, #28
277e: f7ff f83f bl 1800 <touch.constprop.26>
2782: b198 cbz r0, 27ac <handle_mkdir.isra.24+0x150>
ERROR("Failed to touch(%s): %s\n", nomedia, strerror(errno));
2784: f7fe ec36 blx ff4 <__errno@plt>
2788: 6800 ldr r0, [r0, #0]
278a: f7fe ec7c blx 1084 <strerror@plt>
278e: 4a19 ldr r2, [pc, #100] ; (27f4 <handle_mkdir.isra.24+0x198>)
2790: 4603 mov r3, r0
2792: 491c ldr r1, [pc, #112] ; (2804 <handle_mkdir.isra.24+0x1a8>)
2794: f859 0002 ldr.w r0, [r9, r2]
2798: 4479 add r1, pc
279a: 30a8 adds r0, #168 ; 0xa8
279c: f50d 5200 add.w r2, sp, #8192 ; 0x2000
27a0: 321c adds r2, #28
27a2: f7fe ebf8 blx f94 <fprintf@plt>
return -ENOENT;
27a6: f06f 0001 mvn.w r0, #1
27aa: e00c b.n 27c6 <handle_mkdir.isra.24+0x16a>
}
}
return fuse_reply_entry(fuse, hdr->unique, parent_node, name, actual_name, child_path);
27ac: e9d8 2302 ldrd r2, r3, [r8, #8]
27b0: 4620 mov r0, r4
27b2: 9600 str r6, [sp, #0]
27b4: 9501 str r5, [sp, #4]
27b6: f8cd a008 str.w sl, [sp, #8]
27ba: 9703 str r7, [sp, #12]
27bc: f7ff fde4 bl 2388 <fuse_reply_entry>
27c0: e001 b.n 27c6 <handle_mkdir.isra.24+0x16a>
if (!parent_node || !(actual_name = find_file_within(parent_path, name,
child_path, sizeof(child_path), 1))) {
return -ENOENT;
}
if (!check_caller_access_to_name(fuse, hdr, parent_node, name, W_OK, has_rw)) {
return -EACCES;
27c2: f06f 000c mvn.w r0, #12
return -ENOENT;
}
}
return fuse_reply_entry(fuse, hdr->unique, parent_node, name, actual_name, child_path);
}
27c6: 9905 ldr r1, [sp, #20]
27c8: f50d 5240 add.w r2, sp, #12288 ; 0x3000
27cc: 321c adds r2, #28
27ce: 6812 ldr r2, [r2, #0]
27d0: 680b ldr r3, [r1, #0]
27d2: 429a cmp r2, r3
27d4: d001 beq.n 27da <handle_mkdir.isra.24+0x17e>
27d6: f7fe ec38 blx 1048 <__stack_chk_fail@plt>
27da: b009 add sp, #36 ; 0x24
27dc: f50d 5d40 add.w sp, sp, #12288 ; 0x3000
27e0: e8bd 8ff0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, sl, fp, pc}
27e4: 00002844 .word 0x00002844
27e8: fffffff4 .word 0xfffffff4
27ec: 0000102d .word 0x0000102d
27f0: 00001025 .word 0x00001025
27f4: fffffff0 .word 0xfffffff0
27f8: 00001009 .word 0x00001009
27fc: 00000fe6 .word 0x00000fe6
2800: 00000fd7 .word 0x00000fd7
2804: 00000fbd .word 0x00000fbd
00002808 <handle_fuse_requests>:
}
}
}
static void handle_fuse_requests(struct fuse_handler* handler)
{
2808: e92d 4ff0 stmdb sp!, {r4, r5, r6, r7, r8, r9, sl, fp, lr}
280c: 4606 mov r6, r0
for (;;) {
ssize_t len = read(fuse->fd,
handler->request_buffer, sizeof(handler->request_buffer));
if (len < 0) {
if (errno != EINTR) {
ERROR("[%d] handle_fuse_requests: errno=%d\n", handler->token, errno);
280e: f8df 92ac ldr.w r9, [pc, #684] ; 2abc <handle_fuse_requests+0x2b4>
continue;
}
const struct fuse_in_header *hdr = (void*)handler->request_buffer;
if (hdr->len != (size_t)len) {
ERROR("[%d] malformed header: len=%zu, hdr->len=%u\n",
2812: f8df a2ac ldr.w sl, [pc, #684] ; 2ac0 <handle_fuse_requests+0x2b8>
}
continue;
}
if ((size_t)len < sizeof(struct fuse_in_header)) {
ERROR("[%d] request too short: len=%zu\n", handler->token, (size_t)len);
2816: f8df b2ac ldr.w fp, [pc, #684] ; 2ac4 <handle_fuse_requests+0x2bc>
for (;;) {
ssize_t len = read(fuse->fd,
handler->request_buffer, sizeof(handler->request_buffer));
if (len < 0) {
if (errno != EINTR) {
ERROR("[%d] handle_fuse_requests: errno=%d\n", handler->token, errno);
281a: 44f9 add r9, pc
}
}
}
static void handle_fuse_requests(struct fuse_handler* handler)
{
281c: ed2d 8b02 vpush {d8}
2820: b08b sub sp, #44 ; 0x2c
struct fuse* fuse = handler->fuse;
2822: 6807 ldr r7, [r0, #0]
continue;
}
const struct fuse_in_header *hdr = (void*)handler->request_buffer;
if (hdr->len != (size_t)len) {
ERROR("[%d] malformed header: len=%zu, hdr->len=%u\n",
2824: 44fa add sl, pc
}
}
}
static void handle_fuse_requests(struct fuse_handler* handler)
{
2826: f8df 82a0 ldr.w r8, [pc, #672] ; 2ac8 <handle_fuse_requests+0x2c0>
}
continue;
}
if ((size_t)len < sizeof(struct fuse_in_header)) {
ERROR("[%d] request too short: len=%zu\n", handler->token, (size_t)len);
282a: 44fb add fp, pc
}
}
}
static void handle_fuse_requests(struct fuse_handler* handler)
{
282c: 44f8 add r8, pc
struct fuse* fuse = handler->fuse;
for (;;) {
ssize_t len = read(fuse->fd,
handler->request_buffer, sizeof(handler->request_buffer));
282e: f106 0408 add.w r4, r6, #8
static void handle_fuse_requests(struct fuse_handler* handler)
{
struct fuse* fuse = handler->fuse;
for (;;) {
ssize_t len = read(fuse->fd,
2832: 6938 ldr r0, [r7, #16]
2834: 4621 mov r1, r4
2836: 4aa0 ldr r2, [pc, #640] ; (2ab8 <handle_fuse_requests+0x2b0>)
2838: f7fe ecae blx 1198 <read@plt>
handler->request_buffer, sizeof(handler->request_buffer));
if (len < 0) {
283c: 1e03 subs r3, r0, #0
283e: da0b bge.n 2858 <handle_fuse_requests+0x50>
if (errno != EINTR) {
2840: f7fe ebd8 blx ff4 <__errno@plt>
2844: 6802 ldr r2, [r0, #0]
2846: 2a04 cmp r2, #4
2848: d0f1 beq.n 282e <handle_fuse_requests+0x26>
ERROR("[%d] handle_fuse_requests: errno=%d\n", handler->token, errno);
284a: 4da0 ldr r5, [pc, #640] ; (2acc <handle_fuse_requests+0x2c4>)
284c: 4649 mov r1, r9
284e: 6803 ldr r3, [r0, #0]
2850: f858 0005 ldr.w r0, [r8, r5]
2854: 30a8 adds r0, #168 ; 0xa8
2856: e006 b.n 2866 <handle_fuse_requests+0x5e>
}
continue;
}
if ((size_t)len < sizeof(struct fuse_in_header)) {
2858: 2b27 cmp r3, #39 ; 0x27
285a: d808 bhi.n 286e <handle_fuse_requests+0x66>
ERROR("[%d] request too short: len=%zu\n", handler->token, (size_t)len);
285c: 489b ldr r0, [pc, #620] ; (2acc <handle_fuse_requests+0x2c4>)
285e: 4659 mov r1, fp
2860: f858 0000 ldr.w r0, [r8, r0]
2864: 30a8 adds r0, #168 ; 0xa8
2866: 6872 ldr r2, [r6, #4]
2868: f7fe eb94 blx f94 <fprintf@plt>
continue;
286c: e7df b.n 282e <handle_fuse_requests+0x26>
}
const struct fuse_in_header *hdr = (void*)handler->request_buffer;
if (hdr->len != (size_t)len) {
286e: 68b2 ldr r2, [r6, #8]
2870: 429a cmp r2, r3
2872: d009 beq.n 2888 <handle_fuse_requests+0x80>
ERROR("[%d] malformed header: len=%zu, hdr->len=%u\n",
2874: 4c95 ldr r4, [pc, #596] ; (2acc <handle_fuse_requests+0x2c4>)
2876: 4651 mov r1, sl
2878: f858 0004 ldr.w r0, [r8, r4]
287c: 9200 str r2, [sp, #0]
287e: 6872 ldr r2, [r6, #4]
2880: 30a8 adds r0, #168 ; 0xa8
2882: f7fe eb88 blx f94 <fprintf@plt>
handler->token, (size_t)len, hdr->len);
continue;
2886: e7d2 b.n 282e <handle_fuse_requests+0x26>
}
static int handle_fuse_request(struct fuse *fuse, struct fuse_handler* handler,
const struct fuse_in_header *hdr, const void *data, size_t data_len)
{
switch (hdr->opcode) {
2888: 68f3 ldr r3, [r6, #12]
ERROR("[%d] malformed header: len=%zu, hdr->len=%u\n",
handler->token, (size_t)len, hdr->len);
continue;
}
const void *data = handler->request_buffer + sizeof(struct fuse_in_header);
288a: f106 0230 add.w r2, r6, #48 ; 0x30
size_t data_len = len - sizeof(struct fuse_in_header);
__u64 unique = hdr->unique;
288e: ed96 8b04 vldr d8, [r6, #16]
}
static int handle_fuse_request(struct fuse *fuse, struct fuse_handler* handler,
const struct fuse_in_header *hdr, const void *data, size_t data_len)
{
switch (hdr->opcode) {
2892: 1e59 subs r1, r3, #1
2894: 291c cmp r1, #28
2896: f200 8106 bhi.w 2aa6 <handle_fuse_requests+0x29e>
289a: e8df f011 tbh [pc, r1, lsl #1]
289e: 001d .short 0x001d
28a0: 00470022 .word 0x00470022
28a4: 0104004c .word 0x0104004c
28a8: 01040104 .word 0x01040104
28ac: 00580051 .word 0x00580051
28b0: 0064005f .word 0x0064005f
28b4: 01040069 .word 0x01040069
28b8: 007e0079 .word 0x007e0079
28bc: 00ae0096 .word 0x00ae0096
28c0: 010400b3 .word 0x010400b3
28c4: 010400b8 .word 0x010400b8
28c8: 01040104 .word 0x01040104
28cc: 00f80104 .word 0x00f80104
28d0: 00c900db .word 0x00c900db
28d4: 00d300ce .word 0x00d300ce
case FUSE_LOOKUP: { /* bytez[] -> entry_out */
const char* name = data;
return handle_lookup(fuse, handler, hdr, name);
28d8: 4638 mov r0, r7
28da: 4621 mov r1, r4
28dc: f7ff fde8 bl 24b0 <handle_lookup.isra.22>
28e0: e0d2 b.n 2a88 <handle_fuse_requests+0x280>
static int handle_forget(struct fuse* fuse, struct fuse_handler* handler,
const struct fuse_in_header *hdr, const struct fuse_forget_in *req)
{
struct node* node;
pthread_mutex_lock(&fuse->lock);
28e2: 4638 mov r0, r7
28e4: f7fe eb9e blx 1024 <pthread_mutex_lock@plt>
node = lookup_node_by_id_locked(fuse, hdr->nodeid);
28e8: e9d6 2306 ldrd r2, r3, [r6, #24]
return 0;
}
static struct node *lookup_node_by_id_locked(struct fuse *fuse, __u64 nid)
{
if (nid == FUSE_ROOT_ID) {
28ec: 2b00 cmp r3, #0
28ee: bf08 it eq
28f0: 2a01 cmpeq r2, #1
28f2: d102 bne.n 28fa <handle_fuse_requests+0xf2>
return &fuse->root;
28f4: f107 0320 add.w r3, r7, #32
28f8: e005 b.n 2906 <handle_fuse_requests+0xfe>
pthread_mutex_lock(&fuse->lock);
node = lookup_node_by_id_locked(fuse, hdr->nodeid);
TRACE("[%d] FORGET #%lld @ %llx (%s)\n", handler->token, req->nlookup,
hdr->nodeid, node ? node->name : "?");
if (node) {
28fa: 4613 mov r3, r2
28fc: b91a cbnz r2, 2906 <handle_fuse_requests+0xfe>
__u64 n = req->nlookup;
while (n--) {
release_node_locked(node);
}
}
pthread_mutex_unlock(&fuse->lock);
28fe: 4638 mov r0, r7
2900: f7fe eb96 blx 1030 <pthread_mutex_unlock@plt>
2904: e793 b.n 282e <handle_fuse_requests+0x26>
pthread_mutex_lock(&fuse->lock);
node = lookup_node_by_id_locked(fuse, hdr->nodeid);
TRACE("[%d] FORGET #%lld @ %llx (%s)\n", handler->token, req->nlookup,
hdr->nodeid, node ? node->name : "?");
if (node) {
__u64 n = req->nlookup;
2906: e9d6 450c ldrd r4, r5, [r6, #48] ; 0x30
290a: ed9f 8b69 vldr d8, [pc, #420] ; 2ab0 <handle_fuse_requests+0x2a8>
290e: e009 b.n 2924 <handle_fuse_requests+0x11c>
while (n--) {
release_node_locked(node);
2910: 4618 mov r0, r3
2912: 9303 str r3, [sp, #12]
2914: f7fe fe36 bl 1584 <release_node_locked>
2918: ec51 0b18 vmov r0, r1, d8
291c: 9b03 ldr r3, [sp, #12]
291e: 1824 adds r4, r4, r0
2920: eb45 0501 adc.w r5, r5, r1
node = lookup_node_by_id_locked(fuse, hdr->nodeid);
TRACE("[%d] FORGET #%lld @ %llx (%s)\n", handler->token, req->nlookup,
hdr->nodeid, node ? node->name : "?");
if (node) {
__u64 n = req->nlookup;
while (n--) {
2924: ea54 0105 orrs.w r1, r4, r5
2928: d1f2 bne.n 2910 <handle_fuse_requests+0x108>
292a: e7e8 b.n 28fe <handle_fuse_requests+0xf6>
return handle_forget(fuse, handler, hdr, req);
}
case FUSE_GETATTR: { /* getattr_in -> attr_out */
const struct fuse_getattr_in *req = data;
return handle_getattr(fuse, handler, hdr, req);
292c: 4638 mov r0, r7
292e: 4621 mov r1, r4
2930: f7ff fa10 bl 1d54 <handle_getattr.isra.5>
2934: e0a8 b.n 2a88 <handle_fuse_requests+0x280>
}
case FUSE_SETATTR: { /* setattr_in -> attr_out */
const struct fuse_setattr_in *req = data;
return handle_setattr(fuse, handler, hdr, req);
2936: 4638 mov r0, r7
2938: 4621 mov r1, r4
293a: f7ff fa57 bl 1dec <handle_setattr.isra.13>
293e: e0a3 b.n 2a88 <handle_fuse_requests+0x280>
// case FUSE_READLINK:
// case FUSE_SYMLINK:
case FUSE_MKNOD: { /* mknod_in, bytez[] -> entry_out */
const struct fuse_mknod_in *req = data;
const char *name = ((const char*) data) + sizeof(*req);
return handle_mknod(fuse, handler, hdr, req, name);
2940: 4638 mov r0, r7
2942: 4621 mov r1, r4
2944: f106 0340 add.w r3, r6, #64 ; 0x40
2948: f7ff fe12 bl 2570 <handle_mknod.isra.23>
294c: e09c b.n 2a88 <handle_fuse_requests+0x280>
}
case FUSE_MKDIR: { /* mkdir_in, bytez[] -> entry_out */
const struct fuse_mkdir_in *req = data;
const char *name = ((const char*) data) + sizeof(*req);
return handle_mkdir(fuse, handler, hdr, req, name);
294e: 4638 mov r0, r7
2950: 4621 mov r1, r4
2952: f106 0338 add.w r3, r6, #56 ; 0x38
2956: f7ff fe81 bl 265c <handle_mkdir.isra.24>
295a: e095 b.n 2a88 <handle_fuse_requests+0x280>
}
case FUSE_UNLINK: { /* bytez[] -> */
const char* name = data;
return handle_unlink(fuse, handler, hdr, name);
295c: 4638 mov r0, r7
295e: 4621 mov r1, r4
2960: f7ff f850 bl 1a04 <handle_unlink.isra.15>
2964: e090 b.n 2a88 <handle_fuse_requests+0x280>
}
case FUSE_RMDIR: { /* bytez[] -> */
const char* name = data;
return handle_rmdir(fuse, handler, hdr, name);
2966: 4638 mov r0, r7
2968: 4621 mov r1, r4
296a: f7fe ffe9 bl 1940 <handle_rmdir.isra.16>
296e: e08b b.n 2a88 <handle_fuse_requests+0x280>
}
case FUSE_RENAME: { /* rename_in, oldname, newname -> */
const struct fuse_rename_in *req = data;
const char *old_name = ((const char*) data) + sizeof(*req);
2970: f106 0538 add.w r5, r6, #56 ; 0x38
size_t bos = __bos(s);
#if !defined(__clang__)
// Compiler doesn't know destination size. Don't call __strlen_chk
if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
return __builtin_strlen(s);
2974: 9203 str r2, [sp, #12]
2976: 4628 mov r0, r5
2978: f7fe eb18 blx fac <strlen@plt>
const char *new_name = old_name + strlen(old_name) + 1;
297c: 1c41 adds r1, r0, #1
return handle_rename(fuse, handler, hdr, req, old_name, new_name);
297e: 9a03 ldr r2, [sp, #12]
}
case FUSE_RENAME: { /* rename_in, oldname, newname -> */
const struct fuse_rename_in *req = data;
const char *old_name = ((const char*) data) + sizeof(*req);
const char *new_name = old_name + strlen(old_name) + 1;
2980: 186b adds r3, r5, r1
return handle_rename(fuse, handler, hdr, req, old_name, new_name);
2982: 4638 mov r0, r7
2984: 9300 str r3, [sp, #0]
2986: 4621 mov r1, r4
2988: 462b mov r3, r5
298a: f7ff fab5 bl 1ef8 <handle_rename.isra.17>
298e: e07b b.n 2a88 <handle_fuse_requests+0x280>
}
// case FUSE_LINK:
case FUSE_OPEN: { /* open_in -> open_out */
const struct fuse_open_in *req = data;
return handle_open(fuse, handler, hdr, req);
2990: 4638 mov r0, r7
2992: 4621 mov r1, r4
2994: f7ff f898 bl 1ac8 <handle_open.isra.14>
2998: e076 b.n 2a88 <handle_fuse_requests+0x280>
static int handle_read(struct fuse* fuse, struct fuse_handler* handler,
const struct fuse_in_header* hdr, const struct fuse_read_in* req)
{
struct handle *h = id_to_ptr(req->fh);
__u64 unique = hdr->unique;
__u32 size = req->size;
299a: 6c32 ldr r2, [r6, #64] ; 0x40
};
};
static inline void *id_to_ptr(__u64 nid)
{
return (void *) (uintptr_t) nid;
299c: 6b33 ldr r3, [r6, #48] ; 0x30
const struct fuse_in_header* hdr, const struct fuse_read_in* req)
{
struct handle *h = id_to_ptr(req->fh);
__u64 unique = hdr->unique;
__u32 size = req->size;
__u64 offset = req->offset;
299e: e9d6 010e ldrd r0, r1, [r6, #56] ; 0x38
* overlaps the request buffer and will clobber data in the request. This
* saves us 128KB per request handler thread at the cost of this scary comment. */
TRACE("[%d] READ %p(%d) %u@%llu\n", handler->token,
h, h->fd, size, offset);
if (size > sizeof(handler->read_buffer)) {
29a2: f5b2 3f00 cmp.w r2, #131072 ; 0x20000
29a6: d80d bhi.n 29c4 <handle_fuse_requests+0x1bc>
return -EINVAL;
}
res = pread64(h->fd, handler->read_buffer, size, offset);
29a8: f106 0508 add.w r5, r6, #8
29ac: e9cd 0100 strd r0, r1, [sp]
29b0: 4629 mov r1, r5
29b2: 6818 ldr r0, [r3, #0]
29b4: f7fe ebf6 blx 11a4 <pread64@plt>
if (res < 0) {
29b8: 2800 cmp r0, #0
29ba: da00 bge.n 29be <handle_fuse_requests+0x1b6>
29bc: e033 b.n 2a26 <handle_fuse_requests+0x21e>
return -errno;
}
fuse_reply(fuse, unique, handler->read_buffer, res);
29be: 9500 str r5, [sp, #0]
29c0: 9001 str r0, [sp, #4]
29c2: e05b b.n 2a7c <handle_fuse_requests+0x274>
* saves us 128KB per request handler thread at the cost of this scary comment. */
TRACE("[%d] READ %p(%d) %u@%llu\n", handler->token,
h, h->fd, size, offset);
if (size > sizeof(handler->read_buffer)) {
return -EINVAL;
29c4: f06f 0015 mvn.w r0, #21
29c8: e062 b.n 2a90 <handle_fuse_requests+0x288>
struct handle *h = id_to_ptr(req->fh);
int res;
TRACE("[%d] WRITE %p(%d) %u@%llu\n", handler->token,
h, h->fd, req->size, req->offset);
res = pwrite64(h->fd, buffer, req->size, req->offset);
29ca: e9d6 010e ldrd r0, r1, [r6, #56] ; 0x38
29ce: 6b35 ldr r5, [r6, #48] ; 0x30
29d0: 6c32 ldr r2, [r6, #64] ; 0x40
29d2: e9cd 0100 strd r0, r1, [sp]
29d6: f106 0158 add.w r1, r6, #88 ; 0x58
29da: 6828 ldr r0, [r5, #0]
29dc: f7fe ebe8 blx 11b0 <pwrite64@plt>
if (res < 0) {
29e0: 2800 cmp r0, #0
29e2: da00 bge.n 29e6 <handle_fuse_requests+0x1de>
29e4: e01f b.n 2a26 <handle_fuse_requests+0x21e>
return -errno;
}
out.size = res;
29e6: a90a add r1, sp, #40 ; 0x28
fuse_reply(fuse, hdr->unique, &out, sizeof(out));
29e8: 2408 movs r4, #8
h, h->fd, req->size, req->offset);
res = pwrite64(h->fd, buffer, req->size, req->offset);
if (res < 0) {
return -errno;
}
out.size = res;
29ea: f841 0d18 str.w r0, [r1, #-24]!
fuse_reply(fuse, hdr->unique, &out, sizeof(out));
29ee: 4638 mov r0, r7
29f0: e9d6 2304 ldrd r2, r3, [r6, #16]
29f4: 9100 str r1, [sp, #0]
29f6: 9401 str r4, [sp, #4]
29f8: e043 b.n 2a82 <handle_fuse_requests+0x27a>
const void* buffer = (const __u8*)data + sizeof(*req);
return handle_write(fuse, handler, hdr, req, buffer);
}
case FUSE_STATFS: { /* getattr_in -> attr_out */
return handle_statfs(fuse, handler, hdr);
29fa: 4638 mov r0, r7
29fc: 4621 mov r1, r4
29fe: f7fe fe1b bl 1638 <handle_statfs.isra.19>
2a02: e041 b.n 2a88 <handle_fuse_requests+0x280>
};
};
static inline void *id_to_ptr(__u64 nid)
{
return (void *) (uintptr_t) nid;
2a04: 6b35 ldr r5, [r6, #48] ; 0x30
const struct fuse_in_header* hdr, const struct fuse_release_in* req)
{
struct handle *h = id_to_ptr(req->fh);
TRACE("[%d] RELEASE %p(%d)\n", handler->token, h, h->fd);
close(h->fd);
2a06: 6828 ldr r0, [r5, #0]
2a08: f7fe eb42 blx 1090 <close@plt>
2a0c: e01e b.n 2a4c <handle_fuse_requests+0x244>
}
static int handle_fsync(struct fuse* fuse, struct fuse_handler* handler,
const struct fuse_in_header* hdr, const struct fuse_fsync_in* req)
{
int is_data_sync = req->fsync_flags & 1;
2a0e: 6bb2 ldr r2, [r6, #56] ; 0x38
};
};
static inline void *id_to_ptr(__u64 nid)
{
return (void *) (uintptr_t) nid;
2a10: 6b33 ldr r3, [r6, #48] ; 0x30
struct handle *h = id_to_ptr(req->fh);
int res;
TRACE("[%d] FSYNC %p(%d) is_data_sync=%d\n", handler->token,
h, h->fd, is_data_sync);
res = is_data_sync ? fdatasync(h->fd) : fsync(h->fd);
2a12: 07d1 lsls r1, r2, #31
2a14: 6818 ldr r0, [r3, #0]
2a16: d502 bpl.n 2a1e <handle_fuse_requests+0x216>
2a18: f7fe ebd0 blx 11bc <fdatasync@plt>
2a1c: e001 b.n 2a22 <handle_fuse_requests+0x21a>
2a1e: f7fe ebd4 blx 11c8 <fsync@plt>
if (res < 0) {
2a22: 2800 cmp r0, #0
2a24: da33 bge.n 2a8e <handle_fuse_requests+0x286>
return -errno;
2a26: f7fe eae6 blx ff4 <__errno@plt>
2a2a: 6802 ldr r2, [r0, #0]
2a2c: 4250 negs r0, r2
2a2e: e02b b.n 2a88 <handle_fuse_requests+0x280>
return handle_flush(fuse, handler, hdr);
}
case FUSE_OPENDIR: { /* open_in -> open_out */
const struct fuse_open_in *req = data;
return handle_opendir(fuse, handler, hdr, req);
2a30: 4638 mov r0, r7
2a32: 4621 mov r1, r4
2a34: f7ff f8c6 bl 1bc4 <handle_opendir.isra.10>
2a38: e026 b.n 2a88 <handle_fuse_requests+0x280>
}
case FUSE_READDIR: {
const struct fuse_read_in *req = data;
return handle_readdir(fuse, handler, hdr, req);
2a3a: 4638 mov r0, r7
2a3c: 4621 mov r1, r4
2a3e: f7fe fe63 bl 1708 <handle_readdir.isra.21>
2a42: e021 b.n 2a88 <handle_fuse_requests+0x280>
};
};
static inline void *id_to_ptr(__u64 nid)
{
return (void *) (uintptr_t) nid;
2a44: 6b35 ldr r5, [r6, #48] ; 0x30
const struct fuse_in_header* hdr, const struct fuse_release_in* req)
{
struct dirhandle *h = id_to_ptr(req->fh);
TRACE("[%d] RELEASEDIR %p\n", handler->token, h);
closedir(h->d);
2a46: 6828 ldr r0, [r5, #0]
2a48: f7fe eb34 blx 10b4 <closedir@plt>
free(h);
2a4c: 4628 mov r0, r5
2a4e: f7fe eac6 blx fdc <free@plt>
2a52: e01c b.n 2a8e <handle_fuse_requests+0x286>
TRACE("[%d] INIT ver=%d.%d maxread=%d flags=%x\n",
handler->token, req->major, req->minor, req->max_readahead, req->flags);
out.major = FUSE_KERNEL_VERSION;
out.minor = FUSE_KERNEL_MINOR_VERSION;
out.max_readahead = req->max_readahead;
2a54: 6bb2 ldr r2, [r6, #56] ; 0x38
{
struct fuse_init_out out;
TRACE("[%d] INIT ver=%d.%d maxread=%d flags=%x\n",
handler->token, req->major, req->minor, req->max_readahead, req->flags);
out.major = FUSE_KERNEL_VERSION;
2a56: 2007 movs r0, #7
out.minor = FUSE_KERNEL_MINOR_VERSION;
2a58: 240d movs r4, #13
out.max_readahead = req->max_readahead;
out.flags = FUSE_ATOMIC_O_TRUNC | FUSE_BIG_WRITES;
out.max_background = 32;
2a5a: 2120 movs r1, #32
{
struct fuse_init_out out;
TRACE("[%d] INIT ver=%d.%d maxread=%d flags=%x\n",
handler->token, req->major, req->minor, req->max_readahead, req->flags);
out.major = FUSE_KERNEL_VERSION;
2a5c: 9004 str r0, [sp, #16]
out.minor = FUSE_KERNEL_MINOR_VERSION;
out.max_readahead = req->max_readahead;
out.flags = FUSE_ATOMIC_O_TRUNC | FUSE_BIG_WRITES;
2a5e: 2328 movs r3, #40 ; 0x28
struct fuse_init_out out;
TRACE("[%d] INIT ver=%d.%d maxread=%d flags=%x\n",
handler->token, req->major, req->minor, req->max_readahead, req->flags);
out.major = FUSE_KERNEL_VERSION;
out.minor = FUSE_KERNEL_MINOR_VERSION;
2a60: 9405 str r4, [sp, #20]
out.max_readahead = req->max_readahead;
out.flags = FUSE_ATOMIC_O_TRUNC | FUSE_BIG_WRITES;
out.max_background = 32;
out.congestion_threshold = 32;
out.max_write = MAX_WRITE;
2a62: f44f 2580 mov.w r5, #262144 ; 0x40000
fuse_reply(fuse, hdr->unique, &out, sizeof(out));
2a66: a804 add r0, sp, #16
2a68: 2418 movs r4, #24
TRACE("[%d] INIT ver=%d.%d maxread=%d flags=%x\n",
handler->token, req->major, req->minor, req->max_readahead, req->flags);
out.major = FUSE_KERNEL_VERSION;
out.minor = FUSE_KERNEL_MINOR_VERSION;
out.max_readahead = req->max_readahead;
2a6a: 9206 str r2, [sp, #24]
out.flags = FUSE_ATOMIC_O_TRUNC | FUSE_BIG_WRITES;
2a6c: 9307 str r3, [sp, #28]
out.max_background = 32;
2a6e: f8ad 1020 strh.w r1, [sp, #32]
out.congestion_threshold = 32;
2a72: f8ad 1022 strh.w r1, [sp, #34] ; 0x22
out.max_write = MAX_WRITE;
2a76: 9509 str r5, [sp, #36] ; 0x24
fuse_reply(fuse, hdr->unique, &out, sizeof(out));
2a78: 9000 str r0, [sp, #0]
2a7a: 9401 str r4, [sp, #4]
2a7c: 4638 mov r0, r7
2a7e: ec53 2b18 vmov r2, r3, d8
2a82: f7fe fd51 bl 1528 <fuse_reply>
2a86: e6d2 b.n 282e <handle_fuse_requests+0x26>
int res = handle_fuse_request(fuse, handler, hdr, data, data_len);
/* We do not access the request again after this point because the underlying
* buffer storage may have been reused while processing the request. */
if (res != NO_STATUS) {
2a88: 2801 cmp r0, #1
2a8a: d101 bne.n 2a90 <handle_fuse_requests+0x288>
2a8c: e6cf b.n 282e <handle_fuse_requests+0x26>
// case FUSE_SETXATTR:
// case FUSE_GETXATTR:
// case FUSE_LISTXATTR:
// case FUSE_REMOVEXATTR:
case FUSE_FLUSH: {
return handle_flush(fuse, handler, hdr);
2a8e: 2000 movs r0, #0
}
static void fuse_status(struct fuse *fuse, __u64 unique, int err)
{
struct fuse_out_header hdr;
hdr.len = sizeof(hdr);
2a90: 2210 movs r2, #16
hdr.error = err;
2a92: 9005 str r0, [sp, #20]
}
static void fuse_status(struct fuse *fuse, __u64 unique, int err)
{
struct fuse_out_header hdr;
hdr.len = sizeof(hdr);
2a94: 9204 str r2, [sp, #16]
hdr.error = err;
hdr.unique = unique;
write(fuse->fd, &hdr, sizeof(hdr));
2a96: eb0d 0102 add.w r1, sp, r2
static void fuse_status(struct fuse *fuse, __u64 unique, int err)
{
struct fuse_out_header hdr;
hdr.len = sizeof(hdr);
hdr.error = err;
hdr.unique = unique;
2a9a: ed8d 8b06 vstr d8, [sp, #24]
write(fuse->fd, &hdr, sizeof(hdr));
2a9e: 6938 ldr r0, [r7, #16]
2aa0: f7fe eb98 blx 11d4 <write@plt>
2aa4: e6c3 b.n 282e <handle_fuse_requests+0x26>
}
default: {
TRACE("[%d] NOTIMPL op=%d uniq=%llx nid=%llx\n",
handler->token, hdr->opcode, hdr->unique, hdr->nodeid);
return -ENOSYS;
2aa6: f06f 0025 mvn.w r0, #37 ; 0x25
2aaa: e7f1 b.n 2a90 <handle_fuse_requests+0x288>
2aac: f3af 8000 nop.w
2ab0: ffffffff .word 0xffffffff
2ab4: ffffffff .word 0xffffffff
2ab8: 00040050 .word 0x00040050
2abc: 00000f54 .word 0x00000f54
2ac0: 00000f90 .word 0x00000f90
2ac4: 00000f69 .word 0x00000f69
2ac8: 0000268c .word 0x0000268c
2acc: fffffff0 .word 0xfffffff0
00002ad0 <run>:
return 1;
}
static int run(const char* source_path, const char* dest_path, uid_t uid,
gid_t gid, gid_t write_gid, int num_threads, derive_t derive,
bool split_perms) {
2ad0: e92d 4ff0 stmdb sp!, {r4, r5, r6, r7, r8, r9, sl, fp, lr}
2ad4: 4699 mov r9, r3
2ad6: f8df 4530 ldr.w r4, [pc, #1328] ; 3008 <run+0x538>
2ada: f5ad 5dcc sub.w sp, sp, #6528 ; 0x1980
2ade: b087 sub sp, #28
2ae0: 4617 mov r7, r2
2ae2: f8df 3528 ldr.w r3, [pc, #1320] ; 300c <run+0x53c>
2ae6: 468a mov sl, r1
2ae8: 447c add r4, pc
}
return __open_real(pathname, flags, __builtin_va_arg_pack());
2aea: f8df b524 ldr.w fp, [pc, #1316] ; 3010 <run+0x540>
2aee: 4606 mov r6, r0
2af0: f50d 51cc add.w r1, sp, #6528 ; 0x1980
2af4: f854 8003 ldr.w r8, [r4, r3]
2af8: f50d 50ce add.w r0, sp, #6592 ; 0x19c0
2afc: 3008 adds r0, #8
2afe: 3114 adds r1, #20
2b00: 6805 ldr r5, [r0, #0]
2b02: 44fb add fp, pc
2b04: f8d8 2000 ldr.w r2, [r8]
char opts[256];
int res;
struct fuse fuse;
/* cleanup from previous instance, if necessary */
umount2(dest_path, 2);
2b08: 4650 mov r0, sl
return 1;
}
static int run(const char* source_path, const char* dest_path, uid_t uid,
gid_t gid, gid_t write_gid, int num_threads, derive_t derive,
bool split_perms) {
2b0a: 600a str r2, [r1, #0]
char opts[256];
int res;
struct fuse fuse;
/* cleanup from previous instance, if necessary */
umount2(dest_path, 2);
2b0c: 2102 movs r1, #2
2b0e: f7fe eb68 blx 11e0 <umount2@plt>
2b12: 2102 movs r1, #2
2b14: 4658 mov r0, fp
2b16: f7fe eab0 blx 1078 <open@plt>
fd = open("/dev/fuse", O_RDWR);
if (fd < 0){
2b1a: 2800 cmp r0, #0
2b1c: f8cd 800c str.w r8, [sp, #12]
2b20: 9002 str r0, [sp, #8]
2b22: da12 bge.n 2b4a <run+0x7a>
ERROR("cannot open fuse device: %s\n", strerror(errno));
2b24: f8df a4ec ldr.w sl, [pc, #1260] ; 3014 <run+0x544>
2b28: f7fe ea64 blx ff4 <__errno@plt>
2b2c: 6800 ldr r0, [r0, #0]
2b2e: f7fe eaaa blx 1084 <strerror@plt>
2b32: f8df 14e4 ldr.w r1, [pc, #1252] ; 3018 <run+0x548>
2b36: 4602 mov r2, r0
2b38: f854 000a ldr.w r0, [r4, sl]
return -1;
2b3c: f04f 3aff mov.w sl, #4294967295 ; 0xffffffff
/* cleanup from previous instance, if necessary */
umount2(dest_path, 2);
fd = open("/dev/fuse", O_RDWR);
if (fd < 0){
ERROR("cannot open fuse device: %s\n", strerror(errno));
2b40: 4479 add r1, pc
2b42: 30a8 adds r0, #168 ; 0xa8
2b44: f7fe ea26 blx f94 <fprintf@plt>
2b48: e24c b.n 2fe4 <run+0x514>
2b4a: f8df 24d0 ldr.w r2, [pc, #1232] ; 301c <run+0x54c>
return -1;
}
snprintf(opts, sizeof(opts),
2b4e: f10d 0818 add.w r8, sp, #24
2b52: f44f 7180 mov.w r1, #256 ; 0x100
2b56: 9b02 ldr r3, [sp, #8]
2b58: e88d 0280 stmia.w sp, {r7, r9}
2b5c: 4640 mov r0, r8
2b5e: 447a add r2, pc
2b60: f7fe eb14 blx 118c <snprintf@plt>
"fd=%i,rootmode=40000,default_permissions,allow_other,user_id=%d,group_id=%d",
fd, uid, gid);
res = mount("/dev/fuse", dest_path, "fuse", MS_NOSUID | MS_NODEV, opts);
2b64: f8df 24b8 ldr.w r2, [pc, #1208] ; 3020 <run+0x550>
2b68: 4651 mov r1, sl
2b6a: 2306 movs r3, #6
2b6c: f8cd 8000 str.w r8, [sp]
2b70: 4658 mov r0, fp
2b72: 447a add r2, pc
2b74: f7fe eb3a blx 11ec <mount@plt>
if (res < 0) {
2b78: f1b0 0a00 subs.w sl, r0, #0
2b7c: da0d bge.n 2b9a <run+0xca>
ERROR("cannot mount fuse filesystem: %s\n", strerror(errno));
2b7e: f7fe ea3a blx ff4 <__errno@plt>
2b82: 6800 ldr r0, [r0, #0]
2b84: f7fe ea7e blx 1084 <strerror@plt>
2b88: f8df 1488 ldr.w r1, [pc, #1160] ; 3014 <run+0x544>
2b8c: 4602 mov r2, r0
2b8e: 5860 ldr r0, [r4, r1]
2b90: f8df 1490 ldr.w r1, [pc, #1168] ; 3024 <run+0x554>
2b94: 30a8 adds r0, #168 ; 0xa8
2b96: 4479 add r1, pc
2b98: e03e b.n 2c18 <run+0x148>
goto error;
}
res = setgroups(sizeof(kGroups) / sizeof(kGroups[0]), kGroups);
2b9a: f8df 148c ldr.w r1, [pc, #1164] ; 3028 <run+0x558>
2b9e: 2001 movs r0, #1
2ba0: 4479 add r1, pc
2ba2: f7fe eb2a blx 11f8 <setgroups@plt>
if (res < 0) {
2ba6: f1b0 0a00 subs.w sl, r0, #0
2baa: da0d bge.n 2bc8 <run+0xf8>
ERROR("cannot setgroups: %s\n", strerror(errno));
2bac: f7fe ea22 blx ff4 <__errno@plt>
2bb0: 6800 ldr r0, [r0, #0]
2bb2: f7fe ea68 blx 1084 <strerror@plt>
2bb6: 4602 mov r2, r0
2bb8: f8df 0458 ldr.w r0, [pc, #1112] ; 3014 <run+0x544>
2bbc: f8df 146c ldr.w r1, [pc, #1132] ; 302c <run+0x55c>
2bc0: 5820 ldr r0, [r4, r0]
2bc2: 4479 add r1, pc
2bc4: 30a8 adds r0, #168 ; 0xa8
2bc6: e027 b.n 2c18 <run+0x148>
goto error;
}
res = setgid(gid);
2bc8: 4648 mov r0, r9
2bca: f7fe eb1c blx 1204 <setgid@plt>
if (res < 0) {
2bce: f1b0 0a00 subs.w sl, r0, #0
2bd2: da0d bge.n 2bf0 <run+0x120>
ERROR("cannot setgid: %s\n", strerror(errno));
2bd4: f7fe ea0e blx ff4 <__errno@plt>
2bd8: 6800 ldr r0, [r0, #0]
2bda: f7fe ea54 blx 1084 <strerror@plt>
2bde: f8df 3434 ldr.w r3, [pc, #1076] ; 3014 <run+0x544>
2be2: 4602 mov r2, r0
2be4: f8df 1448 ldr.w r1, [pc, #1096] ; 3030 <run+0x560>
2be8: 58e0 ldr r0, [r4, r3]
2bea: 4479 add r1, pc
2bec: 30a8 adds r0, #168 ; 0xa8
2bee: e013 b.n 2c18 <run+0x148>
goto error;
}
res = setuid(uid);
2bf0: 4638 mov r0, r7
2bf2: f7fe eb0e blx 1210 <setuid@plt>
if (res < 0) {
2bf6: f1b0 0a00 subs.w sl, r0, #0
2bfa: da10 bge.n 2c1e <run+0x14e>
ERROR("cannot setuid: %s\n", strerror(errno));
2bfc: f7fe e9fa blx ff4 <__errno@plt>
2c00: 6800 ldr r0, [r0, #0]
2c02: f7fe ea40 blx 1084 <strerror@plt>
2c06: f8df c40c ldr.w ip, [pc, #1036] ; 3014 <run+0x544>
2c0a: 4602 mov r2, r0
2c0c: f8df 1424 ldr.w r1, [pc, #1060] ; 3034 <run+0x564>
2c10: f854 000c ldr.w r0, [r4, ip]
2c14: 4479 add r1, pc
2c16: 30a8 adds r0, #168 ; 0xa8
2c18: f7fe e9bc blx f94 <fprintf@plt>
goto error;
2c1c: e1df b.n 2fde <run+0x50e>
return child;
}
static void fuse_init(struct fuse *fuse, int fd, const char *source_path,
gid_t write_gid, derive_t derive, bool split_perms) {
pthread_mutex_init(&fuse->lock, NULL);
2c1e: f60d 1718 addw r7, sp, #2328 ; 0x918
2c22: 2100 movs r1, #0
2c24: 4638 mov r0, r7
fuse->split_perms = split_perms;
fuse->write_gid = write_gid;
memset(&fuse->root, 0, sizeof(fuse->root));
fuse->root.nid = FUSE_ROOT_ID; /* 1 */
fuse->root.refcount = 2;
2c26: f04f 0802 mov.w r8, #2
return child;
}
static void fuse_init(struct fuse *fuse, int fd, const char *source_path,
gid_t write_gid, derive_t derive, bool split_perms) {
pthread_mutex_init(&fuse->lock, NULL);
2c2a: f7fe eaf8 blx 121c <pthread_mutex_init@plt>
fuse->fd = fd;
2c2e: 9802 ldr r0, [sp, #8]
fuse->next_generation = 0;
2c30: 2100 movs r1, #0
fuse->derive = derive;
fuse->split_perms = split_perms;
2c32: f50d 53ce add.w r3, sp, #6592 ; 0x19c0
gid_t write_gid, derive_t derive, bool split_perms) {
pthread_mutex_init(&fuse->lock, NULL);
fuse->fd = fd;
fuse->next_generation = 0;
fuse->derive = derive;
2c36: 617d str r5, [r7, #20]
fuse->split_perms = split_perms;
2c38: 330c adds r3, #12
static void fuse_init(struct fuse *fuse, int fd, const char *source_path,
gid_t write_gid, derive_t derive, bool split_perms) {
pthread_mutex_init(&fuse->lock, NULL);
fuse->fd = fd;
2c3a: 6138 str r0, [r7, #16]
fuse->next_generation = 0;
2c3c: 2000 movs r0, #0
2c3e: e9c7 0102 strd r0, r1, [r7, #8]
fuse->derive = derive;
fuse->split_perms = split_perms;
fuse->write_gid = write_gid;
2c42: f50d 51ce add.w r1, sp, #6592 ; 0x19c0
pthread_mutex_init(&fuse->lock, NULL);
fuse->fd = fd;
fuse->next_generation = 0;
fuse->derive = derive;
fuse->split_perms = split_perms;
2c46: 781a ldrb r2, [r3, #0]
fuse->write_gid = write_gid;
2c48: 6808 ldr r0, [r1, #0]
return __builtin___strncat_chk(dest, src, n, __bos(dest));
}
__BIONIC_FORTIFY_INLINE
void* memset(void *s, int c, size_t n) {
return __builtin___memset_chk(s, c, n, __builtin_object_size (s, 0));
2c4a: 2100 movs r1, #0
pthread_mutex_init(&fuse->lock, NULL);
fuse->fd = fd;
fuse->next_generation = 0;
fuse->derive = derive;
fuse->split_perms = split_perms;
2c4c: 763a strb r2, [r7, #24]
2c4e: 2250 movs r2, #80 ; 0x50
fuse->write_gid = write_gid;
2c50: 61f8 str r0, [r7, #28]
2c52: f60d 1038 addw r0, sp, #2360 ; 0x938
2c56: f7fe e9d4 blx 1000 <memset@plt>
memset(&fuse->root, 0, sizeof(fuse->root));
fuse->root.nid = FUSE_ROOT_ID; /* 1 */
2c5a: 2100 movs r1, #0
2c5c: 2001 movs r0, #1
2c5e: e9c7 010a strd r0, r1, [r7, #40] ; 0x28
size_t bos = __bos(s);
#if !defined(__clang__)
// Compiler doesn't know destination size. Don't call __strlen_chk
if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
return __builtin_strlen(s);
2c62: 4630 mov r0, r6
fuse->root.refcount = 2;
2c64: f8c7 8020 str.w r8, [r7, #32]
2c68: f7fe e9a0 blx fac <strlen@plt>
fuse->root.namelen = strlen(source_path);
2c6c: 65b8 str r0, [r7, #88] ; 0x58
fuse->root.name = strdup(source_path);
2c6e: 4630 mov r0, r6
2c70: f7fe eada blx 1228 <strdup@plt>
fuse->root.userid = 0;
fuse->root.uid = AID_ROOT;
/* Set up root node for various modes of operation */
switch (derive) {
2c74: 2d01 cmp r5, #1
memset(&fuse->root, 0, sizeof(fuse->root));
fuse->root.nid = FUSE_ROOT_ID; /* 1 */
fuse->root.refcount = 2;
fuse->root.namelen = strlen(source_path);
fuse->root.name = strdup(source_path);
2c76: 65f8 str r0, [r7, #92] ; 0x5c
fuse->root.userid = 0;
fuse->root.uid = AID_ROOT;
/* Set up root node for various modes of operation */
switch (derive) {
2c78: d00d beq.n 2c96 <run+0x1c6>
2c7a: d302 bcc.n 2c82 <run+0x1b2>
2c7c: 4545 cmp r5, r8
2c7e: d160 bne.n 2d42 <run+0x272>
2c80: e03b b.n 2cfa <run+0x22a>
case DERIVE_NONE:
/* Traditional behavior that treats entire device as being accessible
* to sdcard_rw, and no permissions are derived. */
fuse->root.perm = PERM_ROOT;
fuse->root.mode = 0775;
2c82: f240 16fd movw r6, #509 ; 0x1fd
/* Set up root node for various modes of operation */
switch (derive) {
case DERIVE_NONE:
/* Traditional behavior that treats entire device as being accessible
* to sdcard_rw, and no permissions are derived. */
fuse->root.perm = PERM_ROOT;
2c86: f8c7 8038 str.w r8, [r7, #56] ; 0x38
fuse->root.mode = 0775;
fuse->root.gid = AID_SDCARD_RW;
2c8a: f506 72fd add.w r2, r6, #506 ; 0x1fa
switch (derive) {
case DERIVE_NONE:
/* Traditional behavior that treats entire device as being accessible
* to sdcard_rw, and no permissions are derived. */
fuse->root.perm = PERM_ROOT;
fuse->root.mode = 0775;
2c8e: f8a7 6048 strh.w r6, [r7, #72] ; 0x48
fuse->root.gid = AID_SDCARD_RW;
2c92: 647a str r2, [r7, #68] ; 0x44
2c94: e055 b.n 2d42 <run+0x272>
case DERIVE_LEGACY:
/* Legacy behavior used to support internal multiuser layout which
* places user_id at the top directory level, with the actual roots
* just below that. Shared OBB path is also at top level. */
fuse->root.perm = PERM_LEGACY_PRE_ROOT;
fuse->root.mode = 0771;
2c96: f240 11f9 movw r1, #505 ; 0x1f9
fuse->root.gid = AID_SDCARD_R;
fuse->package_to_appid = hashmapCreate(256, str_hash, str_icase_equals);
2c9a: 4ae7 ldr r2, [pc, #924] ; (3038 <run+0x568>)
case DERIVE_LEGACY:
/* Legacy behavior used to support internal multiuser layout which
* places user_id at the top directory level, with the actual roots
* just below that. Shared OBB path is also at top level. */
fuse->root.perm = PERM_LEGACY_PRE_ROOT;
fuse->root.mode = 0771;
2c9c: f8a7 1048 strh.w r1, [r7, #72] ; 0x48
fuse->root.gid = AID_SDCARD_R;
2ca0: f240 4004 movw r0, #1028 ; 0x404
fuse->package_to_appid = hashmapCreate(256, str_hash, str_icase_equals);
2ca4: 49e5 ldr r1, [pc, #916] ; (303c <run+0x56c>)
fuse->appid_with_rw = hashmapCreate(128, int_hash, int_equals);
snprintf(fuse->obbpath, sizeof(fuse->obbpath), "%s/obb", source_path);
2ca6: f107 0a70 add.w sl, r7, #112 ; 0x70
/* Legacy behavior used to support internal multiuser layout which
* places user_id at the top directory level, with the actual roots
* just below that. Shared OBB path is also at top level. */
fuse->root.perm = PERM_LEGACY_PRE_ROOT;
fuse->root.mode = 0771;
fuse->root.gid = AID_SDCARD_R;
2caa: 6478 str r0, [r7, #68] ; 0x44
fuse->package_to_appid = hashmapCreate(256, str_hash, str_icase_equals);
2cac: 447a add r2, pc
2cae: f44f 7080 mov.w r0, #256 ; 0x100
break;
case DERIVE_LEGACY:
/* Legacy behavior used to support internal multiuser layout which
* places user_id at the top directory level, with the actual roots
* just below that. Shared OBB path is also at top level. */
fuse->root.perm = PERM_LEGACY_PRE_ROOT;
2cb2: 63bd str r5, [r7, #56] ; 0x38
fuse->root.mode = 0771;
fuse->root.gid = AID_SDCARD_R;
fuse->package_to_appid = hashmapCreate(256, str_hash, str_icase_equals);
2cb4: 4479 add r1, pc
2cb6: f507 5583 add.w r5, r7, #4192 ; 0x1060
2cba: f7fe eabc blx 1234 <hashmapCreate@plt>
fuse->appid_with_rw = hashmapCreate(128, int_hash, int_equals);
2cbe: 49e0 ldr r1, [pc, #896] ; (3040 <run+0x570>)
2cc0: 4ae0 ldr r2, [pc, #896] ; (3044 <run+0x574>)
* places user_id at the top directory level, with the actual roots
* just below that. Shared OBB path is also at top level. */
fuse->root.perm = PERM_LEGACY_PRE_ROOT;
fuse->root.mode = 0771;
fuse->root.gid = AID_SDCARD_R;
fuse->package_to_appid = hashmapCreate(256, str_hash, str_icase_equals);
2cc2: 6128 str r0, [r5, #16]
fuse->appid_with_rw = hashmapCreate(128, int_hash, int_equals);
2cc4: 2080 movs r0, #128 ; 0x80
2cc6: 4479 add r1, pc
2cc8: 447a add r2, pc
2cca: f7fe eab4 blx 1234 <hashmapCreate@plt>
2cce: 4ade ldr r2, [pc, #888] ; (3048 <run+0x578>)
2cd0: 4633 mov r3, r6
2cd2: f44f 5180 mov.w r1, #4096 ; 0x1000
2cd6: 6168 str r0, [r5, #20]
2cd8: 4650 mov r0, sl
2cda: 447a add r2, pc
2cdc: f7fe ea56 blx 118c <snprintf@plt>
snprintf(fuse->obbpath, sizeof(fuse->obbpath), "%s/obb", source_path);
fs_prepare_dir(fuse->obbpath, 0775, getuid(), getgid());
2ce0: f7fe eaae blx 1240 <getuid@plt>
2ce4: 4680 mov r8, r0
2ce6: f7fe eab2 blx 124c <getgid@plt>
2cea: f240 11fd movw r1, #509 ; 0x1fd
2cee: 4603 mov r3, r0
2cf0: 4642 mov r2, r8
2cf2: 4650 mov r0, sl
2cf4: f7fe eab0 blx 1258 <fs_prepare_dir@plt>
2cf8: e023 b.n 2d42 <run+0x272>
/* Unified multiuser layout which places secondary user_id under
* /Android/user and shared OBB path under /Android/obb. */
fuse->root.perm = PERM_ROOT;
fuse->root.mode = 0771;
fuse->root.gid = AID_SDCARD_R;
fuse->package_to_appid = hashmapCreate(256, str_hash, str_icase_equals);
2cfa: 49d4 ldr r1, [pc, #848] ; (304c <run+0x57c>)
case DERIVE_UNIFIED:
/* Unified multiuser layout which places secondary user_id under
* /Android/user and shared OBB path under /Android/obb. */
fuse->root.perm = PERM_ROOT;
fuse->root.mode = 0771;
fuse->root.gid = AID_SDCARD_R;
2cfc: f240 4304 movw r3, #1028 ; 0x404
fuse->package_to_appid = hashmapCreate(256, str_hash, str_icase_equals);
2d00: 4ad3 ldr r2, [pc, #844] ; (3050 <run+0x580>)
2d02: f44f 7080 mov.w r0, #256 ; 0x100
fs_prepare_dir(fuse->obbpath, 0775, getuid(), getgid());
break;
case DERIVE_UNIFIED:
/* Unified multiuser layout which places secondary user_id under
* /Android/user and shared OBB path under /Android/obb. */
fuse->root.perm = PERM_ROOT;
2d06: 63bd str r5, [r7, #56] ; 0x38
fuse->root.mode = 0771;
2d08: f240 15f9 movw r5, #505 ; 0x1f9
fuse->root.gid = AID_SDCARD_R;
fuse->package_to_appid = hashmapCreate(256, str_hash, str_icase_equals);
2d0c: 4479 add r1, pc
case DERIVE_UNIFIED:
/* Unified multiuser layout which places secondary user_id under
* /Android/user and shared OBB path under /Android/obb. */
fuse->root.perm = PERM_ROOT;
fuse->root.mode = 0771;
fuse->root.gid = AID_SDCARD_R;
2d0e: 647b str r3, [r7, #68] ; 0x44
fuse->package_to_appid = hashmapCreate(256, str_hash, str_icase_equals);
2d10: 447a add r2, pc
break;
case DERIVE_UNIFIED:
/* Unified multiuser layout which places secondary user_id under
* /Android/user and shared OBB path under /Android/obb. */
fuse->root.perm = PERM_ROOT;
fuse->root.mode = 0771;
2d12: f8a7 5048 strh.w r5, [r7, #72] ; 0x48
fuse->root.gid = AID_SDCARD_R;
fuse->package_to_appid = hashmapCreate(256, str_hash, str_icase_equals);
2d16: f7fe ea8e blx 1234 <hashmapCreate@plt>
fuse->appid_with_rw = hashmapCreate(128, int_hash, int_equals);
2d1a: 49ce ldr r1, [pc, #824] ; (3054 <run+0x584>)
/* Unified multiuser layout which places secondary user_id under
* /Android/user and shared OBB path under /Android/obb. */
fuse->root.perm = PERM_ROOT;
fuse->root.mode = 0771;
fuse->root.gid = AID_SDCARD_R;
fuse->package_to_appid = hashmapCreate(256, str_hash, str_icase_equals);
2d1c: f507 5583 add.w r5, r7, #4192 ; 0x1060
fuse->appid_with_rw = hashmapCreate(128, int_hash, int_equals);
2d20: 4acd ldr r2, [pc, #820] ; (3058 <run+0x588>)
/* Unified multiuser layout which places secondary user_id under
* /Android/user and shared OBB path under /Android/obb. */
fuse->root.perm = PERM_ROOT;
fuse->root.mode = 0771;
fuse->root.gid = AID_SDCARD_R;
fuse->package_to_appid = hashmapCreate(256, str_hash, str_icase_equals);
2d22: 6128 str r0, [r5, #16]
fuse->appid_with_rw = hashmapCreate(128, int_hash, int_equals);
2d24: 2080 movs r0, #128 ; 0x80
2d26: 4479 add r1, pc
2d28: 447a add r2, pc
2d2a: f7fe ea84 blx 1234 <hashmapCreate@plt>
2d2e: 4acb ldr r2, [pc, #812] ; (305c <run+0x58c>)
2d30: f44f 5180 mov.w r1, #4096 ; 0x1000
2d34: 6168 str r0, [r5, #20]
2d36: 4633 mov r3, r6
2d38: f107 0070 add.w r0, r7, #112 ; 0x70
2d3c: 447a add r2, pc
2d3e: f7fe ea26 blx 118c <snprintf@plt>
#if !defined(__clang__)
if (__builtin_constant_p(mode)) {
if ((mode & 0777) != mode) {
__umask_invalid_mode();
}
return __umask_real(mode);
2d42: 2000 movs r0, #0
static int ignite_fuse(struct fuse* fuse, int num_threads)
{
struct fuse_handler* handlers;
int i;
handlers = malloc(num_threads * sizeof(struct fuse_handler));
2d44: 4daf ldr r5, [pc, #700] ; (3004 <run+0x534>)
2d46: f7fe ea8e blx 1264 <umask@plt>
2d4a: f50d 53ce add.w r3, sp, #6592 ; 0x19c0
2d4e: 1d1e adds r6, r3, #4
2d50: 46a8 mov r8, r5
2d52: 6832 ldr r2, [r6, #0]
2d54: fb05 f002 mul.w r0, r5, r2
2d58: f7fe e9be blx 10d8 <malloc@plt>
if (!handlers) {
2d5c: 4606 mov r6, r0
2d5e: b988 cbnz r0, 2d84 <run+0x2b4>
ERROR("cannot allocate storage for threads\n");
2d60: 49ac ldr r1, [pc, #688] ; (3014 <run+0x544>)
}
fuse_init(&fuse, fd, source_path, write_gid, derive, split_perms);
umask(0);
res = ignite_fuse(&fuse, num_threads);
2d62: f06f 0a0b mvn.w sl, #11
struct fuse_handler* handlers;
int i;
handlers = malloc(num_threads * sizeof(struct fuse_handler));
if (!handlers) {
ERROR("cannot allocate storage for threads\n");
2d66: 48be ldr r0, [pc, #760] ; (3060 <run+0x590>)
2d68: 5861 ldr r1, [r4, r1]
2d6a: 4478 add r0, pc
2d6c: 31a8 adds r1, #168 ; 0xa8
2d6e: f7fe ea80 blx 1270 <fputs@plt>
2d72: e134 b.n 2fde <run+0x50e>
return -ENOMEM;
}
for (i = 0; i < num_threads; i++) {
handlers[i].fuse = fuse;
2d74: 51f1 str r1, [r6, r7]
" -s: split derived permissions for pics, av (requires -d or -l)\n"
"\n", DEFAULT_NUM_THREADS);
return 1;
}
static int run(const char* source_path, const char* dest_path, uid_t uid,
2d76: 19f2 adds r2, r6, r7
2d78: f507 2780 add.w r7, r7, #262144 ; 0x40000
return -ENOMEM;
}
for (i = 0; i < num_threads; i++) {
handlers[i].fuse = fuse;
handlers[i].token = i;
2d7c: 6055 str r5, [r2, #4]
2d7e: 3758 adds r7, #88 ; 0x58
if (!handlers) {
ERROR("cannot allocate storage for threads\n");
return -ENOMEM;
}
for (i = 0; i < num_threads; i++) {
2d80: 3501 adds r5, #1
2d82: e003 b.n 2d8c <run+0x2bc>
{
struct fuse_handler* handlers;
int i;
handlers = malloc(num_threads * sizeof(struct fuse_handler));
if (!handlers) {
2d84: 2700 movs r7, #0
2d86: f60d 1118 addw r1, sp, #2328 ; 0x918
2d8a: 463d mov r5, r7
ERROR("cannot allocate storage for threads\n");
return -ENOMEM;
}
for (i = 0; i < num_threads; i++) {
2d8c: f50d 50ce add.w r0, sp, #6592 ; 0x19c0
2d90: 1d03 adds r3, r0, #4
2d92: 681a ldr r2, [r3, #0]
2d94: 4295 cmp r5, r2
2d96: dbed blt.n 2d74 <run+0x2a4>
handlers[i].token = i;
}
/* When deriving permissions, this thread is used to process inotify events,
* otherwise it becomes one of the FUSE handlers. */
i = (fuse->derive == DERIVE_NONE) ? 1 : 0;
2d98: 694f ldr r7, [r1, #20]
for (; i < num_threads; i++) {
pthread_t thread;
int res = pthread_create(&thread, NULL, start_handler, &handlers[i]);
2d9a: f8df 92c8 ldr.w r9, [pc, #712] ; 3064 <run+0x594>
handlers[i].token = i;
}
/* When deriving permissions, this thread is used to process inotify events,
* otherwise it becomes one of the FUSE handlers. */
i = (fuse->derive == DERIVE_NONE) ? 1 : 0;
2d9e: f1d7 0501 rsbs r5, r7, #1
2da2: bf38 it cc
2da4: 2500 movcc r5, #0
for (; i < num_threads; i++) {
pthread_t thread;
int res = pthread_create(&thread, NULL, start_handler, &handlers[i]);
2da6: 44f9 add r9, pc
" -s: split derived permissions for pics, av (requires -d or -l)\n"
"\n", DEFAULT_NUM_THREADS);
return 1;
}
static int run(const char* source_path, const char* dest_path, uid_t uid,
2da8: fb08 6805 mla r8, r8, r5, r6
2dac: 2700 movs r7, #0
2dae: e015 b.n 2ddc <run+0x30c>
/* When deriving permissions, this thread is used to process inotify events,
* otherwise it becomes one of the FUSE handlers. */
i = (fuse->derive == DERIVE_NONE) ? 1 : 0;
for (; i < num_threads; i++) {
pthread_t thread;
int res = pthread_create(&thread, NULL, start_handler, &handlers[i]);
2db0: eb07 0308 add.w r3, r7, r8
2db4: a805 add r0, sp, #20
2db6: 2100 movs r1, #0
2db8: 464a mov r2, r9
2dba: f507 2780 add.w r7, r7, #262144 ; 0x40000
2dbe: f7fe ea5e blx 127c <pthread_create@plt>
2dc2: 3758 adds r7, #88 ; 0x58
if (res) {
2dc4: 4603 mov r3, r0
2dc6: b140 cbz r0, 2dda <run+0x30a>
ERROR("failed to start thread #%d, error=%d\n", i, res);
2dc8: 4e92 ldr r6, [pc, #584] ; (3014 <run+0x544>)
2dca: 462a mov r2, r5
2dcc: 49a6 ldr r1, [pc, #664] ; (3068 <run+0x598>)
2dce: 59a0 ldr r0, [r4, r6]
2dd0: 4479 add r1, pc
2dd2: 30a8 adds r0, #168 ; 0xa8
2dd4: f7fe e8de blx f94 <fprintf@plt>
2dd8: e0fe b.n 2fd8 <run+0x508>
}
/* When deriving permissions, this thread is used to process inotify events,
* otherwise it becomes one of the FUSE handlers. */
i = (fuse->derive == DERIVE_NONE) ? 1 : 0;
for (; i < num_threads; i++) {
2dda: 3501 adds r5, #1
2ddc: f50d 51ce add.w r1, sp, #6592 ; 0x19c0
2de0: 1d08 adds r0, r1, #4
2de2: 6803 ldr r3, [r0, #0]
2de4: 429d cmp r5, r3
2de6: dbe3 blt.n 2db0 <run+0x2e0>
ERROR("failed to start thread #%d, error=%d\n", i, res);
goto quit;
}
}
if (fuse->derive == DERIVE_NONE) {
2de8: f60d 1518 addw r5, sp, #2328 ; 0x918
2dec: 696a ldr r2, [r5, #20]
2dee: b912 cbnz r2, 2df6 <run+0x326>
handle_fuse_requests(&handlers[0]);
2df0: 4630 mov r0, r6
2df2: f7ff fd09 bl 2808 <handle_fuse_requests>
static void watch_package_list(struct fuse* fuse) {
struct inotify_event *event;
char event_buf[512];
int nfd = inotify_init();
2df6: f7fe ea48 blx 1288 <inotify_init@plt>
if (nfd < 0) {
2dfa: f1b0 0800 subs.w r8, r0, #0
2dfe: da0b bge.n 2e18 <run+0x348>
ERROR("inotify_init failed: %s\n", strerror(errno));
2e00: 4d84 ldr r5, [pc, #528] ; (3014 <run+0x544>)
2e02: f7fe e8f8 blx ff4 <__errno@plt>
2e06: 6800 ldr r0, [r0, #0]
2e08: f7fe e93c blx 1084 <strerror@plt>
2e0c: 4997 ldr r1, [pc, #604] ; (306c <run+0x59c>)
2e0e: 4602 mov r2, r0
2e10: 5960 ldr r0, [r4, r5]
2e12: 4479 add r1, pc
2e14: 30a8 adds r0, #168 ; 0xa8
2e16: e0c6 b.n 2fa6 <run+0x4d6>
}
static int read_package_list(struct fuse *fuse) {
pthread_mutex_lock(&fuse->lock);
hashmapForEach(fuse->package_to_appid, remove_str_to_int, fuse->package_to_appid);
2e18: f505 5683 add.w r6, r5, #4192 ; 0x1060
static void watch_package_list(struct fuse* fuse) {
struct inotify_event *event;
char event_buf[512];
int nfd = inotify_init();
if (nfd < 0) {
2e1c: 2700 movs r7, #0
}
static int read_package_list(struct fuse *fuse) {
pthread_mutex_lock(&fuse->lock);
hashmapForEach(fuse->package_to_appid, remove_str_to_int, fuse->package_to_appid);
2e1e: f106 0910 add.w r9, r6, #16
return;
}
bool active = false;
while (1) {
if (!active) {
2e22: 2f00 cmp r7, #0
2e24: f040 80a6 bne.w 2f74 <run+0x4a4>
int res = inotify_add_watch(nfd, kPackagesListFile, IN_DELETE_SELF);
2e28: 4f91 ldr r7, [pc, #580] ; (3070 <run+0x5a0>)
if (res == -1) {
if (errno == ENOENT || errno == EACCES) {
/* Framework may not have created yet, sleep and retry */
ERROR("missing packages.list; retrying\n");
2e2a: f8df a248 ldr.w sl, [pc, #584] ; 3074 <run+0x5a4>
}
bool active = false;
while (1) {
if (!active) {
int res = inotify_add_watch(nfd, kPackagesListFile, IN_DELETE_SELF);
2e2e: 447f add r7, pc
if (res == -1) {
if (errno == ENOENT || errno == EACCES) {
/* Framework may not have created yet, sleep and retry */
ERROR("missing packages.list; retrying\n");
2e30: 44fa add sl, pc
}
bool active = false;
while (1) {
if (!active) {
int res = inotify_add_watch(nfd, kPackagesListFile, IN_DELETE_SELF);
2e32: 4640 mov r0, r8
2e34: 4639 mov r1, r7
2e36: f44f 6280 mov.w r2, #1024 ; 0x400
2e3a: f7fe ea2c blx 1294 <inotify_add_watch@plt>
if (res == -1) {
2e3e: 3001 adds r0, #1
2e40: d11c bne.n 2e7c <run+0x3ac>
if (errno == ENOENT || errno == EACCES) {
2e42: f7fe e8d8 blx ff4 <__errno@plt>
2e46: 6802 ldr r2, [r0, #0]
2e48: 4972 ldr r1, [pc, #456] ; (3014 <run+0x544>)
2e4a: 2a02 cmp r2, #2
2e4c: f854 b001 ldr.w fp, [r4, r1]
2e50: d002 beq.n 2e58 <run+0x388>
2e52: 6803 ldr r3, [r0, #0]
2e54: 2b0d cmp r3, #13
2e56: d108 bne.n 2e6a <run+0x39a>
/* Framework may not have created yet, sleep and retry */
ERROR("missing packages.list; retrying\n");
2e58: 4650 mov r0, sl
2e5a: f10b 01a8 add.w r1, fp, #168 ; 0xa8
2e5e: f7fe ea08 blx 1270 <fputs@plt>
sleep(3);
2e62: 2003 movs r0, #3
2e64: f7fe ea1c blx 12a0 <sleep@plt>
2e68: e7e3 b.n 2e32 <run+0x362>
continue;
} else {
ERROR("inotify_add_watch failed: %s\n", strerror(errno));
2e6a: 6800 ldr r0, [r0, #0]
2e6c: f7fe e90a blx 1084 <strerror@plt>
2e70: 4981 ldr r1, [pc, #516] ; (3078 <run+0x5a8>)
2e72: 4602 mov r2, r0
2e74: f10b 00a8 add.w r0, fp, #168 ; 0xa8
2e78: 4479 add r1, pc
2e7a: e094 b.n 2fa6 <run+0x4d6>
hashmapRemove(map, key);
return true;
}
static int read_package_list(struct fuse *fuse) {
pthread_mutex_lock(&fuse->lock);
2e7c: 4628 mov r0, r5
2e7e: f7fe e8d2 blx 1024 <pthread_mutex_lock@plt>
hashmapForEach(fuse->package_to_appid, remove_str_to_int, fuse->package_to_appid);
2e82: f8d9 0000 ldr.w r0, [r9]
2e86: 497d ldr r1, [pc, #500] ; (307c <run+0x5ac>)
2e88: 4602 mov r2, r0
2e8a: 4479 add r1, pc
2e8c: f7fe ea0e blx 12ac <hashmapForEach@plt>
hashmapForEach(fuse->appid_with_rw, remove_int_to_null, fuse->appid_with_rw);
2e90: 6970 ldr r0, [r6, #20]
2e92: 497b ldr r1, [pc, #492] ; (3080 <run+0x5b0>)
2e94: 4602 mov r2, r0
2e96: 4479 add r1, pc
2e98: f7fe ea08 blx 12ac <hashmapForEach@plt>
FILE* file = fopen(kPackagesListFile, "r");
2e9c: 4979 ldr r1, [pc, #484] ; (3084 <run+0x5b4>)
2e9e: 4638 mov r0, r7
2ea0: 4479 add r1, pc
2ea2: f7fe ea0a blx 12b8 <fopen@plt>
if (!file) {
2ea6: 4607 mov r7, r0
2ea8: 2800 cmp r0, #0
2eaa: d151 bne.n 2f50 <run+0x480>
ERROR("failed to open package list: %s\n", strerror(errno));
2eac: 4e59 ldr r6, [pc, #356] ; (3014 <run+0x544>)
2eae: f7fe e8a2 blx ff4 <__errno@plt>
2eb2: 6800 ldr r0, [r0, #0]
2eb4: f7fe e8e6 blx 1084 <strerror@plt>
2eb8: 59a7 ldr r7, [r4, r6]
2eba: 4602 mov r2, r0
2ebc: 4972 ldr r1, [pc, #456] ; (3088 <run+0x5b8>)
2ebe: 37a8 adds r7, #168 ; 0xa8
2ec0: 4479 add r1, pc
2ec2: 4638 mov r0, r7
2ec4: f7fe e866 blx f94 <fprintf@plt>
pthread_mutex_unlock(&fuse->lock);
2ec8: 4628 mov r0, r5
2eca: f7fe e8b2 blx 1030 <pthread_mutex_unlock@plt>
}
/* Watch above will tell us about any future changes, so
* read the current state. */
if (read_package_list(fuse) == -1) {
ERROR("read_package_list failed: %s\n", strerror(errno));
2ece: f7fe e892 blx ff4 <__errno@plt>
2ed2: 6800 ldr r0, [r0, #0]
2ed4: f7fe e8d6 blx 1084 <strerror@plt>
2ed8: 496c ldr r1, [pc, #432] ; (308c <run+0x5bc>)
2eda: 4602 mov r2, r0
2edc: 4638 mov r0, r7
2ede: 4479 add r1, pc
2ee0: e061 b.n 2fa6 <run+0x4d6>
while (fgets(buf, sizeof(buf), file) != NULL) {
char package_name[512];
int appid;
char gids[512];
if (sscanf(buf, "%s %d %*d %*s %*s %s", package_name, &appid, gids) == 3) {
2ee2: f50d 6ae3 add.w sl, sp, #1816 ; 0x718
2ee6: a8c6 add r0, sp, #792 ; 0x318
2ee8: f8cd a000 str.w sl, [sp]
2eec: 4659 mov r1, fp
2eee: f50d 62a3 add.w r2, sp, #1304 ; 0x518
2ef2: ab05 add r3, sp, #20
2ef4: f7fe e9e6 blx 12c4 <sscanf@plt>
2ef8: 2803 cmp r0, #3
2efa: d12c bne.n 2f56 <run+0x486>
char* package_name_dup = strdup(package_name);
2efc: f50d 60a3 add.w r0, sp, #1304 ; 0x518
2f00: f7fe e992 blx 1228 <strdup@plt>
hashmapPut(fuse->package_to_appid, package_name_dup, (void*) appid);
2f04: 9a05 ldr r2, [sp, #20]
char package_name[512];
int appid;
char gids[512];
if (sscanf(buf, "%s %d %*d %*s %*s %s", package_name, &appid, gids) == 3) {
char* package_name_dup = strdup(package_name);
2f06: 4601 mov r1, r0
hashmapPut(fuse->package_to_appid, package_name_dup, (void*) appid);
2f08: f8d9 0000 ldr.w r0, [r9]
2f0c: f7fe e9e0 blx 12d0 <hashmapPut@plt>
char* token = strtok(gids, ",");
2f10: 495f ldr r1, [pc, #380] ; (3090 <run+0x5c0>)
2f12: 4650 mov r0, sl
while (token != NULL) {
if (strtoul(token, NULL, 10) == fuse->write_gid) {
hashmapPut(fuse->appid_with_rw, (void*) appid, (void*) 1);
break;
}
token = strtok(NULL, ",");
2f14: f8df a17c ldr.w sl, [pc, #380] ; 3094 <run+0x5c4>
if (sscanf(buf, "%s %d %*d %*s %*s %s", package_name, &appid, gids) == 3) {
char* package_name_dup = strdup(package_name);
hashmapPut(fuse->package_to_appid, package_name_dup, (void*) appid);
char* token = strtok(gids, ",");
2f18: 4479 add r1, pc
2f1a: f7fe e9e0 blx 12dc <strtok@plt>
while (token != NULL) {
if (strtoul(token, NULL, 10) == fuse->write_gid) {
hashmapPut(fuse->appid_with_rw, (void*) appid, (void*) 1);
break;
}
token = strtok(NULL, ",");
2f1e: 44fa add sl, pc
2f20: e013 b.n 2f4a <run+0x47a>
char* package_name_dup = strdup(package_name);
hashmapPut(fuse->package_to_appid, package_name_dup, (void*) appid);
char* token = strtok(gids, ",");
while (token != NULL) {
if (strtoul(token, NULL, 10) == fuse->write_gid) {
2f22: 2100 movs r1, #0
2f24: 220a movs r2, #10
2f26: f7fe e90e blx 1144 <strtoul@plt>
2f2a: 69e9 ldr r1, [r5, #28]
2f2c: 4288 cmp r0, r1
2f2e: d108 bne.n 2f42 <run+0x472>
hashmapPut(fuse->appid_with_rw, (void*) appid, (void*) 1);
2f30: f50d 53cc add.w r3, sp, #6528 ; 0x1980
2f34: 9905 ldr r1, [sp, #20]
2f36: 330c adds r3, #12
2f38: 2201 movs r2, #1
2f3a: 6818 ldr r0, [r3, #0]
2f3c: f7fe e9c8 blx 12d0 <hashmapPut@plt>
2f40: e009 b.n 2f56 <run+0x486>
break;
}
token = strtok(NULL, ",");
2f42: 2000 movs r0, #0
2f44: 4651 mov r1, sl
2f46: f7fe e9ca blx 12dc <strtok@plt>
if (sscanf(buf, "%s %d %*d %*s %*s %s", package_name, &appid, gids) == 3) {
char* package_name_dup = strdup(package_name);
hashmapPut(fuse->package_to_appid, package_name_dup, (void*) appid);
char* token = strtok(gids, ",");
while (token != NULL) {
2f4a: 2800 cmp r0, #0
2f4c: d1e9 bne.n 2f22 <run+0x452>
2f4e: e002 b.n 2f56 <run+0x486>
while (fgets(buf, sizeof(buf), file) != NULL) {
char package_name[512];
int appid;
char gids[512];
if (sscanf(buf, "%s %d %*d %*s %*s %s", package_name, &appid, gids) == 3) {
2f50: f8df b144 ldr.w fp, [pc, #324] ; 3098 <run+0x5c8>
2f54: 44fb add fp, pc
}
// Compiler can prove, at compile time, that the passed in size
// is always <= the actual object size. Don't call __fgets_chk
if (__builtin_constant_p(size) && (size <= (int) bos)) {
return __fgets_real(dest, size, stream);
2f56: a8c6 add r0, sp, #792 ; 0x318
2f58: f44f 7100 mov.w r1, #512 ; 0x200
2f5c: 463a mov r2, r7
2f5e: f7fe e9c4 blx 12e8 <fgets@plt>
pthread_mutex_unlock(&fuse->lock);
return -1;
}
char buf[512];
while (fgets(buf, sizeof(buf), file) != NULL) {
2f62: 2800 cmp r0, #0
2f64: d1bd bne.n 2ee2 <run+0x412>
}
TRACE("read_package_list: found %d packages, %d with write_gid\n",
hashmapSize(fuse->package_to_appid),
hashmapSize(fuse->appid_with_rw));
fclose(file);
2f66: 4638 mov r0, r7
* read the current state. */
if (read_package_list(fuse) == -1) {
ERROR("read_package_list failed: %s\n", strerror(errno));
return;
}
active = true;
2f68: 2701 movs r7, #1
}
TRACE("read_package_list: found %d packages, %d with write_gid\n",
hashmapSize(fuse->package_to_appid),
hashmapSize(fuse->appid_with_rw));
fclose(file);
2f6a: f7fe e9c4 blx 12f4 <fclose@plt>
pthread_mutex_unlock(&fuse->lock);
2f6e: 4628 mov r0, r5
2f70: f7fe e85e blx 1030 <pthread_mutex_unlock@plt>
}
active = true;
}
int event_pos = 0;
int res = read(nfd, event_buf, sizeof(event_buf));
2f74: f50d 7a8c add.w sl, sp, #280 ; 0x118
2f78: 4640 mov r0, r8
2f7a: 4651 mov r1, sl
2f7c: f44f 7200 mov.w r2, #512 ; 0x200
2f80: f7fe e90a blx 1198 <read@plt>
if (res < (int) sizeof(*event)) {
2f84: 280f cmp r0, #15
2f86: dc11 bgt.n 2fac <run+0x4dc>
if (errno == EINTR)
2f88: f7fe e834 blx ff4 <__errno@plt>
2f8c: 6802 ldr r2, [r0, #0]
2f8e: 2a04 cmp r2, #4
2f90: f43f af47 beq.w 2e22 <run+0x352>
continue;
ERROR("failed to read inotify event: %s\n", strerror(errno));
2f94: 6800 ldr r0, [r0, #0]
2f96: f7fe e876 blx 1084 <strerror@plt>
2f9a: 4602 mov r2, r0
2f9c: 481d ldr r0, [pc, #116] ; (3014 <run+0x544>)
2f9e: 493f ldr r1, [pc, #252] ; (309c <run+0x5cc>)
2fa0: 5820 ldr r0, [r4, r0]
2fa2: 4479 add r1, pc
2fa4: 30a8 adds r0, #168 ; 0xa8
2fa6: f7fd eff6 blx f94 <fprintf@plt>
2faa: e00e b.n 2fca <run+0x4fa>
active = true;
}
int event_pos = 0;
int res = read(nfd, event_buf, sizeof(event_buf));
if (res < (int) sizeof(*event)) {
2fac: 2300 movs r3, #0
return;
}
while (res >= (int) sizeof(*event)) {
int event_size;
event = (struct inotify_event *) (event_buf + event_pos);
2fae: eb0a 0103 add.w r1, sl, r3
TRACE("inotify event: %08x\n", event->mask);
if ((event->mask & IN_IGNORED) == IN_IGNORED) {
2fb2: 684a ldr r2, [r1, #4]
/* Previously watched file was deleted, probably due to move
* that swapped in new data; re-arm the watch and read. */
active = false;
}
event_size = sizeof(*event) + event->len;
2fb4: 68c9 ldr r1, [r1, #12]
TRACE("inotify event: %08x\n", event->mask);
if ((event->mask & IN_IGNORED) == IN_IGNORED) {
/* Previously watched file was deleted, probably due to move
* that swapped in new data; re-arm the watch and read. */
active = false;
2fb6: f412 4f00 tst.w r2, #32768 ; 0x8000
2fba: bf18 it ne
2fbc: 2700 movne r7, #0
}
event_size = sizeof(*event) + event->len;
2fbe: 3110 adds r1, #16
res -= event_size;
2fc0: 1a40 subs r0, r0, r1
event_pos += event_size;
2fc2: 185b adds r3, r3, r1
continue;
ERROR("failed to read inotify event: %s\n", strerror(errno));
return;
}
while (res >= (int) sizeof(*event)) {
2fc4: 280f cmp r0, #15
2fc6: dcf2 bgt.n 2fae <run+0x4de>
2fc8: e72b b.n 2e22 <run+0x352>
handle_fuse_requests(&handlers[0]);
} else {
watch_package_list(fuse);
}
ERROR("terminated prematurely\n");
2fca: 4812 ldr r0, [pc, #72] ; (3014 <run+0x544>)
2fcc: 5821 ldr r1, [r4, r0]
2fce: 4834 ldr r0, [pc, #208] ; (30a0 <run+0x5d0>)
2fd0: 31a8 adds r1, #168 ; 0xa8
2fd2: 4478 add r0, pc
2fd4: f7fe e94c blx 1270 <fputs@plt>
/* don't bother killing all of the other threads or freeing anything,
* should never get here anyhow */
quit:
exit(1);
2fd8: 2001 movs r0, #1
2fda: f7fe e992 blx 1300 <exit@plt>
/* we do not attempt to umount the file system here because we are no longer
* running as the root user */
error:
close(fd);
2fde: 9802 ldr r0, [sp, #8]
2fe0: f7fe e856 blx 1090 <close@plt>
return res;
}
2fe4: 9b03 ldr r3, [sp, #12]
2fe6: f50d 52cc add.w r2, sp, #6528 ; 0x1980
2fea: 3214 adds r2, #20
2fec: 4650 mov r0, sl
2fee: 6812 ldr r2, [r2, #0]
2ff0: 6819 ldr r1, [r3, #0]
2ff2: 428a cmp r2, r1
2ff4: d001 beq.n 2ffa <run+0x52a>
2ff6: f7fe e828 blx 1048 <__stack_chk_fail@plt>
2ffa: b067 add sp, #412 ; 0x19c
2ffc: f50d 5dc0 add.w sp, sp, #6144 ; 0x1800
3000: e8bd 8ff0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, sl, fp, pc}
3004: 00040058 .word 0x00040058
3008: 000023d0 .word 0x000023d0
300c: fffffff4 .word 0xfffffff4
3010: 00000cdf .word 0x00000cdf
3014: fffffff0 .word 0xfffffff0
3018: 00000cab .word 0x00000cab
301c: 00000caa .word 0x00000caa
3020: 00000ce2 .word 0x00000ce2
3024: 00000cc3 .word 0x00000cc3
3028: 00000938 .word 0x00000938
302c: 00000cb9 .word 0x00000cb9
3030: 00000ca7 .word 0x00000ca7
3034: 00000c90 .word 0x00000c90
3038: ffffe765 .word 0xffffe765
303c: ffffe76d .word 0xffffe76d
3040: ffffe717 .word 0xffffe717
3044: ffffe717 .word 0xffffe717
3048: 00000bdd .word 0x00000bdd
304c: ffffe715 .word 0xffffe715
3050: ffffe701 .word 0xffffe701
3054: ffffe6b7 .word 0xffffe6b7
3058: ffffe6b7 .word 0xffffe6b7
305c: 00000b82 .word 0x00000b82
3060: 00000b63 .word 0x00000b63
3064: 000002fb .word 0x000002fb
3068: 00000b22 .word 0x00000b22
306c: 00000b06 .word 0x00000b06
3070: 00000b03 .word 0x00000b03
3074: 00000b1c .word 0x00000b1c
3078: 00000af5 .word 0x00000af5
307c: ffffe613 .word 0xffffe613
3080: ffffe5f9 .word 0xffffe5f9
3084: 00000aeb .word 0x00000aeb
3088: 00000acd .word 0x00000acd
308c: 00000ae7 .word 0x00000ae7
3090: 00000aab .word 0x00000aab
3094: 00000aa5 .word 0x00000aa5
3098: 00000a5a .word 0x00000a5a
309c: 00000a41 .word 0x00000a41
30a0: 00000a33 .word 0x00000a33
000030a4 <start_handler>:
}
}
}
static void* start_handler(void* data)
{
30a4: b508 push {r3, lr}
struct fuse_handler* handler = data;
handle_fuse_requests(handler);
30a6: f7ff fbaf bl 2808 <handle_fuse_requests>
...
000030ac <sdcard_main>:
close(fd);
return res;
}
int sdcard_main(int argc, char **argv)
{
30ac: e92d 4ff0 stmdb sp!, {r4, r5, r6, r7, r8, r9, sl, fp, lr}
int res;
const char *source_path = NULL;
const char *dest_path = NULL;
uid_t uid = 0;
gid_t gid = 0;
gid_t write_gid = AID_SDCARD_RW;
30b0: f240 33f7 movw r3, #1015 ; 0x3f7
close(fd);
return res;
}
int sdcard_main(int argc, char **argv)
{
30b4: f8df b1b0 ldr.w fp, [pc, #432] ; 3268 <sdcard_main+0x1bc>
30b8: b08b sub sp, #44 ; 0x2c
uid_t uid = 0;
gid_t gid = 0;
gid_t write_gid = AID_SDCARD_RW;
int num_threads = DEFAULT_NUM_THREADS;
derive_t derive = DERIVE_NONE;
bool split_perms = false;
30ba: 2600 movs r6, #0
const char *source_path = NULL;
const char *dest_path = NULL;
uid_t uid = 0;
gid_t gid = 0;
gid_t write_gid = AID_SDCARD_RW;
int num_threads = DEFAULT_NUM_THREADS;
30bc: f04f 0a02 mov.w sl, #2
bool split_perms = false;
int i;
struct rlimit rlim;
int opt;
while ((opt = getopt(argc, argv, "u:g:w:t:dls")) != -1) {
30c0: 4f6a ldr r7, [pc, #424] ; (326c <sdcard_main+0x1c0>)
const char *dest_path = NULL;
uid_t uid = 0;
gid_t gid = 0;
gid_t write_gid = AID_SDCARD_RW;
int num_threads = DEFAULT_NUM_THREADS;
derive_t derive = DERIVE_NONE;
30c2: 46b1 mov r9, r6
close(fd);
return res;
}
int sdcard_main(int argc, char **argv)
{
30c4: 44fb add fp, pc
30c6: 9006 str r0, [sp, #24]
30c8: 9107 str r1, [sp, #28]
int res;
const char *source_path = NULL;
const char *dest_path = NULL;
uid_t uid = 0;
gid_t gid = 0;
30ca: 4634 mov r4, r6
gid_t write_gid = AID_SDCARD_RW;
30cc: 9305 str r3, [sp, #20]
int sdcard_main(int argc, char **argv)
{
int res;
const char *source_path = NULL;
const char *dest_path = NULL;
uid_t uid = 0;
30ce: 4635 mov r5, r6
bool split_perms = false;
int i;
struct rlimit rlim;
int opt;
while ((opt = getopt(argc, argv, "u:g:w:t:dls")) != -1) {
30d0: 447f add r7, pc
30d2: e03e b.n 3152 <sdcard_main+0xa6>
switch (opt) {
30d4: 3864 subs r0, #100 ; 0x64
30d6: 2813 cmp r0, #19
30d8: d86a bhi.n 31b0 <sdcard_main+0x104>
30da: e8df f000 tbb [pc, r0]
30de: 6935 .short 0x6935
30e0: 69691469 .word 0x69691469
30e4: 69386969 .word 0x69386969
30e8: 69696969 .word 0x69696969
30ec: 0a293369 .word 0x0a293369
30f0: 1e69 .short 0x1e69
case 'u':
uid = strtoul(optarg, NULL, 10);
30f2: 4d5f ldr r5, [pc, #380] ; (3270 <sdcard_main+0x1c4>)
30f4: 220a movs r2, #10
30f6: f85b 1005 ldr.w r1, [fp, r5]
30fa: 6808 ldr r0, [r1, #0]
30fc: 2100 movs r1, #0
30fe: f7fe e822 blx 1144 <strtoul@plt>
3102: 4605 mov r5, r0
break;
3104: e025 b.n 3152 <sdcard_main+0xa6>
case 'g':
gid = strtoul(optarg, NULL, 10);
3106: 4c5a ldr r4, [pc, #360] ; (3270 <sdcard_main+0x1c4>)
3108: 2100 movs r1, #0
310a: f85b 2004 ldr.w r2, [fp, r4]
310e: 6810 ldr r0, [r2, #0]
3110: 220a movs r2, #10
3112: f7fe e818 blx 1144 <strtoul@plt>
3116: 4604 mov r4, r0
break;
3118: e01b b.n 3152 <sdcard_main+0xa6>
case 'w':
write_gid = strtoul(optarg, NULL, 10);
311a: f8df e154 ldr.w lr, [pc, #340] ; 3270 <sdcard_main+0x1c4>
311e: 2100 movs r1, #0
3120: f85b 200e ldr.w r2, [fp, lr]
3124: 6810 ldr r0, [r2, #0]
3126: 220a movs r2, #10
3128: f7fe e80c blx 1144 <strtoul@plt>
312c: 9005 str r0, [sp, #20]
break;
312e: e010 b.n 3152 <sdcard_main+0xa6>
case 't':
num_threads = strtoul(optarg, NULL, 10);
3130: 484f ldr r0, [pc, #316] ; (3270 <sdcard_main+0x1c4>)
3132: 2100 movs r1, #0
3134: 220a movs r2, #10
3136: f85b 3000 ldr.w r3, [fp, r0]
313a: 6818 ldr r0, [r3, #0]
313c: f7fe e802 blx 1144 <strtoul@plt>
3140: 4682 mov sl, r0
break;
3142: e006 b.n 3152 <sdcard_main+0xa6>
break;
case 'l':
derive = DERIVE_LEGACY;
break;
case 's':
split_perms = true;
3144: 2601 movs r6, #1
break;
3146: e004 b.n 3152 <sdcard_main+0xa6>
break;
case 't':
num_threads = strtoul(optarg, NULL, 10);
break;
case 'd':
derive = DERIVE_UNIFIED;
3148: f04f 0902 mov.w r9, #2
314c: e001 b.n 3152 <sdcard_main+0xa6>
break;
case 'l':
derive = DERIVE_LEGACY;
314e: f04f 0901 mov.w r9, #1
bool split_perms = false;
int i;
struct rlimit rlim;
int opt;
while ((opt = getopt(argc, argv, "u:g:w:t:dls")) != -1) {
3152: 9806 ldr r0, [sp, #24]
3154: 463a mov r2, r7
3156: 9907 ldr r1, [sp, #28]
3158: f7fe e8d8 blx 130c <getopt@plt>
315c: 1c43 adds r3, r0, #1
315e: d1b9 bne.n 30d4 <sdcard_main+0x28>
default:
return usage();
}
}
for (i = optind; i < argc; i++) {
3160: 4a44 ldr r2, [pc, #272] ; (3274 <sdcard_main+0x1c8>)
int sdcard_main(int argc, char **argv)
{
int res;
const char *source_path = NULL;
const char *dest_path = NULL;
3162: 2700 movs r7, #0
}
int sdcard_main(int argc, char **argv)
{
int res;
const char *source_path = NULL;
3164: 46b8 mov r8, r7
default:
return usage();
}
}
for (i = optind; i < argc; i++) {
3166: f85b 0002 ldr.w r0, [fp, r2]
316a: 6803 ldr r3, [r0, #0]
316c: e027 b.n 31be <sdcard_main+0x112>
char* arg = argv[i];
316e: 9807 ldr r0, [sp, #28]
3170: f850 0023 ldr.w r0, [r0, r3, lsl #2]
if (!source_path) {
3174: f1b8 0f00 cmp.w r8, #0
3178: d01d beq.n 31b6 <sdcard_main+0x10a>
source_path = arg;
} else if (!dest_path) {
317a: b1f7 cbz r7, 31ba <sdcard_main+0x10e>
dest_path = arg;
} else if (!uid) {
317c: b935 cbnz r5, 318c <sdcard_main+0xe0>
uid = strtoul(arg, NULL, 10);
317e: 4629 mov r1, r5
3180: 220a movs r2, #10
3182: 9304 str r3, [sp, #16]
3184: f7fd efde blx 1144 <strtoul@plt>
3188: 4605 mov r5, r0
318a: e006 b.n 319a <sdcard_main+0xee>
} else if (!gid) {
318c: b93c cbnz r4, 319e <sdcard_main+0xf2>
gid = strtoul(arg, NULL, 10);
318e: 4621 mov r1, r4
3190: 220a movs r2, #10
3192: 9304 str r3, [sp, #16]
3194: f7fd efd6 blx 1144 <strtoul@plt>
3198: 4604 mov r4, r0
319a: 9b04 ldr r3, [sp, #16]
319c: e00e b.n 31bc <sdcard_main+0x110>
} else {
ERROR("too many arguments\n");
319e: f8df c0d8 ldr.w ip, [pc, #216] ; 3278 <sdcard_main+0x1cc>
31a2: 4836 ldr r0, [pc, #216] ; (327c <sdcard_main+0x1d0>)
31a4: f85b 100c ldr.w r1, [fp, ip]
31a8: 4478 add r0, pc
31aa: 31a8 adds r1, #168 ; 0xa8
31ac: f7fe e860 blx 1270 <fputs@plt>
return usage();
31b0: f7fe f91c bl 13ec <usage>
31b4: e054 b.n 3260 <sdcard_main+0x1b4>
}
for (i = optind; i < argc; i++) {
char* arg = argv[i];
if (!source_path) {
source_path = arg;
31b6: 4680 mov r8, r0
31b8: e000 b.n 31bc <sdcard_main+0x110>
} else if (!dest_path) {
dest_path = arg;
31ba: 4607 mov r7, r0
default:
return usage();
}
}
for (i = optind; i < argc; i++) {
31bc: 3301 adds r3, #1
31be: 9906 ldr r1, [sp, #24]
31c0: 428b cmp r3, r1
31c2: dbd4 blt.n 316e <sdcard_main+0xc2>
ERROR("too many arguments\n");
return usage();
}
}
if (!source_path) {
31c4: f1b8 0f00 cmp.w r8, #0
31c8: d105 bne.n 31d6 <sdcard_main+0x12a>
ERROR("no source path specified\n");
31ca: 4b2b ldr r3, [pc, #172] ; (3278 <sdcard_main+0x1cc>)
31cc: 482c ldr r0, [pc, #176] ; (3280 <sdcard_main+0x1d4>)
31ce: f85b 1003 ldr.w r1, [fp, r3]
31d2: 4478 add r0, pc
31d4: e7e9 b.n 31aa <sdcard_main+0xfe>
return usage();
}
if (!dest_path) {
31d6: b92f cbnz r7, 31e4 <sdcard_main+0x138>
ERROR("no dest path specified\n");
31d8: 4927 ldr r1, [pc, #156] ; (3278 <sdcard_main+0x1cc>)
31da: 482a ldr r0, [pc, #168] ; (3284 <sdcard_main+0x1d8>)
31dc: f85b 1001 ldr.w r1, [fp, r1]
31e0: 4478 add r0, pc
31e2: e7e2 b.n 31aa <sdcard_main+0xfe>
return usage();
}
if (!uid || !gid) {
31e4: b105 cbz r5, 31e8 <sdcard_main+0x13c>
31e6: b92c cbnz r4, 31f4 <sdcard_main+0x148>
ERROR("uid and gid must be nonzero\n");
31e8: 4a23 ldr r2, [pc, #140] ; (3278 <sdcard_main+0x1cc>)
31ea: 4827 ldr r0, [pc, #156] ; (3288 <sdcard_main+0x1dc>)
31ec: f85b 1002 ldr.w r1, [fp, r2]
31f0: 4478 add r0, pc
31f2: e7da b.n 31aa <sdcard_main+0xfe>
return usage();
}
if (num_threads < 1) {
31f4: f1ba 0f00 cmp.w sl, #0
31f8: dc06 bgt.n 3208 <sdcard_main+0x15c>
ERROR("number of threads must be at least 1\n");
31fa: f8df e07c ldr.w lr, [pc, #124] ; 3278 <sdcard_main+0x1cc>
31fe: 4823 ldr r0, [pc, #140] ; (328c <sdcard_main+0x1e0>)
3200: f85b 100e ldr.w r1, [fp, lr]
3204: 4478 add r0, pc
3206: e7d0 b.n 31aa <sdcard_main+0xfe>
return usage();
}
if (split_perms && derive == DERIVE_NONE) {
3208: b14e cbz r6, 321e <sdcard_main+0x172>
320a: f1b9 0f00 cmp.w r9, #0
320e: d106 bne.n 321e <sdcard_main+0x172>
ERROR("cannot split permissions without deriving\n");
3210: f8df c064 ldr.w ip, [pc, #100] ; 3278 <sdcard_main+0x1cc>
3214: 481e ldr r0, [pc, #120] ; (3290 <sdcard_main+0x1e4>)
3216: f85b 100c ldr.w r1, [fp, ip]
321a: 4478 add r0, pc
321c: e7c5 b.n 31aa <sdcard_main+0xfe>
return usage();
}
rlim.rlim_cur = 8192;
321e: f44f 5300 mov.w r3, #8192 ; 0x2000
rlim.rlim_max = 8192;
if (setrlimit(RLIMIT_NOFILE, &rlim)) {
3222: 2007 movs r0, #7
3224: a908 add r1, sp, #32
if (split_perms && derive == DERIVE_NONE) {
ERROR("cannot split permissions without deriving\n");
return usage();
}
rlim.rlim_cur = 8192;
3226: 9308 str r3, [sp, #32]
rlim.rlim_max = 8192;
3228: 9309 str r3, [sp, #36] ; 0x24
if (setrlimit(RLIMIT_NOFILE, &rlim)) {
322a: f7fe e876 blx 1318 <setrlimit@plt>
322e: b150 cbz r0, 3246 <sdcard_main+0x19a>
ERROR("Error setting RLIMIT_NOFILE, errno = %d\n", errno);
3230: f7fd eee0 blx ff4 <__errno@plt>
3234: 6802 ldr r2, [r0, #0]
3236: 4810 ldr r0, [pc, #64] ; (3278 <sdcard_main+0x1cc>)
3238: 4916 ldr r1, [pc, #88] ; (3294 <sdcard_main+0x1e8>)
323a: f85b 0000 ldr.w r0, [fp, r0]
323e: 4479 add r1, pc
3240: 30a8 adds r0, #168 ; 0xa8
3242: f7fd eea8 blx f94 <fprintf@plt>
}
res = run(source_path, dest_path, uid, gid, write_gid, num_threads, derive, split_perms);
3246: 9b05 ldr r3, [sp, #20]
3248: 4640 mov r0, r8
324a: f8cd 9008 str.w r9, [sp, #8]
324e: 4639 mov r1, r7
3250: 9603 str r6, [sp, #12]
3252: 462a mov r2, r5
3254: e88d 0408 stmia.w sp, {r3, sl}
3258: 4623 mov r3, r4
325a: f7ff fc39 bl 2ad0 <run>
return res < 0 ? 1 : 0;
325e: 0fc0 lsrs r0, r0, #31
}
3260: b00b add sp, #44 ; 0x2c
3262: e8bd 8ff0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, sl, fp, pc}
3266: bf00 nop
3268: 00001df4 .word 0x00001df4
326c: 0000094d .word 0x0000094d
3270: fffffff8 .word 0xfffffff8
3274: fffffffc .word 0xfffffffc
3278: fffffff0 .word 0xfffffff0
327c: 00000881 .word 0x00000881
3280: 0000086b .word 0x0000086b
3284: 00000877 .word 0x00000877
3288: 0000087f .word 0x0000087f
328c: 00000888 .word 0x00000888
3290: 00000898 .word 0x00000898
3294: 0000089f .word 0x0000089f
3298: 46c04778 .word 0x46c04778
329c: e59fc000 .word 0xe59fc000
32a0: e08cf00f .word 0xe08cf00f
32a4: ffffdd10 .word 0xffffdd10
32a8: 46c04778 .word 0x46c04778
32ac: e59fc000 .word 0xe59fc000
32b0: e08cf00f .word 0xe08cf00f
32b4: ffffdd24 .word 0xffffdd24
32b8: 46c04778 .word 0x46c04778
32bc: e59fc000 .word 0xe59fc000
32c0: e08cf00f .word 0xe08cf00f
32c4: ffffdccc .word 0xffffdccc
32c8: 46c04778 .word 0x46c04778
32cc: e59fc000 .word 0xe59fc000
32d0: e08cf00f .word 0xe08cf00f
32d4: ffffdd40 .word 0xffffdd40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment