📜 ⬆️ ⬇️

27000 errors in the Tizen operating system

PVS-Studio and Tizen

This article will demonstrate that in the development of large projects, static code analysis is not just a useful, but an absolutely necessary element of the development process. I am starting a series of articles on the possibility of using the PVS-Studio static code analyzer to improve the quality and reliability of the Tizen operating system. To begin with, I checked a small part of the operating system (3.3%) and wrote out about 900 warnings indicating real errors. If we extrapolate the results, it turns out that our team is able to identify and eliminate about 27,000 errors in Tizen. Following the results of the study, I prepared a presentation, which was intended for demonstration to Samsung representatives and was devoted to possible cooperation. The meeting was postponed indefinitely, so I decided not to waste time and transform the presentation material into an article. Stock up on snacks and drinks, we are waiting for a long programmer thriller.

Perhaps, one should start with a link to the presentation “How the PVS-Studio team can improve the code of the Tizen operating system”, from which this article was born: RU - pptx , slideshare ; EN - pptx , slideshare . However, it is not necessary to watch the presentation, since all the material contained in it will be discussed here, and in more detail. The theme of the presentation overlaps with an open letter , in which we also tell that we are ready to work with the Tizen project.

With different memories and references, I finished and get to the point. The first thing to do is remind the reader what the Tizen operating system is all about.

Tizen


Tizen is an open source Linux-based operating system designed for a wide range of devices, including smartphones, Internet tablets, computers, car infotainment systems, smart TVs and digital cameras, developed and operated by corporations like Intel and Samsung. Supports hardware platforms on ARM and x86 processors. More information is available on the Wikipedia website.
')
The Tizen platform has shown steady growth over the past few years, despite the saturation of the market for operating systems for mobile and wearable devices. According to the Samsung report, the growth in sales of mobile phones with OC Tizen was 100% in 2017.

Tizen


For our team, the Tizen operating system is attractive because Samsung is interested in its reliability and makes efforts to improve the quality of the code. For example, in order to improve the quality of the code, Samsung has invested in the development of the specialized code analyzer Svace at ISP RAS. The Svace tool is used as the primary tool for securing the Tizen platform system and application software. Here are some quotes taken from the “Samsung have Invested $ 10 Million in Svace, Security Solution to Analyze Tizen Apps” note :

As a part of the Tizen Operating System (OS). This technology has been developed by ISP RAS (Institute for System Programming of the Russian Academy of Sciences), who are based in Moscow, Russia.

The Tizen SDK and Studio. If you are a C / C ++, you can perform this. It allows you to find out how to compile your memory card, such as the Null Pointers, Memory Leaks, Division by Zero, and Double Free etc.

Also worth noting is the news "In Russia, for the first time, they created a secure operating system", published on rbc.ru. Quote:

The creation of the Russian version of the operating system (OS) Tizen was announced on June 2, 2016. Tizen is an independent OS, that is, it is not tied to the Apple or Google cloud, and therefore it can be adapted to local markets, said the president of the association "Tyzen.ru" Tikhonov. The main feature of the OS is in its security, Tikhonov said. This is the first and only in Russia certified in the Federal Service for Technical and Export Control (FSTEC) mobile operating system, said a Samsung representative.

The PVS-Studio team simply could not get past such an interesting open source project without trying to test it.

Tizen analysis


The goal of the presentation I mentioned earlier was to demonstrate that the PVS-Studio analyzer finds a lot of errors of various types. This is a kind of summary of the analyzer and our team that we want to show Samsung.

The reader may doubt whether he should read this “article-summary”. Yes, it is worth it, there will be a lot of interesting and useful things here. First, it is better to learn from the mistakes of others, and not on their own. Secondly, the article perfectly shows that the static analysis methodology just needs to be applied in large-scale projects. If someone from colleagues involved in a big project assures you that they write high-quality code and almost without errors, then show him this article. I do not think that the creators of Tizen wanted the project to have many defects, but here they are - thousands of bugs.

As always, I want to remind you that static code analysis should be applied regularly. A one-time check of Tizen or any other project, of course, will be useful, but ineffective. Basically, minor errors will be found that have little effect on the performance of the project. All obvious errors were revealed by other methods, for example, due to user complaints. Does this mean that there is little use in static analysis? Of course not, simply, as I said, one-time checks are an inefficient way to use code analyzers. Analyzers should be used regularly and then many, including critical, errors will be detected at an early stage. The earlier the error is detected, the cheaper it is to fix it.

I think that:


Of course, I could be mistaken, but I did not customize the results of the research in order to show the capabilities of the PVS-Studio analyzer in the best light. This is just not necessary. The PVS-Studio analyzer is a powerful tool that finds so many defects that it simply makes no sense to falsify the results. Next, I will demonstrate how all the numbers given here were obtained.

Of course, I could not check out the entire Tizen project. Together with third-party libraries, it has 72,500,000 lines of C and C ++ code (excluding comments). Therefore, I decided to randomly check several dozen projects that are part of Tizen: Unified .

Choosing projects, I divided them into two groups. The first group is projects written directly by Samsung employees. I identified such projects by the presence of comments at the beginning of the files that look like this:

/*
* Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
....
*/

— , Tizen. , , . , efl-1.16.0:

//TIZEN_ONLY(20161121)
// Pre-rotation should be enabled only when direct
// rendering is set but client side rotation is not set
if ((sfc->direct_fb_opt) &&
    (!sfc->client_side_rotation) &&
    (evgl_engine->funcs->native_win_prerotation_set))
  {
    if (!evgl_engine->funcs->native_win_prerotation_set(eng_data))
      ERR("Prerotation does not work");
  }
//

, , .

, , . , . , - :

m_ptr = (int *)realloc(m_ptr, newSize);
if (!m_ptr) return ERROR;

, . . , , , , , .

, , , , . , .

. , . , , , , .

, , «27000 , , ». , . , .

, Samsung


: bluetooth-frwk-0.2.157, capi-appfw-application-0.5.5, capi-base-utils-3.0.0, capi-content-media-content-0.3.10, capi-maps-service-0.6.12, capi-media-audio-io-0.3.70, capi-media-codec-0.5.3, capi-media-image-util-0.1.15, capi-media-player-0.3.58, capi-media-screen-mirroring-0.1.78, capi-media-streamrecorder-0.0.10, capi-media-vision-0.3.24, capi-network-bluetooth-0.3.4, capi-network-http-0.0.23, cynara-0.14.10, e-mod-tizen-devicemgr-0.1.69, ise-engine-default-1.0.7, ise-engine-sunpinyin-1.0.10, ise-engine-tables-1.0.10, isf-3.0.186, org.tizen.app-selector-0.1.61, org.tizen.apps-0.3.1, org.tizen.bluetooth-0.1.2, org.tizen.browser-3.2.0, org.tizen.browser-profile_common-1.6.4, org.tizen.classic-watch-0.0.1, org.tizen.d2d-conv-setting-profile_mobile-1.0, org.tizen.d2d-conv-setting-profile_wearable-1.0, org.tizen.download-manager-0.3.21, org.tizen.download-manager-0.3.22, org.tizen.dpm-toolkit-0.1, org.tizen.elm-demo-tizen-common-0.1, org.tizen.indicator-0.2.53, org.tizen.inputdelegator-0.1.170518, org.tizen.menu-screen-1.2.5, org.tizen.myplace-1.0.1, org.tizen.privacy-setting-profile_mobile-1.0.0, org.tizen.privacy-setting-profile_wearable-1.0.0, org.tizen.quickpanel-0.8.0, org.tizen.screen-reader-0.0.8, org.tizen.service-plugin-sample-0.1.6, org.tizen.setting-1.0.1, org.tizen.settings-0.2, org.tizen.settings-adid-0.0.1, org.tizen.telephony-syspopup-0.1.6, org.tizen.voice-control-panel-0.1.1, org.tizen.voice-setting-0.0.1, org.tizen.volume-0.1.149, org.tizen.w-home-0.1.0, org.tizen.w-wifi-1.0.229, org.tizen.watch-setting-0.0.1, security-manager-1.2.17.

, . , .

. PVS-Studio CWE (Common Weakness Enumeration). , - , CWE-ID , . — , , , .

, . , .

,


: (2 )


. : !

-, V501. Copy-Paste. . , V501.

-, (<). — , - , . " ". , « » .

, :

bool operator <(const TSegment& other) const {
  if (m_start < other.m_start)
    return true;
  if (m_start == other.m_start)
    return m_len < m_len;                // <=
  return false;
}

PVS-Studio: V501 There are identical sub-expressions to the left and to the right of the '<' operator: m_len < m_len segmentor.h 65

Software weaknesses type — CWE-570: Expression is Always False

- , m_len, . :

return m_len < other.m_len;

: V501 There are identical sub-expressions '0 == safeStrCmp(btn_str, setting_gettext(«IDS_ST_BUTTON_OK»))' to the left and to the right of the '||' operator. setting-common-general-func.c 919

: (2 )


static void __page_focus_changed_cb(void *data)
{
  int i = 0;
  int *focus_unit = (int *)data;
  if (focus_unit == NULL || focus_unit < 0) {    // <=
    _E("focus page is wrong");
    return ;
  }
  ....
}

PVS-Studio: V503 This is a nonsensical comparison: pointer < 0. apps_view_circle_indicator.c 193

Software weaknesses type — CWE-697: Insufficient Comparison

«pointer < 0» . , (*), . :

if (focus_unit == NULL || *focus_unit < 0) {

, __page_count_changed_cb:

static void __page_count_changed_cb(void *data)
{
  int i = 0;
  int *page_cnt = (int *)data;
  if (page_cnt == NULL || page_cnt < 0) {
    _E("page count is wrong");
    return ;
  }
  ....
}

Copy-Paste . : V503 This is a nonsensical comparison: pointer < 0. apps_view_circle_indicator.c 219

alloca (1 )


, , . , . , , .

int audio_io_loopback_in_test()
{
  ....
  while (1) {
    char *buffer = alloca(size);
    if ((ret = audio_in_read(input, (void *)buffer, size)) >
        AUDIO_IO_ERROR_NONE)
    {
      fwrite(buffer, size, sizeof(char), fp);
      printf("PASS, size=%d, ret=0x%x\n", size, ret);
    } else {
      printf("FAIL, size=%d, ret=0x%x\n", size, ret);
    }
  }
  ....
}

PVS-Studio: V505 The 'alloca' function is used inside the loop. This can quickly overflow stack. audio_io_test.c 247

Software weaknesses type — CWE-770: Allocation of Resources Without Limits or Throttling

, , -, alloca. , .

, . , . , .

, , , .

, . . - , . . , , , , , .

, , — . . , .

:

char *buffer = alloca(size);
while (1) {
  if ((ret = audio_in_read(input, (void *)buffer, size)) >
      AUDIO_IO_ERROR_NONE)
  {
    fwrite(buffer, size, sizeof(char), fp);
    printf("PASS, size=%d, ret=0x%x\n", size, ret);
  } else {
    printf("FAIL, size=%d, ret=0x%x\n", size, ret);
  }
}

(1 )


, . - , . — .

void extract_input_aacdec_m4a_test(
  App * app, unsigned char **data, int *size, bool * have_frame)
{
  ....
  unsigned char buffer[100000];
  ....
DONE:
  *data = buffer;
  *have_frame = TRUE;
  if (read_size >= offset)
    *size = offset;
  else
    *size = read_size;
}

PVS-Studio: V507 Pointer to local array 'buffer' is stored outside the scope of this array. Such a pointer will become invalid. media_codec_test.c 793

Software weaknesses type — CWE-562: Return of Stack Variable Address

, . , .

, (7 )


, , .

typedef int gint;
typedef gint gboolean;  

#define BT_REQUEST_ID_RANGE_MAX 245

static gboolean req_id_used[BT_REQUEST_ID_RANGE_MAX];

void _bt_init_request_id(void)
{
  assigned_id = 0;
  memset(req_id_used, 0x00, BT_REQUEST_ID_RANGE_MAX);
}

PVS-Studio: V512 A call of the 'memset' function will lead to underflow of the buffer 'req_id_used'. bt-service-util.c 38

Software weaknesses type — CWE-131: Incorrect Calculation of Buffer Size

, memset , . memset C/C++. .

gboolean 1 , 4. 1/4 , .

:

memset(req_id_used, 0x00, BT_REQUEST_ID_RANGE_MAX * sizeof(gboolean));

:

memset(req_id_used, 0x00, sizeof(req_id_used));

, .

static void _on_atspi_event_cb(const AtspiEvent * event)
{
  ....
  char buf[256] = "\0";
  ....
  snprintf(buf, sizeof(buf), "%s, %s, ",
           name, _("IDS_BR_BODY_IMAGE_T_TTS"));
  ....
  snprintf(buf + strlen(buf), sizeof(buf),
           "%s, ", _("IDS_ACCS_BODY_SELECTED_TTS"));
  ....
}

PVS-Studio: V512 A call of the 'snprintf' function will lead to overflow of the buffer 'buf + strlen(buf)'. app_tracker.c 450

Software weaknesses type — CWE-131: Incorrect Calculation of Buffer Size

… …

, snprintf - . buf + strlen(buf). , . strlen(buf). , snprintf .

:

snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),
         "%s, ", _("IDS_ACCS_BODY_SELECTED_TTS"));

, . .

#define BT_ADDRESS_STRING_SIZE 18

typedef struct {
 unsigned char addr[6];
} bluetooth_device_address_t;

typedef struct {
 int count;
 bluetooth_device_address_t addresses[20];
} bt_dpm_device_list_t;

, addr 6 . , , BT_ADDRESS_STRING_SIZE 18.

:

dpm_result_t _bt_dpm_get_bluetooth_devices_from_whitelist(
  GArray **out_param1)
{
  dpm_result_t ret = DPM_RESULT_FAIL;
  bt_dpm_device_list_t device_list;
  ....
  for (; list; list = list->next, i++) {
    memset(device_list.addresses[i].addr, 0, BT_ADDRESS_STRING_SIZE);
    _bt_convert_addr_string_to_type(device_list.addresses[i].addr,
                                    list->data);
  }
  ....
}

PVS-Studio: V512 A call of the 'memset' function will lead to overflow of the buffer 'device_list.addresses[i].addr'. bt-service-dpm.c 226

Software weaknesses type — CWE-805: Buffer Access with Incorrect Length Value

:

memset(device_list.addresses[i].addr, 0, BT_ADDRESS_STRING_SIZE);

, , addr 6 . memset 18 , , .

4 :


if… else… if (4 )


char *voice_setting_language_conv_lang_to_id(const char* lang)
{
  ....
  } else if (!strcmp(LANG_PT_PT, lang)) {
    return "pt_PT";
  } else if (!strcmp(LANG_ES_MX, lang)) {     // <=
    return "es_MX";
  } else if (!strcmp(LANG_ES_US, lang)) {     // <=
    return "es_US";
  } else if (!strcmp(LANG_EL_GR, lang)) {
    return "el_GR";
  ....
}

PVS-Studio: V517 The use of 'if (A) {...} else if (A) {...}' pattern was detected. There is a probability of logical error presence. Check lines: 144, 146. voice_setting_language.c 144

Software weaknesses type — CWE-570 Expression is Always False

, , . , LANG_ES_MX LANG_ES_US — . :

#define LANG_ES_MX "\x45\x73\x70\x61\xC3\xB1\x6f\x6c\x20\x28\" \
 "x45\x73\x74\x61\x64\x6f\x73\x20\x55\x6e\x69\x64\x6f\x73\x29"

#define LANG_ES_US "\x45\x73\x70\x61\xC3\xB1\x6f\x6c\x20\x28\" \
 "x45\x73\x74\x61\x64\x6f\x73\x20\x55\x6e\x69\x64\x6f\x73\x29"

, . , «es_US».

. ES_MX — Spanish (Mexico), ES_US — Spanish (United States).

org.tizen.voice-setting-0.0.1. , Copy-Paste, org.tizen.voice-control-panel-0.1.1.

:


(11 )


. , :

void
isf_wsc_context_del (WSCContextISF *wsc_ctx)
{
  ....
  WSCContextISF* old_focused = _focused_ic;
  _focused_ic = context_scim;
  _focused_ic = old_focused;
  ....
}

PVS-Studio: V519 The '_focused_ic' variable is assigned values twice successively. Perhaps this is a mistake. Check lines: 1260, 1261. wayland_panel_agent_module.cpp 1261

Software weaknesses type — CWE-563 Assignment to Variable without Use ('Unused Variable')

_focused_ic . :

WSCContextISF* old_focused = _focused_ic;
_focused_ic = context_scim;
context_scim = old_focused;

, std::swap. :

std::swap(_focused_ic, context_scim);

, . , Copy-Paste.

void create_privacy_package_list_view(app_data_s* ad)
{
  ....
  Elm_Genlist_Item_Class *ttc = elm_genlist_item_class_new();
  Elm_Genlist_Item_Class *ptc = elm_genlist_item_class_new();
  Elm_Genlist_Item_Class *mtc = elm_genlist_item_class_new();
  ....
  ttc->item_style = "title";
  ttc->func.text_get = gl_title_text_get_cb;
  ttc->func.del = gl_del_cb;                   // <=

  ptc->item_style = "padding";
  ptc->func.del = gl_del_cb;

  mtc->item_style = "multiline";
  mtc->func.text_get = gl_multi_text_get_cb;
  ttc->func.del = gl_del_cb;                   // <=
  ....
}

PVS-Studio: V519 The 'ttc->func.del' variable is assigned values twice successively. Perhaps this is a mistake. Check lines: 409, 416. privacy_package_list_view.c 416

Software weaknesses type — CWE-563 Assignment to Variable without Use ('Unused Variable')

mtc->func.del.

:


11 , , , . V519 . , . :

status = Foo(0); 
status = Foo(1);
status = Foo(2);

, , :

  1. , - , , . - , (void)Foo(x);.
  2. , . , - .

, , , , . , , , . , . , , .

() ( 88)


V522 V575. V522 , , (*MyNullPtr = 2;). V575 — , (s = strlen(MyNullPtr);). V575 , , . , , V522 V575 , .

, malloc, realloc, strdup. , NULL, . , . , , , . , , .

, Tizen , . , :

static FilterModule *__filter_modules = 0;
static void
__initialize_modules (const ConfigPointer &config)
{
  ....
  __filter_modules = new FilterModule [__number_of_modules];
  if (!__filter_modules) return;
  ....
}

, new std::bad_alloc. , . , , Tizen , .

, PVS-Studio , . , - .

void QuickAccess::setButtonColor(Evas_Object* button,
                                 int r, int g, int b, int a)
{
  Edje_Message_Int_Set* msg =
  (Edje_Message_Int_Set *)malloc(sizeof(*msg) + 3 * sizeof(int));
  msg->count = 4;
  msg->val[0] = r;
  msg->val[1] = g;
  msg->val[2] = b;
  msg->val[3] = a;
  edje_object_message_send(elm_layout_edje_get(button),
                           EDJE_MESSAGE_INT_SET, 0, msg);
  free(msg);
}

PVS-Studio: V522 There might be dereferencing of a potential null pointer 'msg'. QuickAccess.cpp 743

Software weaknesses type — CWE-690: Unchecked Return Value to NULL Pointer Dereference

, malloc . , , NULL , . , , .

, . , . . dynamic_cast.

int cpp_audio_in_peek(audio_in_h input, const void **buffer,
                      unsigned int *length) {
  ....
  CAudioInput* inputHandle = 
    dynamic_cast<CAudioInput*>(handle->audioIoHandle);
  assert(inputHandle);
  inputHandle->peek(buffer, &_length);
  ....
}

PVS-Studio: V522 There might be dereferencing of a potential null pointer 'inputHandle'. cpp_audio_io.cpp 928

Software weaknesses type — CWE-690: Unchecked Return Value to NULL Pointer Dereference

. , handle->audioIoHandle CAudioInput, static_cast. , , assert release-.

, :

CAudioInput* inputHandle = 
  dynamic_cast<CAudioInput*>(handle->audioIoHandle);
if (inputHandle == nullptr) {
  assert(false);
  THROW_ERROR_MSG_FORMAT(
     CAudioError::EError::ERROR_INVALID_HANDLE, "Handle is NULL");
}

, . .

, , . , , '-' '.'. , , . , , .

int main(int argc, char *argv[])
{
  ....
  char *temp1 = strstr(dp->d_name, "-");
  char *temp2 = strstr(dp->d_name, ".");

  strncpy(temp_filename, dp->d_name,
          strlen(dp->d_name) - strlen(temp1));
  strncpy(file_format, temp2, strlen(temp2));
  ....
}

PVS-Studio:


Software weaknesses type — CWE-690: Unchecked Return Value to NULL Pointer Dereference

temp1 temp2 , '-' '.'. .

84 , , NULL. . , . : Tizen_V522_V575.txt.

(6 )


static void _content_resize(...., const char *signal)
{
  ....
  if (strcmp(signal, "portrait") == 0) {
    evas_object_size_hint_min_set(s_info.layout,
      ELM_SCALE_SIZE(width), ELM_SCALE_SIZE(height));
  } else {
    evas_object_size_hint_min_set(s_info.layout,
      ELM_SCALE_SIZE(width), ELM_SCALE_SIZE(height));
  }
  ....
}

PVS-Studio: V523 The 'then' statement is equivalent to the 'else' statement. page_setting_all.c 125

Software weaknesses type — , .

, . , evas_object_size_hint_min_set width height.

:

static Eina_Bool _move_cb(void *data, int type, void *event)
{
  Ecore_Event_Mouse_Move *move = event;

  mouse_info.move_x = move->root.x;
  mouse_info.move_y = move->root.y;

  if (mouse_info.pressed == false) {
    return ECORE_CALLBACK_RENEW;                 // <=
  }

  return ECORE_CALLBACK_RENEW;                   // <=
}

PVS-Studio: V523 The 'then' statement is equivalent to the subsequent code fragment. mouse.c 143

Software weaknesses type — CWE-393 Return of Wrong Status Code

, - , ECORE_CALLBACK_RENEW. , .

:


(1 )


: .

int _read_request_body(http_transaction_h http_transaction,
                       char **body)
{
  ....
  *body = realloc(*body, new_len + 1);
  ....
  memcpy(*body + curr_len, ptr, body_size);
  body[new_len] = '\0';                        // <=
  curr_len = new_len;
  ....
}

PVS-Studio: V527 It is odd that the '\0' value is assigned to 'char' type pointer. Probably meant: *body[new_len] = '\0'. http_request.c 370

Software weaknesses type — CWE-787: Out-of-bounds Write

. .

:

body[new_len] = '\0';

, . , , . NULL ('\0' ) . - .

..

, . . , .

:

(*body)[new_len] = '\0';

true/false (9 )


, , - , 3 .

.

unsigned m_candiPageFirst;

bool
CIMIClassicView::onKeyEvent(const CKeyEvent& key)
{
  ....
  if (m_candiPageFirst > 0) {
    m_candiPageFirst -= m_candiWindowSize;
    if (m_candiPageFirst < 0) m_candiPageFirst = 0;
    changeMasks |= CANDIDATE_MASK;
  }
  ....
}

PVS-Studio: V547 Expression 'm_candiPageFirst < 0' is always false. Unsigned type value is never < 0. imi_view_classic.cpp 201

Software weaknesses type — CWE-570: Expression is Always False

m_candiPageFirst unsigned. , . , :

if (m_candiPageFirst > 0) {
  if (m_candiPageFirst > m_candiWindowSize)
    m_candiPageFirst -= m_candiWindowSize;
  else 
    m_candiPageFirst = 0;
  changeMasks |= CANDIDATE_MASK;
}

.

void
QuickAccess::_grid_mostVisited_del(void *data, Evas_Object *)
{
  BROWSER_LOGD("[%s:%d]", __PRETTY_FUNCTION__, __LINE__);
  if (data) {
    auto itemData = static_cast<HistoryItemData*>(data);
    if (itemData)
      delete itemData;
  }
}

PVS-Studio: V547 Expression 'itemData' is always true. QuickAccess.cpp 571

Software weaknesses type — CWE-571: Expression is Always True

. data != nullptr, itemData != nullptr. , . :

  1. . static_cast dynamic_cast, nullptr.
  2. , . , .

, 1 2, , .

.

typedef enum {
  BT_HID_MOUSE_BUTTON_NONE = 0x00,
  BT_HID_MOUSE_BUTTON_LEFT = 0x01,
  BT_HID_MOUSE_BUTTON_RIGHT = 0x02,
  BT_HID_MOUSE_BUTTON_MIDDLE = 0x04
} bt_hid_mouse_button_e;

int bt_hid_device_send_mouse_event(const char *remote_address,
    const bt_hid_mouse_data_s *mouse_data)
{
  ....
  if (mouse_data->buttons != BT_HID_MOUSE_BUTTON_LEFT ||
      mouse_data->buttons != BT_HID_MOUSE_BUTTON_RIGHT ||
      mouse_data->buttons != BT_HID_MOUSE_BUTTON_MIDDLE) {
    return BT_ERROR_INVALID_PARAMETER;
  }
  ....
}

PVS-Studio: V547 Expression is always true. Probably the '&&' operator should be used here. bluetooth-hid.c 229

Software weaknesses type — CWE-571: Expression is Always True

, :

if (buttons != 1 ||
    buttons != 2 ||
    buttons != 4) {

, 1 2 4.

:


enum (18 )


, . , , .

enum, :

typedef enum {
 WIFI_MANAGER_RSSI_LEVEL_0 = 0,
 WIFI_MANAGER_RSSI_LEVEL_1 = 1,
 WIFI_MANAGER_RSSI_LEVEL_2 = 2,
 WIFI_MANAGER_RSSI_LEVEL_3 = 3,
 WIFI_MANAGER_RSSI_LEVEL_4 = 4,
} wifi_manager_rssi_level_e;

typedef enum {
 WIFI_RSSI_LEVEL_0 = 0,
 WIFI_RSSI_LEVEL_1 = 1,
 WIFI_RSSI_LEVEL_2 = 2,
 WIFI_RSSI_LEVEL_3 = 3,
 WIFI_RSSI_LEVEL_4 = 4,
} wifi_rssi_level_e;

, :

static int
_rssi_level_to_strength(wifi_manager_rssi_level_e level)
{
  switch (level) {
    case WIFI_RSSI_LEVEL_0:
    case WIFI_RSSI_LEVEL_1:
      return LEVEL_WIFI_01;
    case WIFI_RSSI_LEVEL_2:
      return LEVEL_WIFI_02;
    case WIFI_RSSI_LEVEL_3:
      return LEVEL_WIFI_03;
    case WIFI_RSSI_LEVEL_4:
      return LEVEL_WIFI_04;
    default:
      return WIFI_RSSI_LEVEL_0;
  }
}

level wifi_manager_rssi_level_e. wifi_rssi_level_e. , 5 , 5 :


Software weaknesses type — CWE-697: Insufficient Comparison

— , . , WIFI_MANAGER_RSSI_LEVEL_0 WIFI_RSSI_LEVEL_0 .

, , . :

  1. , , .
  2. enum , .

:


true/false (2 )


2 , , .

int bytestream2nalunit(FILE * fd, unsigned char *nal)
{
  unsigned char val, zero_count, i;
  ....
  val = buffer[0];
  while (!val) {                                            // <=
    if ((zero_count == 2 || zero_count == 3) && val == 1)   // <=
      break;
    zero_count++;
    result = fread(buffer, 1, read_size, fd);

    if (result != read_size)
      break;
    val = buffer[0];
  }
  ....
}

PVS-Studio: V560 A part of conditional expression is always false: val == 1. player_es_push_test.c 284

Software weaknesses type — CWE-570: Expression is Always False

, val . val 1. , val 1, . - .

.

const int GT_SEARCH_NO_LONGER = 0,
          GT_SEARCH_INCLUDE_LONGER = 1,
          GT_SEARCH_ONLY_LONGER = 2;

bool GenericTableContent::search (const String &key,
                                  int search_type) const
{
  ....
  else if (nkeys.size () > 1 && GT_SEARCH_ONLY_LONGER) {
  ....
}

PVS-Studio: V560 A part of conditional expression is always true: GT_SEARCH_ONLY_LONGER. scim_generic_table.cpp 1884

Software weaknesses type — CWE-571: Expression is Always True

GT_SEARCH_ONLY_LONGER . , :

if (nkeys.size () > 1 && search_type == GT_SEARCH_ONLY_LONGER)

(4 )


, :

struct sockaddr_un
{
  sa_family_t sun_family;
  char sun_path[108];
};

struct sockaddr_in
{
  sa_family_t sin_family;
  in_port_t sin_port;
  struct in_addr sin_addr;
  unsigned char sin_zero[sizeof (struct sockaddr) -
    (sizeof (unsigned short int)) -
    sizeof (in_port_t) -
    sizeof (struct in_addr)];
};

struct sockaddr
{
  sa_family_t sa_family;
  char sa_data[14];
};

, , :

class SocketAddress::SocketAddressImpl
{
  struct sockaddr *m_data;
  ....
  SocketAddressImpl (const SocketAddressImpl &other)
  {
    ....
    case SCIM_SOCKET_LOCAL:
        m_data = (struct sockaddr*) new struct sockaddr_un; // <=
        len = sizeof (sockaddr_un);
        break;
    case SCIM_SOCKET_INET:
        m_data = (struct sockaddr*) new struct sockaddr_in; // <=
        len = sizeof (sockaddr_in);
        break;
    ....
  }

  ~SocketAddressImpl () {
    if (m_data) delete m_data;                              // <=
  }
};

:


Software weaknesses type — CWE-762: Mismatched Memory Management Routines.

sockaddr_un sockaddr_in. sockaddr. . , . , POD ( ..) delete free. . , .

, , . , , / ( std::string), .

:


printf- (4 )


static int _write_file(const char *file_name, void *data,
                       unsigned long long data_size)
{
  FILE *fp = NULL;

  if (!file_name || !data || data_size <= 0) {
    fprintf(stderr,
            "\tinvalid data %s %p size:%lld\n",
            file_name, data, data_size);
    return FALSE;
  }
  ....
}

PVS-Studio: V576 Incorrect format. Consider checking the third actual argument of the 'fprintf' function. Under certain conditions the pointer can be null. image_util_decode_encode_testsuite.c 124

Software weaknesses type — CWE-476: NULL Pointer Dereference

, file_name NULL. printf, . printf. . "What is the behavior of printing NULL with printf's %s specifier?".

.

void subscribe_to_event()
{
  ....
  int error = ....;
  ....
  PRINT_E("Failed to destroy engine configuration for event trigger.",
          error);
  ....
}

PVS-Studio: V576 Incorrect format. A different number of actual arguments is expected while calling 'printf' function. Expected: 1. Present: 2. surveillance_test_suite.c 393

Software weaknesses type — , .

PRINT_E printf. , error . .

:


(5 )


static void _show(void *data)
{
  SETTING_TRACE_BEGIN;
  struct _priv *priv = (struct _priv *)data;
  Eina_List *children = elm_box_children_get(priv->box);    // <=
  Evas_Object *first = eina_list_data_get(children);
  Evas_Object *selected =
    eina_list_nth(children, priv->item_selected_on_show);   // <=

  if (!priv) {                                              // <=
    _ERR("Invalid parameter.");
    return;
  }
  ....
}

PVS-Studio: V595 The 'priv' pointer was utilized before it was verified against nullptr. Check lines: 110, 114. view_generic_popup.c 110

Software weaknesses type — CWE-476: NULL Pointer Dereference

priv :


. , :

static void _show(void *data)
{
  SETTING_TRACE_BEGIN;
  struct _priv *priv = (struct _priv *)data;
  if (!priv) {
    _ERR("Invalid parameter.");
    return;
  }
  Eina_List *children = elm_box_children_get(priv->box);
  Evas_Object *first = eina_list_data_get(children);
  Evas_Object *selected =
    eina_list_nth(children, priv->item_selected_on_show);
  ....
}

.

_ticker_window_create, , .

static Evas_Object *_ticker_window_create(struct appdata *ad)
{
  ....
  //    'ad'
  ....
  evas_object_resize(win, ad->win.w, indicator_height_get());
  ....
}

, NULL. , _ticker_window_create . , .

static int _ticker_view_create(void)
{
  if (!ticker.win)
    ticker.win = _ticker_window_create(ticker.ad);       // <=
  if (!ticker.layout)
    ticker.layout = _ticker_layout_create(ticker.win);
  if (!ticker.scroller)
    ticker.scroller = _ticker_scroller_create(ticker.layout);

  evas_object_show(ticker.layout);
  evas_object_show(ticker.scroller);
  evas_object_show(ticker.win);

  if (ticker.ad)                                         // <=
    util_signal_emit_by_win(&ticker.ad->win,
      "message.show.noeffect", "indicator.prog");
  ....
}

PVS-Studio: V595 The 'ticker.ad' pointer was utilized before it was verified against nullptr. Check lines: 590, 600. ticker.c 590

Software weaknesses type — CWE-476: NULL Pointer Dereference

ticker.ad _ticker_window_create. "if (ticket.ad)", , .

:


(1 )


static void SHA1Final(unsigned char digest[20],
                      SHA1_CTX* context)
{
  u32 i;
  unsigned char finalcount[8];
  ....
  memset(context->count, 0, 8);
  memset(finalcount, 0, 8);
}

PVS-Studio: V597 The compiler could delete the 'memset' function call, which is used to flush 'finalcount' buffer. The memset_s() function should be used to erase the private data. wifi_generate_pin.c 185

Software weaknesses type — CWE-14: Compiler Removal of Code to Clear Buffers

memset, finalcount. C C++, , . , , . (. V597, CWE-14).

(2 )


.

void
GenericTableContent::set_max_key_length (size_t max_key_length)
{
  ....
  std::vector<uint32> *offsets;
  std::vector<OffsetGroupAttr> *offsets_attrs;

  offsets = new(std::nothrow)                       // <=
            std::vector <uint32> [max_key_length];
  if (!offsets) return;

  offsets_attrs = new(std::nothrow)
                  std::vector <OffsetGroupAttr> [max_key_length];
  if (!offsets_attrs) {
    delete offsets;                                 // <=
    return;
  }
  ....
}

PVS-Studio: V611 The memory was allocated using 'new T[]' operator but was released using the 'delete' operator. Consider inspecting this code. It's probably better to use 'delete [] offsets;'. scim_generic_table.cpp 998

Software weaknesses type — CWE-762: Mismatched Memory Management Routines

offsets , new[]. , delete[].

.

static void __draw_remove_list(SettingRingtoneData *ad)
{
  char *full_path = NULL;
  ....
  full_path = (char *)alloca(PATH_MAX);                  // <=
  ....
  if (!select_all_item) {
    SETTING_TRACE_ERROR("select_all_item is NULL");
    free(full_path);                                     // <=
    return;
  }
  ....  
}

PVS-Studio: V611 The memory was allocated using 'alloca' function but was released using the 'free' function. Consider inspecting operation logics behind the 'full_path' variable. setting-ringtone-remove.c 88

Software weaknesses type — CWE-762: Mismatched Memory Management Routines

. , free, .

(1 )


_app_create, , , :

Eext_Circle_Surface *surface;
....
if (_WEARABLE)
  surface = eext_circle_surface_conformant_add(conform);
....
app_data->circle_surface = surface;

PVS-Studio: V614 Potentially uninitialized pointer 'surface' used. w-input-selector.cpp 896

Software weaknesses type — CWE-457: Use of Uninitialized Variable

surface , "if (_WEARABLE)".

(6 )


, , . 6, . , 6 .

void ise_show_stt_mode(Evas_Object *win)
{
  ....
  snprintf(buf, BUF_LEN, gettext("IDS_ST_SK_CANCEL"));
  ....
}

PVS-Studio: V618 It's dangerous to call the 'snprintf' function in such a manner, as the line being passed could contain format specification. The example of the safe code: printf("%s", str); ise-stt-mode.cpp 802

Software weaknesses type — CWE-134 Use of Externally-Controlled Format String

, :

  1. , - IDS_ST_SK_CANCEL . : «bla-bla %SystemDrive% bla-bla». %S , access violation.
  2. . , , .

, , , , . :

snprintf(buf, BUF_LEN, "%s", gettext("IDS_ST_SK_CANCEL"));

:


(2 )


#define PI 3.141592
void __apps_view_circle_get_pos(
             int radius, double angle, int *x, int *y)
{
  *x = radius * sin(angle * PI / 180);
  *y = radius * cos(angle * PI / 180);

  *x = *x + WINDOW_CENTER_X;
  *y = WINDOW_CENTER_Y - *y;
}

PVS-Studio:


Software weaknesses type — , .

, . 3.141592 .

, , . PI - , . M_PI, .

(4 )


__extension__ typedef long int __time_t;
__extension__ typedef long int __suseconds_t;

struct timeval
{
  __time_t tv_sec;
  __suseconds_t tv_usec;
};

static struct timeval _t0 = {0, 0};
static struct timeval _t1;

void ISF_PROF_DEBUG_TIME (....)
{
  float etime = 0.0;
  ....
  etime = ((_t1.tv_sec * 1000000 + _t1.tv_usec) -
           (_t0.tv_sec * 1000000 + _t0.tv_usec))/1000000.0;
  ....
}

PVS-Studio: V636 The '_t1.tv_sec * 1000000' expression was implicitly cast from 'long' type to 'float' type. Consider utilizing an explicit type cast to avoid overflow. An example: double A = (double)(X) * Y;. scim_utility.cpp 1492.

Software weaknesses type — CWE-681: Incorrect Conversion between Numeric Types

. . long, 32- Tizen 32-. . , long long double.

:


, (2 )


, , . , .

int bt_tds_provider_send_activation_resp(
  char *address, int result, bt_tds_provider_h provider)
{
  ....
  if (error_code != BT_ERROR_NONE)
    BT_ERR("%s(0x%08x)",
           _bt_convert_error_to_string(error_code), error_code);
    return error_code;

  return error_code;
}

PVS-Studio: V640 The code's operational logic does not correspond with its formatting. The statement is indented to the right, but it is always executed. It is possible that curly brackets are missing. bluetooth-tds.c 313

Software weaknesses type — CWE-483: Incorrect Block Delimitation

, . . :

if (error_code != BT_ERROR_NONE)
{
  BT_ERR("%s(0x%08x)",
         _bt_convert_error_to_string(error_code), error_code);
  return error_code;
}
return error_code;

return :

if (error_code != BT_ERROR_NONE)
  BT_ERR("%s(0x%08x)",
         _bt_convert_error_to_string(error_code), error_code);
return error_code;

. - :

#define MC_FREEIF(x) \
  if (x) \
    g_free(x); \
  x = NULL;

...

, :

static gboolean __mc_gst_init_gstreamer()
{
  ....
  int i = 0;
  ....
  for (i = 0; i < arg_count; i++)
    MC_FREEIF(argv2[i]);
  ....
}

PVS-Studio: V640 The code's operational logic does not correspond with its formatting. The second statement will always be executed. It is possible that curly brackets are missing. media_codec_port_gst.c 1800

Software weaknesses type — CWE-483: Incorrect Block Delimitation, CWE-787: Out-of-bounds Write

, :

for (i = 0; i < arg_count; i++)
  if (argv2[i])
    g_free(argv2[i]);
argv2[i] = NULL;

:

  1. .
  2. NULL .

(1 )


typedef unsigned char Eina_Bool;
static Eina_Bool _state_get(....)
{
  ....
  if (!strcmp(part, STATE_BROWSER))
    return !strcmp(id, APP_ID_BROWSER);
  else if (!strcmp(part, STATE_NOT_BROWSER))
    return strcmp(id, APP_ID_BROWSER);
  ....
}

PVS-Studio: V642 Saving the 'strcmp' function result inside the 'unsigned char' type variable is inappropriate. The significant bits could be lost breaking the program's logic. grid.c 137

Software weaknesses type — CWE-197: Numeric Truncation Error

strcmp int:


. « 0» , 1. : 2, 3, 100, 256, 1024, 5555 . « 0». , unsigned char, . , , 256 0.

. , MySQL/MariaDB 5.1.61, 5.2.11, 5.3.5, 5.5.22. , MySQL/MariaDB (SHA ), memcmp. [-128..127]. 1 256 true, . bash MySQL, . 'sql/password.c':

typedef char my_bool;
...
my_bool check(...) {
  return memcmp(...);
}

: Security vulnerability in MySQL/MariaDB.

Tizen. , '!'. :

else if (!strcmp(part, STATE_NOT_BROWSER))
  return !strcmp(id, APP_ID_BROWSER);

Off-by-one Error (2 )


#define OP_MAX_URI_LEN 2048
char object_uri[OP_MAX_URI_LEN];
void op_libxml_characters_dd1(....)
{
  ....
  strncat(dd_info->object_uri, ch_str,
          OP_MAX_URI_LEN - strlen(dd_info->object_uri));
  ....
}

PVS-Studio: V645 The 'strncat' function call could lead to the 'dd_info->object_uri' buffer overflow. The bounds should not contain the size of the buffer, but a number of characters it can hold. oma-parser-dd1.c 422

Software weaknesses type — CWE-193: Off-by-one Error

, strncat , , . :

char buf[5] = "ABCD";
strncat(buf, "E", 5 - strlen(buf));

. 4 . 5 — strlen(buf) 1. strncpy E . 0 .

:

strncat(dd_info->object_uri, ch_str,
        OP_MAX_URI_LEN - strlen(dd_info->object_uri) - 1);

: V645 The 'strncat' function call could lead to the 'dd_info->name' buffer overflow. The bounds should not contain the size of the buffer, but a number of characters it can hold. oma-parser-dd1.c 433

C. (1 )


void person_recognized_cb(
  mv_surveillance_event_trigger_h handle,
  mv_source_h source,
  int video_stream_id,
  mv_surveillance_result_h event_result,
  void *user_data)
{
  ....
  int *labels = malloc(sizeof(int) * number_of_persons);
  ....
}

PVS-Studio: V647 The value of 'int' type is assigned to the pointer of 'int' type. surveillance_test_suite.c 928

Software weaknesses type — CWE-822: Untrusted Pointer Dereference

. «», Tizen 64- .

, malloc, .. #include <stdlib.h>. , i-. , , int. , , int .

32- , int. 64- , . " 64- " (. 7. .)

, new, malloc, NULL (54 )


malloc, , NULL. new std::bad_alloc.

, new nullptr, nothrow :

P = new (std::nothrow) T;

PVS-Studio new new, .

PVS-Studio , , new .

. .

template <class T> class vector {
private:
  ....
  void push_back(const T &value)
  {
    T *clone = new T(value);
    if (clone) {
      g_array_append_val(parray, clone);
      current_size++;
    }
  }
  ....
};

PVS-Studio: V668 There is no sense in testing the 'clone' pointer against null, as the memory was allocated using the 'new' operator. The exception will be generated in the case of memory allocation error. maps_util.h 153

Software weaknesses type — CWE-697: Insufficient Comparison / CWE-571: Expression is Always True

. , , .

.

bool CThreadSlm::load(const char* fname, bool MMap)
{
  int fd = open(fname, O_RDONLY);
  ....
  if ((m_buf = new char[m_bufSize]) == NULL) {
    close(fd);
    return false;
  }
  ....
}

PVS-Studio: V668 There is no sense in testing the 'm_buf' pointer against null, as the memory was allocated using the 'new' operator. The exception will be generated in the case of memory allocation error. slm.cpp 97

Software weaknesses type — . , :

  1. CWE-697: Insufficient Comparison
  2. CWE-570: Expression is Always False
  3. CWE-404: Improper Resource Shutdown or Release

, , false. , , . , .

, malloc new. :

void SettingsAFCreator::createNewAutoFillFormItem()
{
  ....
  auto item_data = new AutoFillFormItemData;
  if (!item_data) {
    BROWSER_LOGE("Malloc failed to get item_data");
    return;
  }
  ....
}

PVS-Studio: V668 There is no sense in testing the 'item_data' pointer against null, as the memory was allocated using the 'new' operator. The exception will be generated in the case of memory allocation error. SettingsAFCreator.cpp 112

, - malloc.

. malloc new . malloc , , .

3 . 51 . , Tizen_V668.txt.

integer double (1 )


, , .. , . ( ).



PVS-Studio: V674 The '0.5' literal of the 'double' type is assigned to a variable of the 'int' type. Consider inspecting the '= 0.5' expression. add-viewer.c 824

Software weaknesses type — CWE-681: Incorrect Conversion between Numeric Types

, delay, . 500 . - , 500 . 0.5, , .. 500 . int 0.5, 0.

:

int delay = 500;

readonly (1 )


int test_batch_operations()
{
  ....
  char *condition = "MEDIA_PATH LIKE \'";
  strncat(condition,
          tzplatform_mkpath(TZ_USER_CONTENT, "test/image%%jpg\'"),
          17);
  ....
}

PVS-Studio: V675 Calling the 'strncat' function will cause the writing into the read-only memory. Inspect the first argument. media-content_test.c 2952

Software weaknesses type — , .

, . , .

condition , . . access violation.

do… while (2 )


enum nss_status _nss_securitymanager_initgroups_dyn(....)
{
  ....
  do {
    ret = TEMP_FAILURE_RETRY(getpwnam_r(....));
    if (ret == ERANGE && buffer.size() < MEMORY_LIMIT) {
      buffer.resize(buffer.size() << 1);
      continue;                                          // <=
    }
  } while (0);
  ....
}

PVS-Studio: V696 The 'continue' operator will terminate 'do {… } while (FALSE)' loop because the condition is always false. Check lines: 73, 75. nss_securitymanager.cpp 73

Software weaknesses type — CWE-670: Always-Incorrect Control Flow Implementation

, continue do {… } while(0) , . continue , . , continue .

, :

while (true) {
  ret = TEMP_FAILURE_RETRY(getpwnam_r(....));
  if (ret != ERANGE || buffer.size() >= MEMORY_LIMIT) {
    break;
  buffer.resize(buffer.size() << 1);
};

: V696 The 'continue' operator will terminate 'do {… } while (FALSE)' loop because the condition is always false. Check lines: 120, 122. nss_securitymanager.cpp 120

realloc (11 )


V701, :

P = (T *)realloc(P, n);

, , P NULL. , , - P . , V701 . , 11, . , , , .

.

static int _preference_get_key_filesys(
  keynode_t *keynode, int* io_errno)
{
  ....
  char *value = NULL;
  ....
  case PREFERENCE_TYPE_STRING:
    while (fgets(file_buf, sizeof(file_buf), fp)) {
      if (value) {
        value_size = value_size + strlen(file_buf);
        value = (char *) realloc(value, value_size);      // <=
        if (value == NULL) {
          func_ret = PREFERENCE_ERROR_OUT_OF_MEMORY;
          break;
        }
        strncat(value, file_buf, strlen(file_buf));
      } else {
        ....
      }
    }
                ....
    if (value)
      free(value);
    break;
  
  ....
}

PVS-Studio: V701 realloc() possible leak: when realloc() fails in allocating memory, original pointer 'value' is lost. Consider assigning realloc() to a temporary pointer. preference.c 951

Software weaknesses type — CWE-401: Improper Release of Memory Before Removing Last Reference ('Memory Leak')

. realloc. , realloc - NULL, .

:


(1 )


#define BUFFER_SIZE 128
int main(int argc, char *argv[])
{
  ....
  char temp[BUFFER_SIZE] = {0,};
  ....
  snprintf(temp, BUFFER_SIZE, "%s%s-%d%s",
           argv[2], temp_filename, i, file_format);
  ....
}

PVS-Studio: V755 A copy from unsafe data source to a buffer of fixed size. Buffer overflow is possible. image_util_decode_encode_testsuite.c 237

Software weaknesses type — CWE-121: Stack-based Buffer Overflow

argv[2] , . temp .

(3 )


. , .

char *generate_role_trait(AtspiAccessible * obj) {
  ....
  return strdup(ret);
}
char *generate_description_trait(AtspiAccessible * obj) {
  ....
  return strdup(ret);
}
char *generate_state_trait(AtspiAccessible * obj) {
  ....
  return strdup(ret);
}

, 3 .

static char *generate_description_from_relation_object(....)
{
  ....
  char *role_name = generate_role_trait(obj);
  char *description_from_role = generate_description_trait(obj);
  char *state_from_role = generate_state_trait(obj);
  ....
  char *desc = atspi_accessible_get_description(obj, &err);

  if (err)
  {
    g_error_free(err);
    g_free(desc);
    return strdup(trait);
  }
  ....  
}

PVS-Studio:


Software weaknesses type — CWE-401 Improper Release of Memory Before Removing Last Reference ('Memory Leak')

atspi_accessible_get_description , generate_description_from_relation_object . , desc. role_name, description_from_role state_from_role , 3 .

(1 )


BookmarkManagerUI::~BookmarkManagerUI()
{
  BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__);
  if (m_modulesToolbar) {
    evas_object_smart_callback_del(m_modulesToolbar,
      "language,changed", _modules_toolbar_language_changed);
    evas_object_del(m_modulesToolbar);
  }
  if (m_navigatorToolbar) {
    evas_object_smart_callback_del(m_navigatorToolbar,
      "language,changed", _navigation_toolbar_language_changed);
    evas_object_del(m_modulesToolbar);                    // <=
  }
  ....
}

PVS-Studio: V778 Two similar code fragments were found. Perhaps, this is a typo and 'm_navigatorToolbar' variable should be used instead of 'm_modulesToolbar'. BookmarkManagerUI.cpp 66

Software weaknesses type — CWE-675: Duplicate Operations on Resource

Copy-Paste. m_modulesToolbar m_navigatorToolbar.

(8 )


, , , . :

void Integrity::syncElement(....) {
  ....
  if (ret < 0) {
    int err = errno;
    LOGE("'close' function error [%d] : <%s>",err,strerror(err));
    throw UnexpectedErrorException(err, strerror(err));
  }
}

, :

void Integrity::createHardLink(....) {
  int ret = link(oldName.c_str(), newName.c_str());

  if (ret < 0) {
    int err = errno;
    throw UnexpectedErrorException(err, strerror(err));
    LOGN("Trying to link to non-existent...", oldName.c_str());
  }
}

PVS-Studio: V779 Unreachable code detected. It is possible that an error is present. Integrity.cpp 233

Software weaknesses type — CWE-561: Dead Code

, , , .

.

#define LS_FUNC_ENTER LS_LOGD("(%s) ENTER", __FUNCTION__);
#define LS_FUNC_EXIT LS_LOGD("(%s) EXIT", __FUNCTION__);
static bool __check_myplace_automation(void)
{
  LS_FUNC_ENTER
  bool myplace_automation_supported = false;
  bool myplace_automation_consent = false;
  ....
  return false;
  LS_FUNC_EXIT
}

PVS-Studio: V779 Unreachable code detected. It is possible that an error is present. myplace-suggest.c 68

Software weaknesses type — CWE-561: Dead Code

- . .

:


(2 )


.
struct _VoiceData {
  int voicefw_state;
  ....
  std::vector<std::string> stt_results;
  ....
  is::ui::MicEffector *effector;
};
typedef struct _VoiceData VoiceData;

, VoiceData . , .

void show_voice_input(....)
{
  ....
  my_voicedata = (VoiceData*)malloc(sizeof(VoiceData));
  if (my_voicedata == NULL) {
    LOGD("%d::::Heap Overflow, ......!", __LINE__);
    return;
  }
  memset(my_voicedata, 0, sizeof(VoiceData));
  ....
}

void on_destroy(VoiceData *r_voicedata)
{
  ....
  VoiceData *voicedata = (VoiceData *)r_voicedata;
  ....
  free(voicedata);
}

PVS-Studio: V780 The object 'my_voicedata' of a non-passive (non-PDS) type cannot be initialized using the memset function. ise-stt-mode.cpp 773

Software weaknesses type — CWE-762 Mismatched Memory Management Routines

, malloc memset, free. :


, , , . undefined behavior. .

ise-default-1.3.34. org.tizen.inputdelegator-0.1.170518. ( ): V780 The object 'my_voicedata' of a non-passive (non-PDS) type cannot be initialized using the memset function. w-input-stt-ise.cpp 51

(73 )


73 , . , , , , . , , . .


Tizen_other_things.txt.


344 . 345. , , , , . , , .

1036000 , 19.9% . , « » ( ): 830000.

, 0.41 1000 .

? . , Tizen, Samsung. , . , , .

Carnegie-Mellon 1000 5 15 . , 2011 Linux « » . , Linux 1000 1 . , , , .

Tizen Linux, . 1000 Tizen? 1 5. , 1000 3 .

, PVS-Studio 10% . , , . , PVS-Studio 20% .

, , Samsung. . , , /.

/.  .


, Tizen


, , Samsung. , : alsa-lib-1.0.28, aspell-0.60.6.1, augeas-1.3.0, bind-9.11.0, efl-1.16.0, enlightenment-0.20.0, ise-engine-anthy-1.0.9.

, . , , , , .

, , , . , .

: (4 )


static void _edje_generate_source_state_map(....)
{
  for (i = 0; i < pd->map.colors_count; ++i)
  {
    if ((pd->map.colors[i]->r != 255) ||
        (pd->map.colors[i]->g != 255) ||
        (pd->map.colors[i]->b != 255) ||
        (pd->map.colors[i]->b != 255))
    .....
}

PVS-Studio: V501 There are identical sub-expressions '(pd->map.colors[i]->b != 255)' to the left and to the right of the '||' operator. edje_edit.c 14052

Software weaknesses type — CWE-570: Expression is Always False

-. , PVS-Studio .

:


() ( 269)


. , , malloc, strdup .. , .

, , .

static isc_result_t
setup_style(dns_master_style_t **stylep) {
  isc_result_t result;
  dns_master_style_t *style = NULL;

  REQUIRE(stylep != NULL || *stylep == NULL);
  ....
}

PVS-Studio: V522 Dereferencing of the null pointer 'stylep' might take place. Check the logical condition. delv.c 500

Software weaknesses type — CWE-476: NULL Pointer Dereference

: , . :

REQUIRE(stylep != NULL && *stylep != NULL);

, . V522 V575 , . .

, 268 , Tizen_third_party_V522_V575.txt.

(3 )


, , Tizen , .

static Eina_Bool
_ipc_server_data(void *data, int type EINA_UNUSED, void *event)
{
  ....
  //TIZEN_ONLY(170317): add skipping indicator buffer logic
  if (indicator_buffer_skip)
    return;
  //END
  ....
}

PVS-Studio: V591 Non-void function should return a value. ecore_evas_extn.c 1526

Software weaknesses type — CWE-393: Return of Wrong Status Code

( ) Eina_Bool.

:


(5 )


static char *readline_path_generator(const char *text, int state) {
  ....
  if (ctx != NULL) {
    char *c = realloc(child, strlen(child)-strlen(ctx)+1);  // <=
    if (c == NULL)
      return NULL;
    int ctxidx = strlen(ctx);
    if (child[ctxidx] == SEP)                               // <=
      ctxidx++;
    strcpy(c, &child[ctxidx]);                              // <=
    child = c;
  }
  ....
}

:


Software weaknesses type — CWE-416: Use after free

, .

realloc child .

, ? , , . . , .

:


(1 )


void Config::del()
{
  while (first_) {
    Entry * tmp = first_->next;
    delete first_;
    first_ = tmp;
  }

  while (others_) {
    Entry * tmp = others_->next;
    delete first_;
    others_ = tmp;
  }
  .....
}

PVS-Studio: V778 Two similar code fragments were found. Perhaps, this is a typo and 'others_' variable should be used instead of 'first_'. config.cpp 185

Software weaknesses type — CWE-401: Improper Release of Memory Before Removing Last Reference ('Memory Leak')

Copy-Paste. , .

first_ nullptr. , , .

true/false (9 )


StyleLineType StyleLine::get_type (void)
{
  ....
  unsigned int spos, epos;
  ....
  for (epos = m_line.length () - 1;
       epos >= 0 && isspace (m_line[epos]);
       epos--);
  ....
}

PVS-Studio: V547 Expression 'epos >= 0' is always true. Unsigned type value is always >= 0. scim_anthy_style_file.cpp 103

Software weaknesses type — CWE-571 Expression is Always True

, . , epos . , epos >= 0 .

- , m_line . , epos UINT_MAX , , (m_line[epos]) .

:


(52 )


. , Samsung, , . , , , , - - .

, .

void
isc_hmacsha1_sign(isc_hmacsha1_t *ctx,
                  unsigned char *digest, size_t len) {
  unsigned char opad[ISC_SHA1_BLOCK_LENGTH];
  unsigned char newdigest[ISC_SHA1_DIGESTLENGTH];
  ....
  memset(newdigest, 0, sizeof(newdigest));
}

PVS-Studio: V597 The compiler could delete the 'memset' function call, which is used to flush 'newdigest' buffer. The memset_s() function should be used to erase the private data. hmacsha.c 1140

Software weaknesses type — CWE-14: Compiler Removal of Code to Clear Buffers

, newdigest .

. , , .

static void
_e_icon_smart_del(Evas_Object *obj)
{
  E_Smart_Data *sd;

  if (!(sd = evas_object_smart_data_get(obj))) return;
  evas_object_del(sd->obj);
  evas_object_del(sd->eventarea);
  ....
  evas_object_smart_data_set(obj, NULL);
  memset(sd, 0, sizeof(*sd));                          // <=
  free(sd);
}

PVS-Studio: V597 The compiler could delete the 'memset' function call, which is used to flush 'sd' object. The memset_s() function should be used to erase the private data. e_icon.c 838

Software weaknesses type — CWE-14: Compiler Removal of Code to Clear Buffers

sd , free. , memset.

50 , , Tizen_third_party_V597.txt.

(227 )


, , , , . . , - , .

:


Tizen_third_party_other_things.txt.


570 . 564, - . 1915000 . — 17,6%.

PVS-Studio 0,36 1000 . , - , Tizen ( 0.41 1000 ).

?


. , .


! !

, , , , , . , 900 , 900 , , . ? . :)

, , . , , .


:
V501There are identical sub-expressions to the left and to the right of the 'foo' operator.6
V502Perhaps the '?:' operator works in a different way than it was expected. The '?:' operator has a lower priority than the 'foo' operator.1
V503This is a nonsensical comparison: pointer < 0.2
V505The 'alloca' function is used inside the loop. This can quickly overflow stack.26
V507Pointer to local array 'X' is stored outside the scope of this array. Such a pointer will become invalid.1
V512A call of the 'Foo' function will lead to a buffer overflow or underflow.7
V517The use of 'if (A) {...} else if (A) {...}' pattern was detected. There is a probability of logical error presence.8
V519The 'x' variable is assigned values twice successively. Perhaps this is a mistake.14
V522Dereferencing of the null pointer might take place.276
V523The 'then' statement is equivalent to the 'else' statement.8
V524It is odd that the body of 'Foo_1' function is fully equivalent to the body of 'Foo_2' function.1
V527It is odd that the 'zero' value is assigned to pointer. Probably meant: *ptr = zero.1
V528It is odd that pointer is compared with the 'zero' value. Probably meant: *ptr != zero.1
V535The variable 'X' is being used for this loop and for the outer loop.4
V547Expression is always true/false.18
V556The values of different enum types are compared.24
V560A part of conditional expression is always true/false.2
V571Recurring check. This condition was already verified in previous line.2
V572It is odd that the object which was created using 'new' operator is immediately cast to another type.4
V575Function receives an odd argument.83
V576Incorrect format. Consider checking the N actual argument of the 'Foo' function.5
V590Consider inspecting this expression. The expression is excessive or contains a misprint.3
V591Non-void function should return a value.3
V593Consider reviewing the expression of the 'A = B == C' kind. The expression is calculated as following: 'A = (B == C)'.1
V595The pointer was utilized before it was verified against nullptr. Check lines: N1, N2.28
V597The compiler could delete the 'memset' function call, which is used to flush 'Foo' buffer. The RtlSecureZeroMemory() function should be used to erase the private data.53
V601An odd implicit type casting.1
V609Divide or mod by zero.1
V610Undefined behavior. Check the shift operator.2
V611The memory allocation and deallocation methods are incompatible.2
V614Uninitialized variable 'Foo' used.1
V618It's dangerous to call the 'Foo' function in such a manner, as the line being passed could contain format specification. The example of the safe code: printf("%s", str);6
V622Consider inspecting the 'switch' statement. It's possible that the first 'case' operator is missing.1
V624The constant NN is being utilized. The resulting value could be inaccurate. Consider using the M_NN constant from <math.h>.2
V636The expression was implicitly cast from integer type to real type. Consider utilizing an explicit type cast to avoid overflow or loss of a fractional part.12
V640The code's operational logic does not correspond with its formatting.3
V642Saving the function result inside the 'byte' type variable is inappropriate. The significant bits could be lost breaking the program's logic.1
V645The function call could lead to the buffer overflow. The bounds should not contain the size of the buffer, but a number of characters it can hold.6
V646Consider inspecting the application's logic. It's possible that 'else' keyword is missing.4
V647The value of 'A' type is assigned to the pointer of 'B' type.1
V649There are two 'if' statements with identical conditional expressions. The first 'if' statement contains function return. This means that the second 'if' statement is senseless.1
V666Consider inspecting NN argument of the function 'Foo'. It is possible that the value does not correspond with the length of a string which was passed with the YY argument.6
V668There is no sense in testing the pointer against null, as the memory was allocated using the 'new' operator. The exception will be generated in the case of memory allocation error.63
V674The expression contains a suspicious mix of integer and real types.1
V675Writing into the read-only memory.1
V686A pattern was detected: A || (A && ...). The expression is excessive or contains a logical error.2
V690The class implements a copy constructor/operator=, but lacks the operator=/copy constructor.8
V692An inappropriate attempt to append a null character to a string. To determine the length of a string by 'strlen' function correctly, a string ending with a null terminator should be used in the first place.2
V694The condition (ptr — const_value) is only false if the value of a pointer equals a magic constant.2
V696The 'continue' operator will terminate 'do {… } while (FALSE)' loop because the condition is always false.2
V701realloc() possible leak: when realloc() fails in allocating memory, original pointer is lost. Consider assigning realloc() to a temporary pointer.113
V746Type slicing. An exception should be caught by reference rather than by value.32
V755Copying from unsafe data source. Buffer overflow is possible.1
V759Violated order of exception handlers. Exception caught by handler for base class.9
V760Two identical text blocks detected. The second block starts with NN string.1
V762Consider inspecting virtual function arguments. See NN argument of function 'Foo' in derived class and base class.6
V769The pointer in the expression equals nullptr. The resulting value is meaningless and should not be used.8
V773The function was exited without releasing the pointer/handle. A memory/resource leak is possible.6
V774The pointer was used after the memory was released.5
V778Two similar code fragments were found. Perhaps, this is a typo and 'X' variable should be used instead of 'Y'.2
V779Unreachable code detected. It is possible that an error is present.16
V780The object of non-passive (non-PDS) type cannot be used with the function.2
V783Dereferencing of invalid iterator 'X' might take place.4
V786Assigning the value C to the X variable looks suspicious. The value range of the variable: [A, B].1
1. , .

914 . 900 .


. , , . . - . , , .

, . , .

, . , , , Tizen.

27 000


, , 27000 .

2 400 000 ( ).

900 .

Tizen 72 500 000 C C++ ( ).

, 3.3% .

:
(72500000*900/2400000=27187)

PVS-Studio, 27 000 .

, .


, PVS-Studio . , , , PVS-Studio 27000 . , .

, , Tizen. , .

PVS-Studio.

:


. , @Code_Analysis. , .



, : Andrey Karpov. 27 000 errors in the Tizen operating system

Source: https://habr.com/ru/post/332912/


All Articles