App domains which host arbitrary code must not have access to
arbitrary HwBinder services. Such access unnecessarily increases the
attack surface. The reason is twofold:
1. HwBinder servers do not perform client authentication because HIDL
currently does not expose caller UID information and, even if it
did, many HwBinder services either operate at a layer below that of
apps (e.g., HALs) or must not rely on app identity for
authorization. Thus, to be safe, the default assumption is that
a HwBinder service treats all its clients as equally authorized to
perform operations offered by the service.
2. HAL servers (a subset of HwBinder services) contain code with
higher incidence rate of security issues than system/core
components and have access to lower layes of the stack (all the way
down to hardware) thus increasing opportunities for bypassing the
Android security model.
HwBinder services offered by core components (as opposed to vendor
components) are considered safer because of point #2 above.
Always same-process aka always-passthrough HwBinder services are
considered safe for access by these apps. This is because these HALs
by definition do not offer any additional access beyond what its
client already as, because these services run in the process of the
client.
This commit thus introduces these two categories of HwBinder services
in neverallow rules.
Test: mmm system/sepolicy -- this does not change on-device policy
Bug: 34454312
Change-Id: I4f5f4dd10b3fc3bb9d262dda532d4a23dcdf061d
Temporary attribute (checked against in CTS) to point out vendor
processes that run /system executables. These are currently only down to
2-3 of them that are related to telephony on sailfish
Bug: 36463595
Test: Build succeeds for sailfish
Test: ./cts-tradefed run cts -m CtsSecurityHostTestCases -t \
android.security.cts.SELinuxHostTest#testNoExemptionsForVendorExecutingCore \
--skip-device-info --skip-preconditions --skip-connectivity-check \
--abi arm64-v8a
Change-Id: I9eb40ad259aefba73869d6a1b40186d33fa475dd
Signed-off-by: Sandeep Patil <sspatil@google.com>
The CL splits /vendor labeling from /system. Which was allowing all
processes read, execute access to /vendor.
Following directories will remain world readable
/vendor/etc
/vendor/lib(64)/hw/
Following are currently world readable but their scope
will be minimized to platform processes that require access
/vendor/app
/vendor/framework/
/vendor/overlay
Files labelled with 'same_process_hal_file' are allowed to be
read + executed from by the world. This is for Same process HALs and
their dependencies.
Bug: 36527360
Bug: 36832490
Bug: 36681210
Bug: 36680116
Bug: 36690845
Bug: 36697328
Bug: 36696623
Bug: 36806861
Bug: 36656392
Bug: 36696623
Bug: 36792803
All of the tests were done on sailfish, angler, bullhead, dragon
Test: Boot and connect to wifi
Test: Run chrome and load websites, play video in youtube, load maps w/
current location, take pictures and record video in camera,
playback recorded video.
Test: Connect to BT headset and ensure BT audio playback works.
Test: OTA sideload using recovery
Test: CTS SELinuxHostTest pass
Change-Id: I278435b72f7551a28f3c229f720ca608b77a7029
Signed-off-by: Sandeep Patil <sspatil@google.com>
Wifi Keystore HAL is a HwBinder service (currently offered by keystore
daemon) which is used by Wifi Supplicant HAL. This commit thus
switches the SELinux policy of Wifi Keystore HAL to the approach used
for non-HAL HwBinder services.
The basic idea is simimilar to how we express Binder services in the
policy, with two tweaks: (1) we don't have 'hwservicemanager find' and
thus there's no add_hwservice macro, and (2) we need loosen the
coupling between core and vendor components. For example, it should be
possible to move a HwBinder service offered by a core component into
another core component, without having to update the SELinux policy of
the vendor image. We thus annotate all components offering HwBinder
service x across the core-vendor boundary with x_server, which enables
the policy of clients to contain rules of the form:
binder_call(mydomain, x_server), and, if the service uses IPC
callbacks, also binder_call(x_server, mydomain).
Test: mmm system/sepolicy
Test: sesearch indicates to changes to binder { call transfer} between
keystore and hal_wifi_supplicant_default domains
Bug: 36896667
Change-Id: I45c4ce8159b63869d7bb6df5c812c5291776d892
Vendor and system components are only allowed to share files by
passing open FDs over HIDL. Ban all directory access and all file
accesses other than what can be applied to an open FD such as
ioctl/stat/read/write/append.
This commit asserts that core components marked with attribute
coredomain may only access core data types marked with attribute
core_data_file_type.
A temporary exemption is granted to domains that currently rely on
access.
(cherry picked from commit cd97e71084)
Bug: 34980020
Test: build Marlin policy
Change-Id: I2f0442f2628fbac1f2f7aa5ddf2a13e16b2546cc
This futher restricts neverallows for sockets which may be exposed as
filesystem nodes. This is achieved by labelling all such sockets
created by core/non-vendor domains using the new coredomain_socket
attribute, and then adding neverallow rules targeting that attribute.
This has now effect on what domains are permitted to do. This only
changes neverallow rules.
Test: mmm system/sepolicy
Bug: 36577153
(cherry picked from commit cf2ffdf0d8)
Change-Id: Iffeee571a2ff61fb9515fa6849d060649636524e
Moving the wpa_supplicant interaction from the binder keystore service
to the new wifi keystore HAL.
Denials addressed:
03-29 00:04:52.075 734 734 E SELinux : avc: denied { get } for
pid=638 uid=1010 scontext=u:r:hal_wifi_keystore_default:s0
tcontext=u:r:keystore:s0 tclass=keystore_key
Bug: 34603782
Test: Able to connect to wifi passpoint networks. Denials no longer
seen.
Change-Id: I97eb9a4aa9968056a2f1fcc7ce5509ceb62fd41e
Vendor and system components are only allowed to share files by
passing open FDs over HIDL. Ban all directory access and all file
accesses other than what can be applied to an open file:
stat/read/write/append.
This commit marks core data types as core_data_file_type and bans
access to non-core domains with an exemption for apps. A temporary
exemption is also granted to domains that currently rely on
access with TODOs and bug number for each exemption.
Bug: 34980020
Test: Build and boot Marlin. Make phone call, watch youtube video.
No new denials observed.
Change-Id: I320dd30f9f0a5bf2f9bb218776b4bccdb529b197
On PRODUCT_FULL_TREBLE devices, non-vendor domains (coredomain) and
vendor domain are not permitted to connect to each other's sockets.
There are two main exceptions: (1) apps are permitted to talk to other
apps over Unix domain sockets (this is public API in Android
framework), and (2) domains with network access (netdomain) are
permitted to connect to netd.
This commit thus:
* adds neverallow rules restricting socket connection establishment,
* temporarily exempts the domains which are currently violating this
rule from this restriction. These domains are grouped using the new
"socket_between_core_and_vendor_violators" attribute. The attribute
is needed because the types corresponding to violators are not
exposed to the public policy where the neverallow rules are.
Test: mmm system/sepolicy
Bug: 36613996
Change-Id: I458f5a09a964b06ad2bddb52538ec3a15758b003
On PRODUCT_FULL_TREBLE devices, non-vendor domains (except vendor
apps) are not permitted to use Binder. This commit thus:
* groups non-vendor domains using the new "coredomain" attribute,
* adds neverallow rules restricting Binder use to coredomain and
appdomain only, and
* temporarily exempts the domains which are currently violating this
rule from this restriction. These domains are grouped using the new
"binder_in_vendor_violators" attribute. The attribute is needed
because the types corresponding to violators are not exposed to the
public policy where the neverallow rules are.
Test: mmm system/sepolicy
Test: Device boots, no new denials
Test: In Chrome, navigate to ip6.me, play a YouTube video
Test: YouTube: play a video
Test: Netflix: play a movie
Test: Google Camera: take a photo, take an HDR+ photo, record video with
sound, record slow motion video with sound. Confirm videos play
back fine and with sound.
Bug: 35870313
Change-Id: I0cd1a80b60bcbde358ce0f7a47b90f4435a45c95
This switches Allocator HAL policy to the design which enables us to
identify all SELinux domains which host HALs and all domains which are
clients of HALs.
Allocator HAL is special in the sense that it's assumed to be always
binderized. As a result, rules in Camera HAL target hal_allocator_server
rather than hal_allocator (which would be the server and any client, if
the Allocator HAL runs in passthrough mode).
Test: Device boots up, no new denials
Test: YouTube video plays back
Test: Take photo using Google Camera app, recover a video, record a slow
motion video
Bug: 34170079
Change-Id: Ifbbca554ec221712361ee6cda94c82f254d84936
This switches Boot Control HAL policy to the design which enables us
to conditionally remove unnecessary rules from domains which are
clients of Boot Control HAL.
Domains which are clients of Boot Control HAL, such as update_server,
are granted rules targeting hal_bootctl only when the Boot Control HAL
runs in passthrough mode (i.e., inside the client's process). When the
HAL runs in binderized mode (i.e., in another process/domain, with
clients talking to the HAL over HwBinder IPC), rules targeting
hal_bootctl are not granted to client domains.
Domains which offer a binderized implementation of Boot Control HAL,
such as hal_bootctl_default domain, are always granted rules targeting
hal_bootctl.
P. S. This commit removes direct access to Boot Control HAL from
system_server because system_server is not a client of this HAL. This
commit also removes bootctrl_block_device type which is no longer
used. Finally, boot_control_hal attribute is removed because it is now
covered by the hal_bootctl attribute.
Test: Device boots up, no new denials
Test: Reboot into recovery, sideload OTA update succeeds
Test: Apply OTA update via update_engine:
1. make dist
2. Ensure device has network connectivity
3. ota_call.py -s <serial here> out/dist/sailfish-ota-*.zip
Bug: 34170079
Change-Id: I9c410c092069e431a3852b66c04c4d2a9f1a25cf
This switches most remaining HALs to the _client/_server approach.
To unblock efforts blocked on majority of HALs having to use this
model, this change does not remove unnecessary rules from clients of
these HALs. That work will be performed in follow-up commits. This
commit only adds allow rules and thus does not break existing
functionality.
The HALs not yet on the _client/_server model after this commit are:
* Allocator HAL, because it's non-trivial to declare all apps except
isolated apps as clients of this HAL, which they are.
* Boot HAL, because it's still on the non-attributized model and I'm
waiting for update_engine folks to answer a couple of questions
which will let me refactor the policy of this HAL.
Test: mmm system/sepolicy
Test: Device boots, no new denials
Test: Device boots in recovery mode, no new denials
Bug: 34170079
Change-Id: I03e6bcec2fa02f14bdf17d11f7367b62c68a14b9
This switches Sensors HAL policy to the design which enables us to
conditionally remove unnecessary rules from domains which are clients
of Sensors HAL.
Domains which are clients of Sensors HAL, such as system_server, are
granted rules targeting hal_sensors only when the Sensors HAL runs in
passthrough mode (i.e., inside the client's process). When the HAL
runs in binderized mode (i.e., in another process/domain, with clients
talking to the HAL over HwBinder IPC), rules targeting hal_sensors are
not granted to client domains.
Domains which offer a binderized implementation of Sensors HAL, such
as hal_sensors_default domain, are always granted rules targeting
hal_sensors.
P. S. This commit also removes
allow system_server sensors_device:chr_file rw_file_perms
because this is device-specific and thus not needed in device-agnostic
policy. The device-specific policy of the affected devices already has
this rule.
Test: Device boots, no new denials
Test: adb shell dumpsys sensorservice
lists tons of sensors
Test: Proprietary sensors test app indicates that there are sensors
and that the app can register to listen for updates for sensors
and that such updates arrive to the app.
Bug: 34170079
Change-Id: I61bf779070eabcb64ae73724d62b6e837319a668
Note: The existing rules allowing socket communication will be removed
once we migrate over to HIDL completely.
(cherry-pick of 2a9595ede2)
Bug: 34603782
Test: Able to connect to wifi networks.
Test: Will be sending for full wifi integration tests
(go/wifi-test-request)
Change-Id: I9ee238fd0017ec330f6eb67ef9049211f7bd4615
This starts with the reduction in the number of services that
ephemeral apps can access. Prior to this commit, ephemeral apps were
permitted to access most of the service_manager services accessible
by conventional apps. This commit reduces this set by removing access
from ephemeral apps to:
* gatekeeper_service,
* sec_key_att_app_id_provider_service,
* wallpaper_service,
* wifiaware_service,
* wifip2p_service,
* wifi_service.
Test: Device boots up fine, Chrome, Play Movies, YouTube, Netflix, work fine.
Bug: 33349998
Change-Id: Ie4ff0a77eaca8c8c91efda198686c93c3a2bc4b3
This switches Keymaster HAL policy to the design which enables us to
conditionally remove unnecessary rules from domains which are clients
of Keymaster HAL.
Domains which are clients of Keymaster HAL, such as keystore and vold
domains, are granted rules targeting hal_keymaster only when the
Keymaster HAL runs in passthrough mode (i.e., inside the client's
process). When the HAL runs in binderized mode (i.e., in another
process/domain, with clients talking to the HAL over HwBinder IPC),
rules targeting hal_keymaster are not granted to client domains.
Domains which offer a binderized implementation of Keymaster HAL, such
as hal_keymaster_default domain, are always granted rules targeting
hal_keymaster.
Test: Password-protected sailfish boots up and lock screen unlocks --
this exercises vold -> Keymaster HAL interaction
Test: All Android Keystore CTS tests pass -- this exercises keystore ->
Keymaster HAL interaction:
make cts cts-tradefed
cts-tradefed run singleCommand cts --skip-device-info \
--skip-preconditions --skip-connectivity-check --abi arm64-v8a \
--module CtsKeystoreTestCases
Bug: 34170079
Change-Id: I2254d0fdee72145721654d6c9e6e8d3331920ec7
This switches Wi-Fi HAL policy to the design which enables us to
conditionally remove unnecessary rules from domains which are clients
of Wi-Fi HAL.
Domains which are clients of Wi-Fi HAL, such as system_server domain,
are granted rules targeting hal_wifi only when the Wi-Fi HAL runs in
passthrough mode (i.e., inside the client's process). When the HAL
runs in binderized mode (i.e., in another process/domain, with clients
talking to the HAL over HwBinder IPC), rules targeting hal_wifi are
not granted to client domains.
Domains which offer a binderized implementation of Wi-Fi HAL, such as
hal_wifi_default domain, are always granted rules targeting hal_wifi.
Test: Setup Wizard (incl. adding a Google Account) completes fine with
Wi-Fi connectivity only
Test: Toggle Wi-Fi off, on, off, on
Test: Use System UI to see list of WLANs and connect to one which does
not require a password, and to one which requries a PSK
Test: ip6.me loads fine in Chrome over Wi-Fi
Bug: 34170079
Change-Id: I7a216a06727c88b7f2c23d529f67307e83bed17f
This switches Dumpstate HAL policy to the design which enables us to
conditionally remove unnecessary rules from domains which are clients
of Dumpstate HAL.
Domains which are clients of Dumpstate HAL, such as dumpstate domain,
are granted rules targeting hal_dumpstate only when the Dumpstate HAL
runs in passthrough mode (i.e., inside the client's process). When the
HAL runs in binderized mode (i.e., in another process/domain, with
clients talking to the HAL over HwBinder IPC), rules targeting
hal_dumpstate are not granted to client domains.
Domains which offer a binderized implementation of Dumpstate HAL, such
as hal_dumpstate_default domain, are always granted rules targeting
hal_dumpstate.
Test: adb bugreport
Test: Take bugreport through system UI
Bug: 34170079
Change-Id: I3e827534af03cdfa876921c5fa4af3a53025ba27
This switches Fingerprint HAL policy to the design which enables us to
conditionally remove unnecessary rules from domains which are clients
of Bluetooth HAL.
Domains which are clients of Fingerprint HAL, such as system_server
domain, are granted rules targeting hal_fingerprint only when the
Fingerprint HAL runs in passthrough mode (i.e., inside the client's
process). When the HAL runs in binderized mode (i.e., in another
process/domain, with clients talking to the HAL over HwBinder IPC),
rules targeting hal_fingerprint are not granted to client domains.
Domains which offer a binderized implementation of Fingerprint HAL,
such as hal_fingerprint_default domain, are always granted rules
targeting hal_fingerprint.
NOTE: This commit also removes unnecessary allow rules from
Fingerprint HAL, such access to servicemanager (not hwservicemanager)
and access to keystore daemon over Binder IPC. Fingerprint HAL does
not use this functionality anyway and shouldn't use it either.
Test: Enable fingerprint + PIN secure lock screen, confirm it unlocks
with fingerprint or PIN
Test: Disable PIN (and thus fingerprint) secure lock screen
Test: make FingerprintDialog, install, make a fake purchase
Test: Add fingerprint_hidl_hal_test to device.mk, build & add to device,
adb shell stop,
adb shell /data/nativetest64/fingerprint_hidl_hal_test/fingerprint_hidl_hal_test -- all tests pass
Bug: 34170079
Change-Id: I6951c0f0640194c743ff7049357c77f5f21b71a1
This switches DRM HAL policy to the design which enables us to
conditionally remove unnecessary rules from domains which are clients
of DRM HAL.
Domains which are clients of DRM HAL, such as mediadrmserver domain,
are granted rules targeting hal_drm only when the DRM HAL runs in
passthrough mode (i.e., inside the client's process). When the HAL
runs in binderized mode (i.e., in another process/domain, with
clients talking to the HAL over HwBinder IPC), rules targeting hal_drm
are not granted to client domains.
Domains which offer a binderized implementation of DRM HAL, such as
hal_drm_default domain, are always granted rules targeting hal_drm.
Test: Play movie using Google Play Movies
Test: Play movie using Netflix
Bug: 34170079
Change-Id: I3ab0e84818ccd61e54b90f7ade3509b7dbf86fb9
This switches Bluetooth HAL policy to the design which enables us to
conditionally remove unnecessary rules from domains which are clients
of Bluetooth HAL.
Domains which are clients of Bluetooth HAL, such as bluetooth domain,
are granted rules targeting hal_bluetooth only when the Bluetooth HAL
runs in passthrough mode (i.e., inside the client's process). When the
HAL runs in binderized mode (i.e., in another process/domain, with
clients talking to the HAL over HwBinder IPC), rules targeting
hal_bluetooth are not granted to client domains.
Domains which offer a binderized implementation of Bluetooth HAL, such
as hal_bluetooth_default domain, are always granted rules targeting
hal_bluetooth.
Test: Toggle Bluetooth off and on
Test: Pair with another Android, and transfer a file to that Android
over Bluetooth
Test: Pair with a Bluetooth speaker, play music through that
speaker over Bluetooth
Test: Add bluetooth_hidl_hal_test to device.mk, build & add to device,
adb shell stop,
adb shell /data/nativetest64/bluetooth_hidl_hal_test/bluetooth_hidl_hal_test
Bug: 34170079
Change-Id: I05c3ccf1e98cbbc1450a81bb1000c4fb75eb8a83
This switches Camera HAL policy to the design which enables us to
conditionally remove unnecessary rules from domains which are clients
of Camera HAL.
Domains which are clients of Camera HAL, such as cameraserver domain,
are granted rules targeting hal_camera only when the Camera HAL runs
in passthrough mode (i.e., inside the client's process). When the HAL
runs in binderized mode (i.e., in another process/domain, with clients
talking to the HAL over HwBinder IPC), rules targeting hal_camera are
not granted to client domains.
Domains which offer a binderized implementation of Camera HAL, such
as hal_camera_default domain, are always granted rules targeting
hal_camera.
Test: Take non-HDR photo using Google Camera app
Test: Take HDR photo using Google Camera app
Test: Record video using Google Camera app
Bug: 34170079
Change-Id: I463646cf79fede57f11ccd4ec2cbc37a4fff141e
This starts the switch for HAL policy to the approach where:
* domains which are clients of Foo HAL are associated with
hal_foo_client attribute,
* domains which offer the Foo HAL service over HwBinder are
associated with hal_foo_server attribute,
* policy needed by the implementation of Foo HAL service is written
against the hal_foo attribute. This policy is granted to domains
which offer the Foo HAL service over HwBinder and, if Foo HAL runs
in the so-called passthrough mode (inside the process of each
client), also granted to all domains which are clients of Foo HAL.
hal_foo is there to avoid duplicating the rules for hal_foo_client
and hal_foo_server to cover the passthrough/in-process Foo HAL and
binderized/out-of-process Foo HAL cases.
A benefit of associating all domains which are clients of Foo HAL with
hal_foo (when Foo HAL is in passthrough mode) is that this removes the
need for device-specific policy to be able to reference these domains
directly (in order to add device-specific allow rules). Instead,
device-specific policy only needs to reference hal_foo and should no
longer need to care which particular domains on the device are clients
of Foo HAL. This can be seen in simplification of the rules for
audioserver domain which is a client of Audio HAL whose policy is
being restructured in this commit.
This commit uses Audio HAL as an example to illustrate the approach.
Once this commit lands, other HALs will also be switched to this
approach.
Test: Google Play Music plays back radios
Test: Google Camera records video with sound and that video is then
successfully played back with sound
Test: YouTube app plays back clips with sound
Test: YouTube in Chrome plays back clips with sound
Bug: 34170079
Change-Id: I2597a046753edef06123f0476c2ee6889fc17f20
Motivation:
Provide the ability to phase in new security policies by
applying them to apps with a minimum targetSdkVersion.
Place untrusted apps with targetSdkVersion<=25 into the
untrustd_app_25 domain. Apps with targetSdkVersion>=26 are placed
into the untrusted_app domain. Common rules are included in the
untrusted_app_all attribute. Apps with a more recent targetSdkVersion
are granted fewer permissions.
Test: Marlin builds and boots. Apps targeting targetSdkVersion<=25
run in untrusted_app_25 domain. Apps targeting the current development
build >=26 run in the untrusted_app domain with fewer permissions. No
new denials observed during testing.
Bug: 34115651
Bug: 35323421
Change-Id: Ie6a015566fac07c44ea06c963c40793fcdc9a083
This change adds selinux policy for configstore@1.0 hal. Currently, only
surfaceflinger has access to the HAL, but need to be widen.
Bug: 34314793
Test: build & run
Merged-In: I40e65032e9898ab5f412bfdb7745b43136d8e964
Change-Id: I40e65032e9898ab5f412bfdb7745b43136d8e964
(cherry picked from commit 5ff0f178ba)
This adds the premissions required for
android.hardware.keymaster@2.0-service to access the keymaster TA
as well as for keystore and vold to lookup and use
android.hardware.keymaster@2.0-service.
IT DOES NOT remove the privileges from keystore and vold to access
the keymaster TA directly.
Test: Run keystore CTS tests
Bug: 32020919
(cherry picked from commit 5090d6f324)
Change-Id: Ib02682da26e2dbcabd81bc23169f9bd0e832eb19
Bug: 31015010
cherry-pick from b6e4d4bdf1
Test: checked for selinux denial msgs in the dmesg logs.
Change-Id: I8285ea05162ea0d75459e873e5c2bad2dbc7e5ba
- Allow cameraservice to talk to hwbinder, hwservicemanager
- Allow hal_camera to talk to the same interfaces as cameraservice
Test: Compiles, confirmed that cameraservice can call hwservicemanager
Bug: 32991422
Change-Id: Ied0a3f5f7149e29c468a13887510c78d555dcb2a
This marks all HAL domain implementations with the haldomain attribute
so that rules can be written which apply to all HAL implementations.
This follows the pattern used for appdomain, netdomain and
bluetoothdomain.
Test: No change to policy according to sesearch.
Bug: 34180936
Change-Id: I0cfe599b0d49feed36538503c226dfce41eb65f6
Move from fingerprintd to new fingerprint_hal and update SeLinux policy.
Test: Boot with no errors related to fingerprint sepolicy
Bug: 33199080
Change-Id: Idfde0cb0530e75e705033042f64f3040f6df22d6
The following are the avc denials that are addressed:
avc: denied { call } for pid=889 comm="system_server"
scontext=u:r:system_server:s0 tcontext=u:r:hal_gnss_default:s0
tclass=binder permissive=0
avc: denied { call } for scontext=u:r:hal_gnss_default:s0
tcontext=u:r:system_server:s0 tclass=binder permissive=0
avc: denied { read } for name="hw" dev="mmcblk0p43" ino=1837
scontext=u:r:hal_gnss_default:s0 tcontext=u:object_r:system_file:s0
tclass=dir permissive=0
avc: denied { open } for path="/system/lib64/hw" dev="mmcblk0p43"
ino=1837 scontext=u:r:hal_gnss_default:s0
tcontext=u:object_r:system_file:s0 tclass=dir permissive=0
Bug:31974439
Test: Checked that there no more related avc denial messages related to
the GNSS HAL in dmesg.
Change-Id: I5b43dc088017a5568dd8e442726d2bf52e95b1d5
Bug: http://b/32905206
Test: Boot sailfish and no new selinux failures observed in logs
Change-Id: Id9a46180074a61f8cf8d176a7b2ebc995a13b9f9
Signed-off-by: Sandeep Patil <sspatil@google.com>