From: Hyotaek Shim Date: Thu, 14 Jun 2018 03:11:02 +0000 (+0900) Subject: Add a defense code for device_power_request/release_lock() APIs X-Git-Tag: submit/tizen/20180614.063411^0 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=b8358aec238b9dd24fc649439089e30ca557a247;p=platform%2Fcore%2Fapi%2Fdevice.git Add a defense code for device_power_request/release_lock() APIs , which rejects API calls when the rate is over the threshold. -- User-side solution -- Adding a delay(100ms) between calls. -- Problem Definition -- Insensive async dbus calls like this can block dbus-daemon and others (deviced, etc.). while (1) { ret = device_power_request_lock (POWER_LOCK_DISPLAY, 0); } Program terminated with signal SIGABRT, Aborted. #0 0xb68b6964 in poll () at ../sysdeps/unix/syscall-template.S:84 84 ../sysdeps/unix/syscall-template.S: No such file or directory. [Current thread is 1 (Thread 0xb6f3f180 (LWP 367))] (gdb) bt #0 0xb68b6964 in poll () at ../sysdeps/unix/syscall-template.S:84 #1 0xb6b74c18 in g_main_context_poll (priority=, n_fds=1, fds=0xb7574c80, timeout=, context=0xb756fb00) at gmain.c:4259 #2 g_main_context_iterate (context=0xb756fb00, block=block@entry=1, dispatch=dispatch@entry=1, self=) at gmain.c:3955 #3 0xb6b74fd8 in g_main_loop_run (loop=0xb7570c50) at gmain.c:4156 #4 0xb6e345c0 in g_dbus_connection_send_message_with_reply_sync ( connection=connection@entry=0xb752d868, message=message@entry=0xb51d2180, flags=G_DBUS_SEND_MESSAGE_FLAGS_NONE, timeout_msec=10000, timeout_msec@entry=-1226030992, out_serial=out_serial@entry=0x0, cancellable=0x0, error=0xbeeaeaf4, error@entry=0xbeeaeaec) at gdbusconnection.c:2844 #5 0xb6e34b70 in g_dbus_connection_call_sync_internal (connection=connection@entry=0xb752d868, bus_name=, object_path=0xb6c91bb4 "/", interface_name=0xb6c91b9c "org.freedesktop.DBus", method_name=, method_name@entry=0x2710 , parameters=0xb515f960, parameters@entry=0xb6c91339 , reply_type=reply_type@entry=0xb6c91bb8, flags=flags@entry=G_DBUS_CALL_FLAGS_NONE, timeout_msec=timeout_msec@entry=10000, fd_list=fd_list@entry=0x0, out_fd_list=out_fd_list@entry=0x0, cancellable=cancellable@entry=0x0, error=0xbeeaeb78, error@entry=0x2710) at gdbusconnection.c:6901 #6 0xb6e37294 in g_dbus_connection_call_sync (connection=connection@entry=0xb752d868, bus_name=, object_path=, interface_name=, method_name=0xb6c91bb8 "GetConnectionUnixProcessID", parameters=0xb515f960, reply_type=reply_type@entry=0x0, flags=flags@entry=G_DBUS_CALL_FLAGS_NONE, timeout_msec=timeout_msec@entry=10000, cancellable=cancellable@entry=0x0, error=error@entry=0xbeeaeb78) at gdbusconnection.c:7128 #7 0xb6c91338 in dbus_connection_get_sender_pid (conn=conn@entry=0xb752d868, sender=sender@entry=0xb5169b58 ":1.103") at /usr/src/debug/libsyscommon-4.1/src/libgdbus/dbus-system.c:2412 #8 0xb6f798a2 in dbus_lockstate (conn=0xb752d868, sender=0xb5169b58 ":1.103", path=, iface=, name=0xb5166cd8 "lockstate", param=0xb5159360, invocation=0xb50342c0, user_data=0xb6ca230c ) at /usr/src/debug/deviced-5.0.0/src/display/display-dbus.c:128 #9 0xb6c901d6 in _method_call_handler (conn=0xb752d868, sender=0xb5169b58 ":1.103", path=0xb504f000 "/Org/Tizen/System/DeviceD/Display", iface=0xb5157aa0 "org.tizen.system.deviced.display", name=0xb5166cd8 "lockstate", param=0xb5159360, invocation=0xb50342c0, user_data=0xb7532ee0) at /usr/src/debug/libsyscommon-4.1/src/libgdbus/dbus-system.c:1048 #10 0xb6e32a60 in call_in_idle_cb (user_data=0xb50342c0) at gdbusconnection.c:5792 #11 0xb6b748e8 in g_main_dispatch (context=0xb7528f28) at gmain.c:3234 #12 g_main_context_dispatch (context=context@entry=0xb7528f28) at gmain.c:3887 #13 0xb6b74c78 in g_main_context_iterate (context=0xb7528f28, block=block@entry=1, dispatch=dispatch@entry=1, self=) at gmain.c:3960 #14 0xb6b74fd8 in g_main_loop_run (loop=0xb7529400) at gmain.c:4156 #15 0xb6f5bb66 in deviced_main (argc=, argv=) at /usr/src/debug/deviced-5.0.0/src/core/main.c:116 #16 0xb6f57ce8 in main (argc=1, argv=0xbeeaee64) at /usr/src/debug/deviced-5.0.0/src/core/main.c:126 Change-Id: Ide0b04f2af13c25a1e9347b9f3caf35736d61556 Signed-off-by: Hyotaek Shim --- diff --git a/src/power.c b/src/power.c index e3207ef..4029d2a 100755 --- a/src/power.c +++ b/src/power.c @@ -22,6 +22,7 @@ #include #include #include +#include #include "power.h" #include "display.h" @@ -443,12 +444,65 @@ static int unlock_state(display_state_e state, unsigned int flag) METHOD_UNLOCK_STATE, "ss", arr, unlock_cb, -1, NULL); } +#define CHECK_RATE_THRESHOLD 100 +#define CHECK_RATE_PERIOD_LEN 5 +static int check_rate() +{ + static int status; + static long num_calls; + static struct timeval prev; + struct timeval cur; + int ret; + + if (status < 0) + return status; + + ret = gettimeofday(&cur, NULL); + if (ret < 0) { + _E("Failed to do gettimeofday() ret=%d", ret); + return 0; + } + + if (num_calls > 0) { + long rate; + struct timeval diff; + timersub(&cur, &prev, &diff); + + if (diff.tv_sec > 0) { + rate = num_calls / diff.tv_sec; + + if (rate > CHECK_RATE_THRESHOLD) { + status = -1; + return status; + } + + if (diff.tv_sec > CHECK_RATE_PERIOD_LEN) { + /* Reset the check period */ + num_calls = 0; + return 0; + } + } + } else { + /* Start a new check period */ + prev = cur; + } + + num_calls++; + return 0; +} + int device_power_request_lock(power_lock_e type, int timeout_ms) { int ret; _I("power_lock_e = %d", type); + if (check_rate() < 0) { + _E("Rejected by too frequent calls; %d (calls per sec.) limit is over." + , CHECK_RATE_THRESHOLD); + return DEVICE_ERROR_OPERATION_FAILED; + } + if (timeout_ms < 0) return DEVICE_ERROR_INVALID_PARAMETER; @@ -473,6 +527,12 @@ int device_power_release_lock(power_lock_e type) _I("power_lock_e = %d", type); + if (check_rate() < 0) { + _E("Rejected by too frequent calls; %d (calls per sec.) limit is over." + , CHECK_RATE_THRESHOLD); + return DEVICE_ERROR_OPERATION_FAILED; + } + if (type == POWER_LOCK_CPU) { ret = unlock_state(DISPLAY_STATE_SCREEN_OFF, PM_SLEEP_MARGIN); if (ret == 0) {