Skip to content

Commit 704b59e

Browse files
Myself5travarilo
authored andcommitted
privapp_permissions: Check product privapp_permissions
* permission whitelists need to get placed on the same partition as the apps themselves * check product and system individually and generate XMLs accordingly Test: Verify missing entries for system and product get generated on hotdog Test: Verify missing entries for system and system/product get generated on taimen and maple Change-Id: I37bd5c7b738caaab93019688c6a944dc6bbffa75
1 parent 67b9604 commit 704b59e

File tree

1 file changed

+137
-21
lines changed

1 file changed

+137
-21
lines changed

tools/privapp_permissions/privapp_permissions.py

Lines changed: 137 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@
3838
Usage:
3939
Specify which apk to generate priv-app permissions for. If no apk is \
4040
specified, this will default to all APKs under "<ANDROID_PRODUCT_OUT>/ \
41-
system/priv-app".
41+
system/priv-app and (system/)product/priv-app".
4242
4343
Examples:
4444
@@ -156,9 +156,18 @@ def __init__(self, adb_path=None, aapt_path=None, use_device=None,
156156
'You must either set up your build environment, or specify a '
157157
'device to run against. See --help for more info.')
158158

159-
self.privapp_apks = self._resolve_apks(apks)
160-
self.permissions_dir = self._resolve_sys_path('system/etc/permissions')
161-
self.sysconfig_dir = self._resolve_sys_path('system/etc/sysconfig')
159+
self.system_privapp_apks, self.product_privapp_apks =(
160+
self._resolve_apks(apks))
161+
self.system_permissions_dir = (
162+
self._resolve_sys_path('system/etc/permissions'))
163+
self.system_sysconfig_dir = (
164+
self._resolve_sys_path('system/etc/sysconfig'))
165+
self.product_permissions_dir = (
166+
self._resolve_sys_path('product/etc/permissions',
167+
'system/product/etc/permissions'))
168+
self.product_sysconfig_dir = (
169+
self._resolve_sys_path('product/etc/sysconfig',
170+
'system/product/etc/sysconfig'))
162171
self.framework_res_apk = self._resolve_sys_path('system/framework/'
163172
'framework-res.apk')
164173

@@ -289,7 +298,8 @@ def _resolve_apks(self, apks):
289298
be found.
290299
"""
291300
if not apks:
292-
return self._resolve_all_privapps()
301+
return (self._resolve_all_system_privapps(),
302+
self._resolve_all_product_privapps())
293303

294304
ret_apks = []
295305
for apk in apks:
@@ -306,29 +316,77 @@ def _resolve_apks(self, apks):
306316
raise MissingResourceError('File "%s" does not exist.' % apk)
307317
else:
308318
ret_apks.append(apk)
309-
return ret_apks
319+
return ret_apks, None
310320

311-
def _resolve_all_privapps(self):
321+
def _resolve_all_system_privapps(self):
312322
"""Extract package name and requested permissions."""
313323
if self._is_android_env:
314-
priv_app_dir = os.path.join(os.environ['ANDROID_PRODUCT_OUT'],
315-
'system/priv-app')
324+
system_priv_app_dir = (
325+
os.path.join(os.environ['ANDROID_PRODUCT_OUT'],
326+
'system/priv-app'))
316327
else:
317328
try:
318-
priv_app_dir = self.adb.pull('/system/priv-app/')
329+
system_priv_app_dir = self.adb.pull('/system/priv-app/')
319330
except subprocess.CalledProcessError:
320331
raise MissingResourceError(
321332
'Directory "/system/priv-app" could not be pulled from on '
322333
'device "%s".' % self.adb.serial)
323334

324-
return get_output('find %s -name "*.apk"' % priv_app_dir).split()
335+
return get_output('find %s -name "*.apk"' % system_priv_app_dir).split()
325336

326-
def _resolve_sys_path(self, file_path):
337+
def _resolve_all_product_privapps(self):
338+
"""Extract package name and requested permissions."""
339+
if self._is_android_env:
340+
product_priv_app_dir = (
341+
os.path.join(os.environ['ANDROID_PRODUCT_OUT'],
342+
'product/priv-app'))
343+
if not os.path.exists(product_priv_app_dir):
344+
product_priv_app_dir = (
345+
os.path.join(os.environ['ANDROID_PRODUCT_OUT'],
346+
'system/product/priv-app'))
347+
else:
348+
try:
349+
product_priv_app_dir = self.adb.pull('/product/priv-app/')
350+
except subprocess.CalledProcessError:
351+
print('Warning: Directory "/product/priv-app" could not be '
352+
'pulled from on device "%s". Trying '
353+
'"/system/product/priv-app"' % self.adb.serial,
354+
file=sys.stderr)
355+
try:
356+
product_priv_app_dir = (
357+
self.adb.pull('/system/product/priv-app/'))
358+
except subprocess.CalledProcessError:
359+
raise MissingResourceError(
360+
'Directory "/system/product/priv-app" could not be '
361+
'pulled from on device "%s".' % self.adb.serial)
362+
363+
return get_output(
364+
'find %s -name "*.apk"' % product_priv_app_dir).split()
365+
366+
def _resolve_sys_path(self, file_path, fallback_file_path=None):
327367
"""Resolves a path that is a part of an Android System Image."""
328368
if self._is_android_env:
329-
return os.path.join(os.environ['ANDROID_PRODUCT_OUT'], file_path)
369+
sys_path = (
370+
os.path.join(os.environ['ANDROID_PRODUCT_OUT'], file_path))
371+
if not os.path.exists(sys_path):
372+
sys_path = (
373+
os.path.join(os.environ['ANDROID_PRODUCT_OUT'],
374+
fallback_file_path))
330375
else:
331-
return self.adb.pull(file_path)
376+
try:
377+
sys_path = self.adb.pull(file_path)
378+
except subprocess.CalledProcessError:
379+
print('Warning: Directory %s could not be pulled from on device'
380+
'"%s". Trying "/system/product/priv-app"'
381+
% (file_path, self.adb.serial), file=sys.stderr)
382+
try:
383+
sys_path = self.adb.pull(fallback_file_path)
384+
except subprocess.CalledProcessError:
385+
raise MissingResourceError(
386+
'Directory %s could not be pulled from on '
387+
'device "%s".' % (fallback_file_path, self.adb.serial))
388+
389+
return sys_path
332390

333391

334392
def get_output(command):
@@ -390,17 +448,38 @@ def parse_args():
390448
help='A list of paths to priv-app APKs to generate permissions for. '
391449
'To make a path device-side, prefix the path with "device:".'
392450
)
451+
parser.add_argument(
452+
'-w',
453+
'--writetodisk',
454+
action='store_true',
455+
default=False,
456+
required=False,
457+
help='Whether or not to store the generated permissions directly to '
458+
'a file. See --systemfile/--productfile for more information.'
459+
)
460+
parser.add_argument(
461+
'--systemfile',
462+
default='./system.xml',
463+
required=False,
464+
help='Path to system permissions file. Default value is ./system.xml'
465+
)
466+
parser.add_argument(
467+
'--productfile',
468+
default='./product.xml',
469+
required=False,
470+
help='Path to system permissions file. Default value is ./product.xml'
471+
)
393472
cmd_args = parser.parse_args()
394473

395474
return cmd_args
396475

397-
398-
def create_permission_file(resources):
476+
def create_permission_file(resources, privapp_apks, permissions_dir,
477+
sysconfig_dir, file=None):
399478
# Parse base XML files in /etc dir, permissions listed there don't have
400479
# to be re-added
401480
base_permissions = {}
402-
base_xml_files = itertools.chain(list_xml_files(resources.permissions_dir),
403-
list_xml_files(resources.sysconfig_dir))
481+
base_xml_files = itertools.chain(list_xml_files(permissions_dir),
482+
list_xml_files(sysconfig_dir))
404483
for xml_file in base_xml_files:
405484
parse_config_xml(xml_file, base_permissions)
406485

@@ -409,7 +488,7 @@ def create_permission_file(resources):
409488

410489
apps_redefine_base = []
411490
results = {}
412-
for priv_app in resources.privapp_apks:
491+
for priv_app in privapp_apks:
413492
pkg_info = extract_pkg_and_requested_permissions(resources.aapt,
414493
priv_app)
415494
pkg_name = pkg_info['package_name']
@@ -426,7 +505,8 @@ def create_permission_file(resources):
426505
results[pkg_name] = sorted(priv_perms)
427506

428507
print_xml(results, apps_redefine_base)
429-
508+
if file is not None:
509+
print_xml(results, apps_redefine_base, file)
430510

431511
def print_xml(results, apps_redefine_base, fd=sys.stdout):
432512
"""Print results to the given file."""
@@ -572,7 +652,43 @@ def cleanup():
572652
serial=args.serial,
573653
apks=args.apks
574654
)
575-
create_permission_file(tool_resources)
655+
system_permission_file=None
656+
product_permission_file=None
657+
print('#' * 80)
658+
print('#')
659+
if args.writetodisk:
660+
print('#System XML written to %s:' % args.systemfile)
661+
system_permission_file = open(args.systemfile, 'w')
662+
else:
663+
print('#System XML:')
664+
print('#')
665+
print('#' * 80)
666+
create_permission_file(
667+
tool_resources,
668+
tool_resources.system_privapp_apks,
669+
tool_resources.system_permissions_dir,
670+
tool_resources.system_sysconfig_dir,
671+
system_permission_file)
672+
if args.writetodisk:
673+
system_permission_file.close()
674+
if tool_resources.product_privapp_apks:
675+
print('#' * 80)
676+
print('#')
677+
if args.writetodisk:
678+
print('#Product XML written to %s:' % args.productfile)
679+
product_permission_file = open(args.productfile, 'w')
680+
else:
681+
print('#Product XML:')
682+
print('#')
683+
print('#' * 80)
684+
create_permission_file(
685+
tool_resources,
686+
tool_resources.product_privapp_apks,
687+
tool_resources.product_permissions_dir,
688+
tool_resources.product_sysconfig_dir,
689+
product_permission_file)
690+
if args.writetodisk:
691+
product_permission_file.close()
576692
except MissingResourceError as e:
577693
print(str(e), file=sys.stderr)
578694
exit(1)

0 commit comments

Comments
 (0)