Commit graph

5455 commits

Author SHA1 Message Date
William Roberts
29d146887e fc_sort: initial commit
Ordering matters in fc files; the last match wins. In builds where
many BOARD_SEPOLICY_DIRS are set, the order of that list becomes
increasingly important in order to maintain a cohesive built
file_contexts.

To correct this, we sort the device specific file_contexts entries
with the upstream fc_sort tool.

Change-Id: Id79cc6f434c41179d5c0d0d739c4718918b0b1dc
Signed-off-by: William Roberts <william.c.roberts@intel.com>
2016-01-07 10:11:52 -08:00
Mark Salyzyn
ea0da78589 Settings: switch to using ctl.start property instead of exec logcat
- Moves policy of what to do with buffer size changes to logd

Bug: 23685592
Change-Id: I0b12c452e01b94d264d12b30f9040f646e609340
2016-01-06 10:20:48 -08:00
Nick Kralevich
829a749351 domain_deprecated.te: Exclude recovery from auditallow for /cache/recovery
Recovery uses /cache/recovery. Exclude it from auditallow coverage.

Addresses the following SELinux log spam:

  avc:  granted  { search } for  pid=323 comm="recovery" name="recovery" dev="mmcblk0p38" ino=12 scontext=u:r:recovery:s0 tcontext=u:object_r:cache_recovery_file:s0 tclass=dir
  avc:  granted  { read } for  pid=323 comm="recovery" name="block.map" dev="mmcblk0p38" ino=26 scontext=u:r:recovery:s0 tcontext=u:object_r:cache_recovery_file:s0 tclass=file
  avc:  granted  { getattr } for  pid=323 comm="recovery" path="/cache/recovery/block.map" dev="mmcblk0p38" ino=26 scontext=u:r:recovery:s0 tcontext=u:object_r:cache_recovery_file:s0 tclass=file

Change-Id: Ib6c7b44ac23fccaf2ea506429fb760ee85e87c76
2016-01-06 09:37:13 -08:00
Jeff Vander Stoep
956ca4c504 untrusted_app: remove mtp_device perms
No longer necessary after android.process.media moved to the
priv_app domain. Verified no new denials via audit2allow rule.

Bug: 25085347
Change-Id: I2d9498d5d92e79ddabd002b4a5c6f918e1eb9bcc
2016-01-06 17:05:28 +00:00
Daniel Cashman
f02db47bc2 Merge "Add sysfs_batteryinfo label." 2016-01-06 01:16:15 +00:00
Josh Gao
751c007570 Merge "debuggerd.te: allow debuggerd to drop root." 2016-01-06 00:01:09 +00:00
dcashman
a31755fa1c Add sysfs_batteryinfo label.
Shell user needs to be able to get current device battery_level via
/sys/class/power_supply/battery/capacity.  Create a global label and
corresponding policy for accessing this.  Rely on each device to label
the appropriate sysfs entry.

Bug: 26219114
Change-Id: I2c5ef489a9db2fdf7bbd5afd04278214b814351c
2016-01-05 15:54:05 -08:00
Josh Gao
2b93db7795 debuggerd.te: allow debuggerd to drop root.
Bug: http://b/25195825
Change-Id: I70257d5e40332f315020547baaa77a92fdfc58b0
2016-01-05 15:25:11 -08:00
dcashman
f226b0c945 Log app access to sysfs for removal.
Bug: 22032619
Change-Id: Ic160e0beef353c6dc5fb5e2d6a09a5628f067fe3
2016-01-05 12:05:06 -08:00
Felipe Leme
549ccf77e3 Creates a new permission for /cache/recovery
This permission was created mostly for dumpstate (so it can include
recovery files on bugreports when an OTA fails), but it was applied to
uncrypt and recovery as well (since it had a wider access before).

Grant access to cache_recovery_file where we previously granted access
to cache_file. Add auditallow rules to determine if this is really
needed.

BUG: 25351711
Change-Id: I07745181dbb4f0bde75694ea31b3ab79a4682f18
2016-01-04 23:11:28 +00:00
dcashman
36f255ff52 Create sysfs_zram label.
Address following denials:
avc: denied { getattr } for path="/sys/devices/virtual/block/zram0/disksize" dev="sysfs" ino=14958 scontext=u:r:init:s0 tcontext=u:object_r:sysfs_zram:s0 tclass=file permissive=0
avc: denied { search } for name="zram0" dev="sysfs" ino=14903 scontext=u:r:system_server:s0 tcontext=u:object_r:sysfs_zram:s0 tclass=dir permissive=0
avc: denied { read } for name="mem_used_total" dev="sysfs" ino=14970 scontext=u:r:system_server:s0 tcontext=u:object_r:sysfs_zram:s0 tclass=file permissive=0
avc: denied { write } for name="uevent" dev="sysfs" ino=14904 scontext=u:r:ueventd:s0 tcontext=u:object_r:sysfs_zram:s0 tclass=file permissive=0
avc: denied { open } for path="/sys/devices/virtual/block/zram0/uevent" dev="sysfs" ino=14904 scontext=u:r:ueventd:s0 tcontext=u:object_r:sysfs_zram:s0 tclass=file permissive=0
avc: denied { read } for pid=348 comm="vold" name="zram0" dev="sysfs" ino=15223 scontext=u:r:vold:s0 tcontext=u:object_r:sysfs_zram:s0 tclass=dir permissive=0
avc: denied { search } for pid=3494 comm="ContactsProvide" name="zram0"dev="sysfs" ino=15223 scontext=u:r:priv_app:s0:c512,c768 tcontext=u:object_r:sysfs_zram:s0 tclass=dir permissive=0

Bug: 22032619
Change-Id: I40cf918b7cafdba6cb3d42b04b1616a84e4ce158
2016-01-04 14:24:09 -08:00
Daniel Cashman
1e5b7a1962 Merge changes from topic 'sepolicy-makefile-cleanup'
* changes:
  Android.mk: cleanse all set but not unset variables
  Android.mk: clean dependencies and clear variables
2015-12-29 17:34:23 +00:00
Pavlin Radoslavov
97a3921259 Minor cleanup to align the content with Master
No functional changes.

Change-Id: Ib6246932a2b491b77bafb1ce19e7b2285abec65e
2015-12-28 16:57:21 -08:00
William Roberts
50a478ef72 Android.mk: cleanse all set but not unset variables
Discovered by diffing the set of "set variables" with
the set of "cleared variables".

Script:

mydir=$(mktemp -d)

grep -E '(^[a-z].)[a-z0-9_\.]*\s*:?=.' Android.mk  | cut -d' ' -f 1-1 | sort | uniq > $mydir/set_vars
grep -E '(^[a-z].)[a-z0-9_\.]*\s*:?=$' Android.mk | cut -d' ' -f1-1 | sort | uniq > $mydir/unset_vars
diff $mydir/set_vars $mydir/unset_vars
rm -rf $mydir

Change-Id: Ib50abac6b417a1bcc1894d9a7bafdbdca371006a
Signed-off-by: William Roberts <william.c.roberts@intel.com>
2015-12-28 16:19:54 -08:00
William Roberts
46749752e5 Android.mk: clean dependencies and clear variables
Dependencies being built with newline files in between
were also including the list of files without the newlines,
thus make would have to process 3n-1 files instead of 2n-1
where n is the number of files to process.

Additionally the *_with_nl variables were not being cleared
out and polluting Make's global name-space.

Change-Id: I76ea1a3dfae994b32991730aea7e4308da52a583
Signed-off-by: William Roberts <william.c.roberts@intel.com>
2015-12-28 16:17:24 -08:00
Daichi Hirono
a20802ddb8 Add new rules for appfuse.
The new rules are used to allow to mount FUSE file system for priv-app.

Change-Id: I5ce2d261be501e2b3fef09b7666f1e5d1cddbe52
2015-12-24 11:32:41 +09:00
Mark Salyzyn
7fbab48344 Merge "Settings: Add option to disable logging" 2015-12-23 23:15:10 +00:00
Mark Salyzyn
8179eb811d Settings: Add option to disable logging
Bug: 26178938
Change-Id: I07eebf9f3854aa447950909b6e97a565b2846644
2015-12-23 22:09:12 +00:00
Nick Kralevich
f8f937a16f undeprecate /proc/cpuinfo, more shell permissions
Access to /proc/cpuinfo was moved to domain_deprecated in commit
6e3506e1ba. Restore access to everyone.

Allow the shell user to stat() /dev, and vfsstat() /proc and other
labeled filesystems such as /system and /data.

Access to /proc/cpuinfo was explicitly granted to bootanim, but is no
longer required after moving it back to domain.te. Delete the redundant
entry.

Commit 4e2d22451f restored access to
/sys/devices/system/cpu for all domains, but forgot to remove the
redundant entry from bootanim.te. Cleanup the redundant entry.

Addresses the following denials:

  avc: denied { getattr } for pid=23648 comm="bionic-unit-tes" name="/" dev="proc" ino=1 scontext=u:r:shell:s0 tcontext=u:object_r:proc:s0 tclass=filesystem permissive=0
  avc: denied { read } for name="cpuinfo" dev="proc" ino=4026533615 scontext=u:r:shell:s0 tcontext=u:object_r:proc_cpuinfo:s0 tclass=file permissive=0
  avc: denied { getattr } for pid=23713 comm="bionic-unit-tes" path="/dev" dev="tmpfs" ino=11405 scontext=u:r:shell:s0 tcontext=u:object_r:device:s0 tclass=dir permissive=0
  avc: denied { getattr } for name="/" dev="mmcblk0p30" ino=2 scontext=u:r:shell:s0 tcontext=u:object_r:labeledfs:s0 tclass=filesystem permissive=0

Bug: 26295417
Change-Id: Ia85ac91cbd43235c0f8fe0aebafffb8046cc77ec
2015-12-22 16:48:47 -08:00
Nick Kralevich
9c5b4a8a44 shell.te: allow rules before neverallow rules
By convention, allow rules should be placed before neverallow rules.

Change-Id: Icb9155bcce1f77bebbf9dc83a8c7b97e161c88a5
2015-12-22 09:40:03 -08:00
Nick Kralevich
96b1c9ca6f neverallow debugfs access
Don't allow access to the generic debugfs label. Instead, force
relabeling to a more specific type. system_server and dumpstate
are excluded from this until I have time to fix them.

Tighten up the neverallow rules for untrusted_app. It should never
be reading any file on /sys/kernel/debug, regardless of the label.

Change-Id: Ic7feff9ba3aca450f1e0b6f253f0b56c7918d0fa
2015-12-17 16:46:08 -08:00
Nick Kralevich
cf7ee8a8e5 Revert "fingerprintd.te: neverallow fingerprint data file access"
Both angler and bullhead violate these SELinux rules.

Bullhead: tee has access to these files
Angler: system_server has read/write access to these files.

Fixes the following compile time error:

  libsepol.report_failure: neverallow on line 32 of external/sepolicy/fingerprintd.te (or line 6704 of policy.conf) violated by allow tee fingerprintd_data_file:file { ioctl read write create setattr lock append rename open };
  libsepol.check_assertions: 1 neverallow failures occurred
  Error while expanding policy
  out/host/linux-x86/bin/checkpolicy:  loading policy configuration from out/target/product/bullhead/obj/ETC/sepolicy_intermediates/policy.conf

This reverts commit 604a8cae62.

Change-Id: Iabb8f2e9de96f9082cd6a790d1af80cbc6a569b1
2015-12-17 23:56:31 +00:00
Nick Kralevich
604a8cae62 fingerprintd.te: neverallow fingerprint data file access
Only fingerprintd should be creating/reading/writing/etc from
/data/system/users/[0-9]+/fpdata(/.*)? . Add a neverallow rule
(compile time assertion + CTS test) to ensure no regressions.

Change-Id: I30261a4bd880f5c4f3d90d1686a6267f60bdd413
2015-12-17 14:02:49 -08:00
Amith Yamasani
107c55393c Add policies for system_server to delete fpdata folder
Bug: 26211308
Change-Id: I8fd2d14ea52d49a33e6cdbcdf90630eea89f7dd0
2015-12-17 12:33:06 -08:00
William Roberts
cb1ab9858e sectxfile_nl: fix superfluous dependencies
The target sectxfile_nl, which is an auto-generated newline file,
has dependencies on itself and the other files. The dependencies
should be on the other files and this newline file, not the other
way around. Ideally, the *_contexts recipes should have the
dependency recorded for their "contexts" files and the newline
file.

Additionally, recipe dependencies for building the *_contexts files
depended on the list of all the contexts files with the newline file
in that list, however an additional explicit addition of the newline
file was also added in. Remove this, since its in the full list of
files.

Change-Id: Iac658923f23a8d9263d392c44003b6bda4064646
Signed-off-by: William Roberts <william.c.roberts@intel.com>
2015-12-16 14:01:58 -08:00
Nick Kralevich
5beeb81e65 init.te: allow writing to /sys/kernel/debug/tracing/tracing_on
Needed to disable tracing. See frameworks/native/cmds/atrace/atrace.rc

Also allow shell getattr access to the tracing file. That way
"ls -la" returns something meaningful.

Bug: 26217098
Change-Id: I4eee1aff1127db8945612133c8ae16c34cfbb786
2015-12-16 12:53:55 -08:00
Jeffrey Vander Stoep
d48773ab3e Merge "checkfc: add attribute test" 2015-12-16 03:35:56 +00:00
Nick Kralevich
24f62b3daa atrace.te: fix /sys/kernel/debug/tracing label
The label for /sys/kernel/debug/tracing was changed from debugfs
to debugfs_tracing in commit https://android-review.googlesource.com/187692 .
Ensure we're using the correct label.

Change-Id: I6cab9d6b9f3d96b41db26642b67d880b1ca17a8b
2015-12-14 16:04:55 -08:00
William Roberts
ad3cb39e54 checkfc: add attribute test
Enable checkfc to check *_contexts against a set of valid attributes
which must be associated with all types in the contexts file that
is being checked.

Since it's imperative that checkfc knows which file its checking to
choose the proper attribute set, the -s option is introduced to
indicate the service_contexts file. The property_contexts file continues
to use the existing -p and file_contexts requires no specification, aka
it's the default.

Failure examples:
file_contexts:
Error: type "init" is not of set: "fs_type, dev_type, file_type"

service_contexts:
Error: type "init_exec" is not of set: "service_manager_type"

property_contexts:
Error: type "bluetooth_service" is not of set: "property_type"

Change-Id: I62077e4d0760858a9459e753e14dfd209868080f
Signed-off-by: William Roberts <william.c.roberts@intel.com>
2015-12-14 23:37:10 +00:00
Nick Kralevich
fe12b61642 label /sys/kernel/debug/tracing and remove debugfs write
Start labeling the directory /sys/kernel/debug/tracing. The files
in this directory need to be writable to the shell user.

Remove global debugfs:file write access. This was added in the days
before we could label individual debugfs files.

Change-Id: I79c1fcb63b4b9b903dcabd99b6b25e201fe540a3
2015-12-14 13:57:26 -08:00
Mark Salyzyn
a9bf995425 Merge "dumpstate: storage statistics" 2015-12-14 19:58:27 +00:00
Nick Kralevich
79ecefd01e Merge "bluetoothdomain.te: drop allow bluetoothdomain self:socket create_socket_perms;" 2015-12-14 18:19:59 +00:00
Nick Kralevich
d6765a99f3 Merge "Ensure newlines are added between context config files" 2015-12-13 22:38:33 +00:00
Richard Haines
c8801fec63 Ensure newlines are added between context config files
When multiple file_contexts, service_contexts and property_contexts
are processed by the m4(1) macro processor, they will fail if one
or more of the intermediate files final line is not terminated by
a newline. This patch adds an intervening file only containing a
newline.

Change-Id: Ie66b32fe477d08c69e6d6eb1725f658adc384ce4
Signed-off-by: Richard Haines <richard_c_haines@btinternet.com>
2015-12-13 12:01:53 +00:00
Nick Kralevich
d0113ae0ae bluetoothdomain.te: drop allow bluetoothdomain self:socket create_socket_perms;
An auditallow has been in place since commit
cb835a2852 but nothing has been triggered.
Remove the rule.

Bug: 25768265
Change-Id: Ia9f35c41feabc9ccf5eb5c6dae09c68dc4f465ff
2015-12-11 16:57:45 -08:00
Nick Kralevich
a1f903dab2 bluetoothdomain.te: drop bluetooth unix_stream_socket auditallow
Yes, it's being used.

  type=1400 audit(0.0:19391): avc: granted { read write } for comm="Binder_4" path="socket:[1354209]" dev="sockfs" ino=1354209 scontext=u:r:untrusted_app:s0:c512,c768 tcontext=u:r:bluetooth:s0 tclass=unix_stream_socket
  type=1400 audit(0.0:19392): avc: granted { read } for comm="pandora.android" scontext=u:r:untrusted_app:s0:c512,c768 tcontext=u:r:bluetooth:s0 tclass=unix_stream_socket
  type=1400 audit(0.0:19393): avc: granted { read } for comm="TransportReader" scontext=u:r:untrusted_app:s0:c512,c768 tcontext=u:r:bluetooth:s0 tclass=unix_stream_socket
  type=1400 audit(0.0:19398): avc: granted { shutdown } for comm="AppLinkBluetoot" scontext=u:r:untrusted_app:s0:c512,c768 tcontext=u:r:bluetooth:s0 tclass=unix_stream_socket
  type=1400 audit(0.0:19400): avc: granted { getopt } for comm="AppLinkBluetoot" scontext=u:r:untrusted_app:s0:c512,c768 tcontext=u:r:bluetooth:s0 tclass=unix_stream_socket
  type=1400 audit(0.0:12517): avc: granted { write } for comm="MultiQueueWrite" scontext=u:r:priv_app:s0:c512,c768 tcontext=u:r:bluetooth:s0 tclass=unix_stream_socket
  type=1400 audit(0.0:12563): avc: granted { read } for comm="WearableReader" scontext=u:r:priv_app:s0:c512,c768 tcontext=u:r:bluetooth:s0 tclass=unix_stream_socket

and a lot more...

Bug: 25767747
Change-Id: I15f89be1f44eef471e432e6d9f9ecb60a43801f8
2015-12-11 16:44:23 -08:00
Mark Salyzyn
140a019aed dumpstate: storage statistics
Deal with a few audit failures

Bug: 24200279
Change-Id: Ifb8e936738ef9c8576842576315cca2825310d3a
2015-12-11 12:50:57 -08:00
Nick Kralevich
1638208fd8 su.te: dontaudit su property_type:file
The "su" domain is in globally permissive mode on userdebug/eng
builds. No SELinux denials are suppose to be generated when running
under "su".

Get rid of useless SELinux denials coming from su trying to stat
files in /dev/__properties__. For example: "ls -la /dev/__properties__"
as root.

Addresses the following denials:

  avc: denied { getattr } for pid=14692 comm="ls" path="/dev/__properties__/u:object_r:wc_transport_prop:s0" dev="tmpfs" ino=10597 scontext=u:r:su:s0 tcontext=u:object_r:wc_transport_prop:s0 tclass=file permissive=1
  avc: denied { getattr } for pid=14692 comm="ls" path="/dev/__properties__/u:object_r:qseecomtee_prop:s0" dev="tmpfs" ino=10596 scontext=u:r:su:s0 tcontext=u:object_r:qseecomtee_prop:s0 tclass=file permissive=1
  avc: denied { getattr } for pid=14692 comm="ls" path="/dev/__properties__/u:object_r:radio_atfwd_prop:s0" dev="tmpfs" ino=10595 scontext=u:r:su:s0 tcontext=u:object_r:radio_atfwd_prop:s0 tclass=file permissive=1
  avc: denied { getattr } for pid=14692 comm="ls" path="/dev/__properties__/u:object_r:qcom_ims_prop:s0" dev="tmpfs" ino=10594 scontext=u:r:su:s0 tcontext=u:object_r:qcom_ims_prop:s0 tclass=file permissive=1
  avc: denied { getattr } for pid=14692 comm="ls" path="/dev/__properties__/u:object_r:contexthub_prop:s0" dev="tmpfs" ino=10593 scontext=u:r:su:s0 tcontext=u:object_r:contexthub_prop:s0 tclass=file permissive=1

Change-Id: Ief051a107f48c3ba596a31d01cd90fb0f3442a69
2015-12-10 13:07:27 -08:00
Nick Kralevich
4e2d22451f Restore sysfs_devices_system_cpu to domain.te
Lots of processes access CPU information. This seems to be triggered
by libraries loaded into every Android process. Allow the access.

Addresses the following denials:

adbd    : type=1400 audit(0.0:3): avc: denied { search } for name="cpu" dev="sysfs" ino=32 scontext=u:r:adbd:s0 tcontext=u:object_r:sysfs_devices_system_cpu:s0 tclass=dir permissive=1
adbd    : type=1400 audit(0.0:4): avc: denied { read } for name="online" dev="sysfs" ino=34 scontext=u:r:adbd:s0 tcontext=u:object_r:sysfs_devices_system_cpu:s0 tclass=file permissive=1
adbd    : type=1400 audit(0.0:5): avc: denied { open } for path="/sys/devices/system/cpu/online" dev="sysfs" ino=34 scontext=u:r:adbd:s0 tcontext=u:object_r:sysfs_devices_system_cpu:s0 tclass=file permissive=1
adbd    : type=1400 audit(0.0:6): avc: denied { getattr } for path="/sys/devices/system/cpu/online" dev="sysfs" ino=34 scontext=u:r:adbd:s0 tcontext=u:object_r:sysfs_devices_system_cpu:s0 tclass=file permissive=1

Change-Id: Ie7bfae53bdf670028db724d2720447ead42bad35
2015-12-10 11:10:20 -08:00
Nick Kralevich
f01453ad45 Remove core_property_type from ctl_* properties
Per https://android-review.googlesource.com/185392 , ctl.* properties
are not represented as files in the filesystem. So there's no need
to grant read access to them, since it's pointless.

Remove core_property_type from these properties, which has the net
effect of removing read access to these non-existent files.

Change-Id: Ic1ca574668a3511c335a7036a2bb7993ff02c1e3
2015-12-09 08:47:02 -08:00
Nick Kralevich
5a570a4b6b Remove property read access for non-core properties
Instead of allowing global read access to all properties,
only allow read access to the properties which are part of
core SELinux policy. Device-specific policies are no longer
readable by default and need to be granted in device-specific
policy.

Grant read-access to any property where the person has write
access. In most cases, anyone who wants to write a property
needs read access to that property.

Change-Id: I2bd24583067b79f31b3bb0940b4c07fc33d09918
2015-12-08 14:47:04 -08:00
Jeffrey Vander Stoep
5ca5696e8b Revert "Migrate to upstream policy version 30"
This reverts commit 2ea23a6e1a.

Change-Id: I5e9efa56d74ab22030611cab515e050e0bb77aca
2015-12-08 18:19:04 +00:00
Tao Bao
7a0b8efe97 Merge "Allow update_verifier to access bootctrl_block_device."
am: e8b176ed44

* commit 'e8b176ed44484f680ebb4c3e1474833e7d35ff78':
  Allow update_verifier to access bootctrl_block_device.
2015-12-08 17:59:50 +00:00
Tao Bao
e8b176ed44 Merge "Allow update_verifier to access bootctrl_block_device." 2015-12-08 17:53:59 +00:00
Nick Kralevich
637af04edd Change /dev/ion from read-only to read-write
am: 71fd337f04

* commit '71fd337f040216cf24a09765589dd9a4dfbb4d4d':
  Change /dev/ion from read-only to read-write
2015-12-08 09:31:35 -08:00
Nick Kralevich
71fd337f04 Change /dev/ion from read-only to read-write
Even though /dev/ion can allocate memory when opened in read-only mode,
some processes seem to unnecessarily open it in read-write mode.
This doesn't seem to be harmful, and was originally allowed in
domain_deprecated. Re-allow it.

Bug: 25965160
Change-Id: Icaf948be89a8f2805e9b6a22633fa05b69988e4f
2015-12-08 09:05:12 -08:00
Jeffrey Vander Stoep
862e4ab15f Merge "Migrate to upstream policy version 30"
am: 9a3d490edd

* commit '9a3d490edd843e544084c487422aa54f39080876':
  Migrate to upstream policy version 30
2015-12-08 07:22:25 -08:00
Nick Kralevich
ce890bf8d5 shell.te: Restore /proc/net access
am: 99c78bf2fd

* commit '99c78bf2fdde7e765fc667043b0afaa49c9098e5':
  shell.te: Restore /proc/net access
2015-12-08 07:22:21 -08:00
Jeffrey Vander Stoep
9a3d490edd Merge "Migrate to upstream policy version 30" 2015-12-08 15:21:39 +00:00
Jeff Vander Stoep
2ea23a6e1a Migrate to upstream policy version 30
Grant untrusted_app and isolated_app unpriv_sock_perms, neverallow
priv_sock_perms to disallow access to MAC address and ESSID.

Change-Id: Idac3b657a153e7d7fdc647ff34b876a325d759b3
2015-12-08 07:18:41 -08:00