Commit graph

53 commits

Author SHA1 Message Date
Dan Austin
b43eb943ae Fix null pointer dereference in auditParse
There is an issue in LogAudit::auditParse where
android::uidToName(uid) crashes with a null pointer dereference.
Include a null check on the value before passing it on.

Bug: 120043607
Test: End-to-end test with syzkaller as per instructions in bug.
Change-Id: Ic0ac5c3003fcd289ec156ce63fbd668413763429
2018-11-27 14:01:29 -08:00
Chih-Hung Hsieh
08d470bf08 Replace (unsigned) short with (u)int16_t.
Bug: 112478838
Test: build with WITH_TIDY=1
Change-Id: I4b81e6287e72bce2d3cb67cacd6220d064818852
2018-08-13 14:24:33 -07:00
Yi Kong
c8d09ddceb [logd] Modernize codebase by replacing NULL with nullptr
Fixes -Wzero-as-null-pointer-constant warning.

Test: m
Bug: 68236239
Change-Id: I15ccb9cfc9967dae4320d9690f5097bc2f7d5bfe
2018-07-13 17:50:55 -07:00
Yi Kong
760a35a91c Remove execute bit for source files
Test: ls -l
Change-Id: Id09514a03f82c89e6350a5f9e34b9ef8bfe27b7e
2018-07-13 17:45:39 -07:00
Jeff Vander Stoep
d885890e78 Logd: include app package name in selinux metadata
Note: denial metadata is currently only included on debug builds.

avc: denied { read } for comm="getprop" name="u:object_r:net_dns_prop:s0"
dev="tmpfs" ino=19605 scontext=u:r:untrusted_app:s0:c164,c256,c512,c768
tcontext=u:object_r:net_dns_prop:s0 tclass=file permissive=0 b/12345678
app=android.selinuxtargetsdkcurrent.cts

Bug: 9496886
Bug: 68016944
Test: cts-tradefed run cts -m CtsSelinuxTargetSdkCurrentTestCases
Change-Id: I1700722a45b75d22f17ba4edc7b95cbaf99fdda8
2018-05-03 22:40:18 -07:00
Max Bires
b8716687f1 Fixing a bug introduced due to refactoring var names
SELinux messages weren't properly filtering into the events buffer
because message_len was being used to determine length of event data
instead of str_len

Bug: 65597269
Test: SELinux denials show up in the events buffer
Change-Id: I857e10211f71dd0db33a272241c7051c5d0c59ca
(cherry picked from commit 3a5acdaa8d)
2018-05-03 15:25:02 -07:00
Jeff Vander Stoep
54c7a5f1e7 LogAudit: remove dynamic rate limiter
Select a low rate-limit to cut down on logspam and resulting
performance regressions.

Functionally reverts 247d682fe1
(logd: sepolicy dynamic rate limiting) and sets a static low
rate-limit. Before 247d682f, the limit was statically set to 20.
247d682f continued to support 20, but if sustained dropped the limit
to 5. This revert leaves us at 5 so as not to impact performance.

Test: /data/nativetest/logd-unit-tests/logd-unit-tests \
    --gtest_filter=logd.sepolicy_rate_limiter
    [  PASSED  ] 1 test.
Bug: 71538411
Change-Id: I6c92f4ba825cc24beb8f1f1b79258fa8097c837b
2018-01-03 12:52:58 -08:00
Hao Wang
f6e2296953 logd: enhance multiple blocking readers performance
logd suffers performance degradation when multiple blocking
readers connect to it. Each time when the writer thread log
new entries, all of the readers are notified regardless of
which log id they are watching.

In this case, only give notification to the readers who are
actually watching new entries' log id. This decreases logd
CPU consumption by skipping unnecessary LogBuffer::flushTo
loops.

Test: liblog-unit-tests, logd-unit-tests & CtsLiblogTestCases
      logcat-unit-tests
Test: manual:
1.'logcat –b all' at constant heavy logging load level
2.simultaneously 'logcat –b crash' in another session,
   a healthy crash buffer usually keep empty
3.logd CPU consumption doesn't increase after step 2

Change-Id: I4ffc045c9feb7a0998f7e47ae2173f8f6aa28e8a
2017-12-05 18:46:24 +08:00
Max Bires
4214d132b3 Add a feature to show which bugs are tracking which se denials
The feature references a new file created by the selinux make system
that is stored on device under /system/etc/selinux/ which contains a
scontext, tcontext, tclass, and the bug they map to. logd will
reference this map every time an selinux denial comes through to see if
it's a known denial with a bug attached and then add the bug number to
the denial that's logged.

go/selinux-bug-metadata

Bug: 34997782
Test: any denial -> bug map listed in the referenced file is correcty
displayed in the selinux denials that are logged

Change-Id: I75bab59917591ed700471a0b4922b5f02f86bee9
2017-08-23 15:05:36 -07:00
Mark Salyzyn
3c501b50b4 logd: reader/writer element locks
Switch to a reader writer lock for the Element List lock.  Also setup
for a reader writer lock for the Times list, but continue to use a
mutex where rdlock() and wrlock() are the same implementation for now.

This should improve general reader performance and prevent blocking of
other reader operations or exit by a single hung logd.reader.per
thread.  For example, a full length logcat of an empty buffer (eg:
crash log buffer) will hold a lock while the iterator scans the entire
list.

Test: gTest liblog-unit-tests, logd-unit-tests, logcat-unit-tests
Bug: 37378309
Bug: 37483775
Change-Id: If5723ff4a978e17d828a75321e8f0ba91d4a09e0
2017-04-20 08:24:38 -07:00
Mark Salyzyn
501c373916 logd: specify clang format
Switch _all_ file's coding style to match to ease all future changes.

SideEffects: None
Test: compile
Bug: 35373582
Change-Id: I470cb17f64fa48f14aafc02f574e296bffe3a3f3
2017-03-13 10:31:09 -07:00
Mark Salyzyn
247d682fe1 logd: sepolicy dynamic rate limiting
Processing overhead for selinux violation messages is costly. We want
to deal with bursts of violations, but we have no intent of allowing
that sustained burst to go unabated as there is a cost of processing
and battery usage.

Tunables in libaudit.h are:

AUDIT_RATE_LIMIT_DEFAULT 20        /* acceptable burst rate      */
AUDIT_RATE_LIMIT_BURST_DURATION 10 /* number of seconds of burst */
AUDIT_RATE_LIMIT_MAX     5         /* acceptable sustained rate  */

Since we can only asymptotically handle DEFAULT rate, we set an upper
threshold of half way between the MAX and DEFAULT rate.

Default kernel audit subsystem message rate is set to 20 a second.
If sepolicy exceeds 125 violation messages over up to ten seconds
(>=~12/s), tell kernel audit subsystem to drop the rate to 5 messages
a second.  If rate drops below 50 messages over the past ten seconds
(<5/s), tell kernel it is ok to increase the burst rate back to 20
messages a second.

Test: gTest logd-unit-tests --gtest_filter=logd.sepolicy_rate_limiter_*
Bug: 27878170
Change-Id: I843f8dcfbb3ecfbbe94a4865ea332c858e3be7f2
2017-01-04 14:46:58 -08:00
Treehugger Robot
5badada997 Merge "LogAudit.cpp: replace newlines with spaces in audit messages" 2017-01-03 22:21:37 +00:00
Nick Kralevich
2e58867771 LogAudit.cpp: replace newlines with spaces in audit messages
Some kernels have a bug which causes a newline to show up in audit
messages. The embedded newlines cause one message to look like two due
to prefix controls.

Replace any newlines with spaces. Duplicate spaces are further
consolidated in code immediately after this newly added code.

Test: create an audit message with a newline, and watch it be cleaned up.
Bug: 27878170
Change-Id: Id90c29ab9e10d3be96f51403b0293622d782422a
2017-01-03 12:39:28 -08:00
Mark Salyzyn
ce80da3018 logd: Add support for ro.logd.auditd.[main|events]
log selinux audit messages boolean (true or false, default true)
selection for logging destinations:

ro.logd.auditd - turn on logd.auditd to pick up violations.
ro.logd.auditd.dmesg - to the kernel log.
ro.logd.auditd.main - to the "main" log buffer.
ro.logd.auditd.events - to the "events" log buffer.

We used to also read logd.auditd.dmesg and persist.logd.auditd.dmesg
which do not get refreshed when /data mounts internally.  This is a
confusing state as these properties will be read after a logd crash
and restart, adjusting the behavior of the logger.  Same can be said
for logd.auditd as well.  Drop reading these other parameters.

Test: manual set r/o parameters, stop/start logd to confirm behavior
Bug: 33969000
Bug: 27878170
Change-Id: I1a6bb4a903074c9aa7b227cf583a0094d49cbefd
2017-01-03 09:44:42 -08:00
Mark Salyzyn
a2c022257c logd: record multiple duplicate messages as chatty
If a series of messages arrive from a single source with identical
message content payload, then suppress them and generate a chatty
report.  The checking is done on a per log id basis.

This alters the assumption that chatty messages are always at the
oldest entries, they now show up in the middle too.  To address this
change in behavior we print the first line, a chatty reference
which internally takes little space, then the last line in the series.

This does not conserve processing time in logd, and certainly has no
impact on the long path of formatting and submitting log messages from
from the source, but it may contribute to memory space and signal to
noise savings under heavy spammy loads.

Test: gTest liblog-unit-tests, logd-unit-tests & logcat-unit-tests
Bug: 33535908
Change-Id: I3160c36d4f4e2f8216f528605a1b3993173f4dec
2016-12-15 16:31:51 -08:00
Mark Salyzyn
c8d3194098 logd: switch to using arraysize() from libbase macros
Test: logd-unit-tests, liblog-unit-tests & logcat-unit-tests
Bug: 32450474
Change-Id: Iacdc4677f2c83898a7812c2af2c36e7ff7d92764
2016-11-03 12:27:29 -07:00
Mark Salyzyn
cfd5b080af system/core: preparation to pull back interfaces from android/log.h
Point to log/log.h where necessary, define LOG_TAG where necessary.
Accept that private/android_logger.h is suitable replacement for
log/logger.h and android/log.h.

Correct liblog/README

Effectively a cleanup and controlled select revert of
'system/core: drop or replace log/logger.h' and
'system/core: Replace log/log.h with android/log.h'.

Test: compile
Bug: 30465923
Change-Id: Ic2ad157bad6f5efe2c6af293a73bb753300b17a2
2016-10-20 08:11:39 -07:00
Mark Salyzyn
8e7e71c56a Merge \"logd: auditd: suppress multiple identical avc: messages to kmsg\"
am: 02ccdc5db9

Change-Id: I65f93004d1795e025d99ca43aa9c45c39c1c2896
2016-07-20 20:37:41 +00:00
Mark Salyzyn
4d205f8975 logd: auditd: suppress multiple identical avc: messages to kmsg
Sends first and last of a series of 3 or more indentical avc:
messages to kmsg and adds 'duplicate messages suppressed'
for the last one in the set. eg:

[67.141658] type=1400 audit(1468852100.171:70): avc: ... tcontext=u:object_r:proc:s0 tclass=file
[67.141678] type=1400 audit(1468852107.494:71): avc: ... tcontext=u:object_r:cache_file:s0 tclass=dir
[67.535202] type=1400 audit(1468852107.498:74): avc: ... tcontext=u:object_r:cache_file:s0 tclass=dir duplicate messages suppressed
[67.535227] type=1400 audit(1468852107.888:75): avc: ... tcontext=u:object_r:proc_net:s0 tclass=file

One can look at the sequence numbers in the above example to see that
four identical message were produced, two were dropped.

ToDo: Evaluate multiple streams of duplicate messages.

Bug: 30118730
Change-Id: I31dcda7c8c42edfc7a8f1bf4d9e46284c74b3d18
2016-07-18 12:30:04 -07:00
Sami Tolvanen
a742d10277 Revert "logd: enforce policy integrity"
This reverts commit 0bdad0f231.

Bug: 26902605
Change-Id: I6ce8fa7bef63c45821628265c379970eb64963a2
2016-06-14 11:14:51 -07:00
Sami Tolvanen
2060a83775 logd: add a comment about untrusted content in the audit log
A single space character in search terms separates us from a denial of
service attack that forces the device into safe mode.  This CL adds a
comment that hopefully stops the spaces from being accidentally deleted
in future.

Change-Id: I33b2632ef4211fa1688ac9c8f0cf7d0c667766c1
2016-02-29 14:10:59 -08:00
Sami Tolvanen
89e0429ce7 logd: stop log spam when integrity enforcement is suppressed
Bug: 27389331
Change-Id: I9f3bc21eb1b85b9fda4fa0a5c5b4da94e5e7cc1c
(cherry pick from commit abda9340e6)
2016-02-29 13:18:46 -08:00
Sami Tolvanen
abda9340e6 logd: stop log spam when integrity enforcement is suppressed
Bug: 27389331
Change-Id: I9f3bc21eb1b85b9fda4fa0a5c5b4da94e5e7cc1c
2016-02-29 12:08:39 -08:00
Nick Kralevich
99fb01e42a Revert "logd: Don't trigger an integrity failure on permissive SELinux denials"
external/sepolicy commit bca98efa575bedab68f2d5eaee2cd1fd1741962b
ensures that no permissive domains can be on user builds, and
external/sepolicy commit 3872ee396898fcb23bdc49c37fd02d81014aaa5f
re-enables enforcing mode on cameraserver.

The conditions which lead to the integrity failure detection
triggering can no longer occur. Revert the patch which relaxed
the detection.

This reverts commit 33ee84f871.

Bug: 27313768
Bug: 26902605
Change-Id: I8ee97d0858345695f9df8240de4e696f4a9ba008
2016-02-27 08:31:57 -08:00
Nick Kralevich
33ee84f871 logd: Don't trigger an integrity failure on permissive SELinux denials
Only trigger an integrity failure if a policy is reloaded or
SELinux is disabled. Don't trigger the integrity failure if
we see a permissive=1 denial, which could occur if an SELinux
domain is in permissive mode.

Bug: 27313768
Bug: 26902605
Change-Id: Ib85a2799eb6378ae8acdb965b1812d691183fdd3
2016-02-26 17:00:15 -08:00
Mark Salyzyn
317bfb923c logd: Allow (some) headers to be individually importable
(cherry pick from commit 2ad0bd0a9b)

LogReader.h needs to be individually importable.

Fix a few others, drop includes of local includes, let them be
included in source instead and allow headers to be included
alphabetically. Was not a complete audit since goal was to
separate LogReader.h out from the pack.

Bug: 27242723
Change-Id: Ic7759ef90995e5bd285810706af33550c73cf5b5
2016-02-25 12:42:31 -08:00
Mark Salyzyn
2ad0bd0a9b logd: Allow (some) headers to be individually importable
LogReader.h needs to be individually importable.

Fix a few others, drop includes of local includes, let them be
included in source instead and allow headers to be included
alphabetically. Was not a complete audit since goal was to
separate LogReader.h out from the pack.

Bug: 27242723
Change-Id: Ic7759ef90995e5bd285810706af33550c73cf5b5
2016-02-24 10:15:22 -08:00
Sami Tolvanen
0bdad0f231 logd: enforce policy integrity
If a SELinux policy change or a switch to permissive mode is detected
on a user build, restart the device into safe mode, and keep it there
until an OTA is applied or user data is wiped.

This change deprecates the ro.logd.auditd property.

Needs matching changes from
  I781c3059ea8d4fb2f0c923e4488b1932d69678d3
  Ica825cf2af74f5624cf4091544bd24bb5482dbe7
  Id3ca7889ede30b54b7af73dd50653ca1a20d59aa

Bug: 26902605
Change-Id: Idcdc5bff133f13c1267f0ec0a75cc8cf1ddbda0d
(cherry picked from commit d122ee65b6)
2016-02-22 14:00:43 -08:00
Sami Tolvanen
d122ee65b6 logd: enforce policy integrity
If a SELinux policy change or a switch to permissive mode is detected
on a user build, restart the device into safe mode, and keep it there
until an OTA is applied or user data is wiped.

This change deprecates the ro.logd.auditd property.

Needs matching changes from
  I781c3059ea8d4fb2f0c923e4488b1932d69678d3
  Ica825cf2af74f5624cf4091544bd24bb5482dbe7
  Id3ca7889ede30b54b7af73dd50653ca1a20d59aa

Bug: 26902605
Change-Id: Idcdc5bff133f13c1267f0ec0a75cc8cf1ddbda0d
2016-02-16 12:54:54 -08:00
Mark Salyzyn
b6bee33182 liblog: logd: support logd.timestamp = monotonic
if ro.logd.timestamp or persist.logd.timestamp are set to the value
monotonic then liblog writer, liblog printing and logd all switch to
recording/printing monotonic time rather than realtime. If reinit
detects a change for presist.logd.timestamp, correct the older entry
timestamps in place.

ToDo: A corner case condition where new log entries in monotonic time
      occur before logd reinit detects persist.logd.timestamp, there
      will be a few out-of-order entries, but with accurate
      timestamps. This problem does not happen for ro.logd.timestamp
      as it is set before logd starts.

NB: This offers a nano second time accuracy on all log entries
    that may be more suitable for merging with other system
    activities, such as systrace, that also use monotonic time. This
    feature is for debugging.

Bug: 23668800
Change-Id: Iee6dab7140061b1a6627254921411f61b01aa5c2
2015-11-03 15:15:51 -08:00
Mark Salyzyn
758058ffd8 logd: object layer format statistics
Simplify table generation by placing the line and header formatting
into each type's (UID, PID, TID) object. Switch to const return
values for the ownership passing functions (*ToName() functions
and methods). Use longer variable names to reduce confusion.

Switch from LINES To NUM for pruned column as that more accurately
reflects what is dropped since one entry can contain several lines.

Bug: 22855208
Change-Id: Ib110dce98a68cf5f844eb30f8a192a1f691eeba2
2015-10-05 09:27:57 -07:00
Mark Salyzyn
ddda212faa logd: optimize code hotspots
Discovered that we had a few libc hotspots. Adjust code to generally
reduce or nullify the number of calls to malloc, free, strlen,
strcmp, strncmp, memcmp & strncasecmp. Total gain looks to be about
3% of logd's processing time. malloc still contributes to 3%, but all
others are now total 0.5%.

Bug: 23685592
Change-Id: Ife721121667969260cdb8b055524ae90f5911278
2015-10-02 16:45:22 -07:00
Mark Salyzyn
151beac76d logd: klogd deal with nuls in dmesg
Switch to using string and length in all transactions, treating
trailing nuls the same as spaces.

ToDo: change dumpstate (bugreport) to use logcat -b printable _regardless_

Bug: 23517551
Change-Id: I42162365e6bf8ed79d356e7b689a673902116fdb
2015-09-29 15:51:38 -07:00
Mark Salyzyn
ed777e9eec logd: serialize accesses to stats helpers
Quick low-risk to resolve possible hash table corruption.
Resolved an unlikely path memory leak.

ToDo: replace lock with nested lock so no lock
      helpers are required.

Bug: 22068332
Change-Id: I303ab06608502c7d61d42f111a9c43366f184d0c
2015-06-25 07:39:24 -07:00
Mark Salyzyn
7718778793 logd: Cleanup
- Android Coding Standard for Constructors
- Side effects NONE

Change-Id: I2cda9dd73f3ac3ab58f394015cb810820093d47b
2015-05-12 15:51:46 -07:00
Mark Salyzyn
ae4d928d81 logd: Add klogd
- Add a klogd to collect the kernel logs and place them into a
  new kernel log buffer
- Parse priority, tag and message from the kernel log messages.
- Turn off pruning for worst UID for the kernel log buffer
- Sniff for 'PM: suspend exit', 'PM: suspend enter' and
  'Suspended for' messages and correct the internal definition
  time correction against monotonic dynamically.
- Discern if we have monotonic or real time (delineation 1980) in
  audit messages.
- perform appropriate math to correct the timestamp to be real time
- filter out any external sources of kernel logging

Change-Id: I8d4c7c5ac19f1f3218079ee3a05a50e2ca55f60d
2015-05-12 15:51:46 -07:00
Mark Salyzyn
202e153f94 logd: propagate ::log status
Add a return value for the ::log() methods, this allows
us to optimize the wakeup for the readers to only occur
when the log message is actually placed.

This is for a future where we may dedupe identical log
messages, filter out log messages, and certainly if we
filter the messages out with an internal logd check of
__android_log_is_loggable().

Change-Id: I763b2a7c29502ab7fa0a5d5022c7b60244fcfde4
2015-04-15 19:43:28 -07:00
Mark Salyzyn
56c6575da7 Merge "logd: syscall optimization" 2015-04-15 14:45:24 +00:00
Nick Kralevich
58ba58a97c logd: Don't embed a flexible array member within another struct
C (but not C++) has a concept of a flexible array member, which
is documented at https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html .
Using a flexible array member indicates that the structure is
really a header for a variable length object.

In logd's case, the variable length structure android_event_string_t
was embedded within another structure called
android_log_event_string_t. This makes gcc's __builtin_object_size()
function really confused. When compiling with C++,
__builtin_object_size(android_log_event_string_t.payload.data, 1)
would return 0, whereas if you compiled the code with C, the same
call would (properly) return -1.

Code which does automatic bounds checking, such as the proposed
patch at https://android-review.googlesource.com/145411 , will
cause problems for logd if this syntax is used.

Don't try to embed a variable length structure within another
structure. This doesn't appear to be valid C nor C++, and
while it's worked, it seems problematic.

Instead, inline the structure so it's one big happy structure.

Change-Id: I8ac02b7142a4f6560f5f80df2effcf720f9896fc
2015-04-07 10:12:20 -07:00
Mark Salyzyn
e3aeeeeccc logd: syscall optimization
- prset(PR_SET_NAME) call once
- No need to call getuid(), should be AID_LOGD

Change-Id: I4dde0b178bc84e711b355cd7677b0dbf905a0634
2015-04-01 19:41:59 +00:00
Mark Salyzyn
ccbadc6be0 logd: report reinit
Bug: 19681572
Change-Id: I343b9d108f064f87df79512a0fdf1b35513c3136
2015-03-12 20:38:53 +00:00
Mark Salyzyn
29eb57066c logd: use <endian.h>
Change-Id: Iba843c054ea4fbe1a26c7821b5613fdb5e8001a1
2015-03-04 13:21:41 -08:00
Mark Salyzyn
eb06de716b logd: auditd remove logDmesg method
- logDmesg method consumes considerable memory
  resources (typically 128KB depending on kernel)
- In the future (eg: klogd, syslogd) there may be need to
  feed multiple logs or threads with the retrieved data.
- By moving the actions of logDmesg into the mainline that
  instantiates the thread objects, we can leverage a single
  allocation of the the kernel log allocation.
- logDmesg (private) is replaced with log (public) which
  has a more useful and descriptive purpose for the class.

Change-Id: Ie2dd0370661493c1e596a7e486904a0e8caab9ff
2014-12-05 20:56:44 +00:00
Nick Kralevich
c234a1b879 logd: throttle SELinux denials to 20/sec
Impose a limit of 20 selinux denials per second. Denials beyond
that point don't add any value, and have the potential to cause
crashes or denial of service attacks.

Do some other misc cleanup while I'm here.

Bug: 18341932
Change-Id: I6125d629ae4d6ae131d2e53bfa41e1f50277d402
2014-11-19 13:35:36 -08:00
Mark Salyzyn
7ee2aef8e0 logd: auditd: report facility LOG_AUTH
Change-Id: Ie325e1b58f52b6c728d5cfd6f6b87287fcf32e10
2014-09-28 14:42:05 -07:00
Mark Salyzyn
6bdeee0ce6 logd: auditd: kmsg priority
Change-Id: I2016fe140e2daf6c69efbd10aef205fffb931aa1
2014-09-19 11:59:42 -07:00
Mark Salyzyn
e4369d68a2 logd: logcat: debuggerd: audit logs to events and main
- auditd spawn log copy to events and main
- logcat delete events as one of the default logs
- debuggerd do not collect events.
- squish multiple spaces
- switch from strcpy to memmove for overlapping buffers

BUG: 14626551
Change-Id: I89b30273ce931ed2b25a53ea9be48e77f4c1bbf4
2014-05-27 14:29:56 -07:00
Mark Salyzyn
989980c55d logd: logcat: debuggerd: auditd logs to events
- auditd switch to recording logs to events log id
- logcat add events as one of the default logs
- debuggerd collect events log as well.

ToDo: debuggerd & bugreport collect intermixed logs.

BUG: 14626551
Change-Id: I958f0e729b7596748be57488a38824db5645be7b
2014-05-15 08:50:50 -07:00
Mark Salyzyn
e0fa291e89 logd: add logd.auditd property
- permit us a mechanism to disable auditd
- standardize property boolean

Bug: 14275676
Change-Id: I76f245c6aee511ed44274159e0ea55915b484dda
2014-04-29 07:25:27 -07:00