@@ -364,67 +364,52 @@ static Result<void> do_interface_stop(const BuiltinArguments& args) {
364
364
return {};
365
365
}
366
366
367
- // mkdir <path> [mode] [owner] [group]
367
+ // mkdir <path> [mode] [owner] [group] [<option> ...]
368
368
static Result<void > do_mkdir (const BuiltinArguments& args) {
369
- mode_t mode = 0755 ;
370
- Result<uid_t > uid = -1 ;
371
- Result<gid_t > gid = -1 ;
372
-
373
- switch (args.size ()) {
374
- case 5 :
375
- gid = DecodeUid (args[4 ]);
376
- if (!gid) {
377
- return Error () << " Unable to decode GID for '" << args[4 ] << " ': " << gid.error ();
378
- }
379
- FALLTHROUGH_INTENDED;
380
- case 4 :
381
- uid = DecodeUid (args[3 ]);
382
- if (!uid) {
383
- return Error () << " Unable to decode UID for '" << args[3 ] << " ': " << uid.error ();
384
- }
385
- FALLTHROUGH_INTENDED;
386
- case 3 :
387
- mode = std::strtoul (args[2 ].c_str (), 0 , 8 );
388
- FALLTHROUGH_INTENDED;
389
- case 2 :
390
- break ;
391
- default :
392
- return Error () << " Unexpected argument count: " << args.size ();
369
+ auto options = ParseMkdir (args.args );
370
+ if (!options) return options.error ();
371
+ std::string ref_basename;
372
+ if (options->ref_option == " ref" ) {
373
+ ref_basename = fscrypt_key_ref;
374
+ } else if (options->ref_option == " per_boot_ref" ) {
375
+ ref_basename = fscrypt_key_per_boot_ref;
376
+ } else {
377
+ return Error () << " Unknown key option: '" << options->ref_option << " '" ;
393
378
}
394
- std::string target = args[ 1 ];
379
+
395
380
struct stat mstat;
396
- if (lstat (target.c_str (), &mstat) != 0 ) {
381
+ if (lstat (options-> target .c_str (), &mstat) != 0 ) {
397
382
if (errno != ENOENT) {
398
- return ErrnoError () << " lstat() failed on " << target;
383
+ return ErrnoError () << " lstat() failed on " << options-> target ;
399
384
}
400
- if (!make_dir (target, mode)) {
401
- return ErrnoErrorIgnoreEnoent () << " mkdir() failed on " << target;
385
+ if (!make_dir (options-> target , options-> mode )) {
386
+ return ErrnoErrorIgnoreEnoent () << " mkdir() failed on " << options-> target ;
402
387
}
403
- if (lstat (target.c_str (), &mstat) != 0 ) {
404
- return ErrnoError () << " lstat() failed on new " << target;
388
+ if (lstat (options-> target .c_str (), &mstat) != 0 ) {
389
+ return ErrnoError () << " lstat() failed on new " << options-> target ;
405
390
}
406
391
}
407
392
if (!S_ISDIR (mstat.st_mode )) {
408
- return Error () << " Not a directory on " << target;
393
+ return Error () << " Not a directory on " << options-> target ;
409
394
}
410
- bool needs_chmod = (mstat.st_mode & ~S_IFMT) != mode;
411
- if ((* uid != static_cast <uid_t >(-1 ) && * uid != mstat.st_uid ) ||
412
- (* gid != static_cast <gid_t >(-1 ) && * gid != mstat.st_gid )) {
413
- if (lchown (target.c_str (), * uid, * gid) == -1 ) {
414
- return ErrnoError () << " lchown failed on " << target;
395
+ bool needs_chmod = (mstat.st_mode & ~S_IFMT) != options-> mode ;
396
+ if ((options-> uid != static_cast <uid_t >(-1 ) && options-> uid != mstat.st_uid ) ||
397
+ (options-> gid != static_cast <gid_t >(-1 ) && options-> gid != mstat.st_gid )) {
398
+ if (lchown (options-> target .c_str (), options-> uid , options-> gid ) == -1 ) {
399
+ return ErrnoError () << " lchown failed on " << options-> target ;
415
400
}
416
401
// chown may have cleared S_ISUID and S_ISGID, chmod again
417
402
needs_chmod = true ;
418
403
}
419
404
if (needs_chmod) {
420
- if (fchmodat (AT_FDCWD, target.c_str (), mode, AT_SYMLINK_NOFOLLOW) == -1 ) {
421
- return ErrnoError () << " fchmodat() failed on " << target;
405
+ if (fchmodat (AT_FDCWD, options-> target .c_str (), options-> mode , AT_SYMLINK_NOFOLLOW) == -1 ) {
406
+ return ErrnoError () << " fchmodat() failed on " << options-> target ;
422
407
}
423
408
}
424
409
if (fscrypt_is_native ()) {
425
- if (fscrypt_set_directory_policy ( target)) {
410
+ if (! FscryptSetDirectoryPolicy (ref_basename, options-> fscrypt_action , options-> target )) {
426
411
return reboot_into_recovery (
427
- {" --prompt_and_wipe_data" , " --reason=set_policy_failed:" s + target});
412
+ {" --prompt_and_wipe_data" , " --reason=set_policy_failed:" s + options-> target });
428
413
}
429
414
}
430
415
return {};
@@ -589,8 +574,8 @@ static Result<void> queue_fs_event(int code) {
589
574
return reboot_into_recovery (options);
590
575
/* If reboot worked, there is no return. */
591
576
} else if (code == FS_MGR_MNTALL_DEV_FILE_ENCRYPTED) {
592
- if (fscrypt_install_keyring ()) {
593
- return Error () << " fscrypt_install_keyring () failed" ;
577
+ if (! FscryptInstallKeyring ()) {
578
+ return Error () << " FscryptInstallKeyring () failed" ;
594
579
}
595
580
property_set (" ro.crypto.state" , " encrypted" );
596
581
property_set (" ro.crypto.type" , " file" );
@@ -600,8 +585,8 @@ static Result<void> queue_fs_event(int code) {
600
585
ActionManager::GetInstance ().QueueEventTrigger (" nonencrypted" );
601
586
return {};
602
587
} else if (code == FS_MGR_MNTALL_DEV_IS_METADATA_ENCRYPTED) {
603
- if (fscrypt_install_keyring ()) {
604
- return Error () << " fscrypt_install_keyring () failed" ;
588
+ if (! FscryptInstallKeyring ()) {
589
+ return Error () << " FscryptInstallKeyring () failed" ;
605
590
}
606
591
property_set (" ro.crypto.state" , " encrypted" );
607
592
property_set (" ro.crypto.type" , " file" );
@@ -611,8 +596,8 @@ static Result<void> queue_fs_event(int code) {
611
596
ActionManager::GetInstance ().QueueEventTrigger (" nonencrypted" );
612
597
return {};
613
598
} else if (code == FS_MGR_MNTALL_DEV_NEEDS_METADATA_ENCRYPTION) {
614
- if (fscrypt_install_keyring ()) {
615
- return Error () << " fscrypt_install_keyring () failed" ;
599
+ if (! FscryptInstallKeyring ()) {
600
+ return Error () << " FscryptInstallKeyring () failed" ;
616
601
}
617
602
property_set (" ro.crypto.state" , " encrypted" );
618
603
property_set (" ro.crypto.type" , " file" );
@@ -1257,7 +1242,7 @@ const BuiltinFunctionMap& GetBuiltinFunctionMap() {
1257
1242
{" load_system_props" , {0 , 0 , {false , do_load_system_props}}},
1258
1243
{" loglevel" , {1 , 1 , {false , do_loglevel}}},
1259
1244
{" mark_post_data" , {0 , 0 , {false , do_mark_post_data}}},
1260
- {" mkdir" , {1 , 4 , {true , do_mkdir}}},
1245
+ {" mkdir" , {1 , 6 , {true , do_mkdir}}},
1261
1246
// TODO: Do mount operations in vendor_init.
1262
1247
// mount_all is currently too complex to run in vendor_init as it queues action triggers,
1263
1248
// imports rc scripts, etc. It should be simplified and run in vendor_init context.
0 commit comments