9 Star 56 Fork 60

OpenHarmony / third_party_bounds_checking_function

 / 详情

Possible memory leak in SecGetCharFromFile

Backlog
Task
Opened this issue  
2020-12-29 18:22

Using gcc 10 static analysis function reports memory leak in SecGetCharFromFile.
You can learn more about gcc static analysis at https://developers.redhat.com/blog/2020/03/26/static-analysis-in-gcc-10/

To reproduce please run:

gcc-10 -fanalyzer -iquote include -iquote src -MMD -c -o src/libsec.a-secureinput_w.o 

Diagnostic message produced:

In file included from src/secureinput_w.c:46:
src/input.inl: In function ‘SecGetCharFromFile’:
src/input.inl:2120:23: warning: leak of ‘<unknown>’ [CWE-401] [-Wanalyzer-malloc-leak]
 2120 |             if (stream->base == NULL) {
      |                 ~~~~~~^~~~~~
  ‘SecInputSW’: events 1-3
    |
    | 1785 | int SecInputSW(SecFileStream *stream, const wchar_t *cFormat, va_list argList)
    |      |     ^~~~~~~~~~
    |      |     |
    |      |     (1) entry to ‘SecInputSW’
    |......
    | 1809 |     while (errRet < 1 && *format != SECUREC_CHAR('\0')) {
    |      |           ~              ~~~~~~~
    |      |           |              |
    |      |           |              (3) ...to here
    |      |           (2) following ‘true’ branch (when ‘errRet <= 0’)...
    |
  ‘SecInputSW’: events 4-8
    |
    | 1809 |     while (errRet < 1 && *format != SECUREC_CHAR('\0')) {
    | 1810 |         /* Skip space in format and space in input */
    | 1811 |         if (SecIsSpace((SecInt)(int)(*format)) != 0) {
    |      |                                     ~~~~~~~~~
    |      |                                      |
    |      |                                      (5) ...to here
    |......
    | 1821 |         if (*format != SECUREC_CHAR('%')) {
    |      |            ~
    |      |            |
    |      |            (6) following ‘true’ branch...
    | 1822 |             spec.ch = SecGetChar(stream, &(spec.charCount));
    |      |                       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    |      |                       |
    |      |                       (7) ...to here
    |      |                       (8) calling ‘SecGetChar’ from ‘SecInputSW’
    |
    +--> ‘SecGetChar’: events 9-14
           |
           | 2152 | SECUREC_INLINE SecInt SecGetChar(SecFileStream *stream, int *counter)
           |      |                       ^~~~~~~~~~
           |      |                       |
           |      |                       (9) entry to ‘SecGetChar’
           |......
           | 2156 |     if ((stream->flag & SECUREC_MEM_STR_FLAG) != 0) {
           |      |        ~
           |      |        |
           |      |        (10) following ‘false’ branch...
           |......
           | 2162 |     if ((stream->flag & SECUREC_FILE_STREAM_FLAG) != 0) {
           |      |        ~ ~~~~~~~~~~~~
           |      |        |       |
           |      |        |       (11) ...to here
           |      |        (12) following ‘true’ branch...
           | 2163 |         return SecGetCharFromFile(stream);
           |      |                ~~~~~~~~~~~~~~~~~~~~~~~~~~
           |      |                |
           |      |                (13) ...to here
           |      |                (14) calling ‘SecGetCharFromFile’ from ‘SecGetChar’
           |
           +--> ‘SecGetCharFromFile’: events 15-20
                  |
                  | 2099 | SECUREC_INLINE SecInt SecGetCharFromFile(SecFileStream *stream)
                  |      |                       ^~~~~~~~~~~~~~~~~~
                  |      |                       |
                  |      |                       (15) entry to ‘SecGetCharFromFile’
                  |......
                  | 2102 |     if (stream->count < sizeof(SecChar)) {
                  |      |        ~
                  |      |        |
                  |      |        (16) following ‘true’ branch...
                  |......
                  | 2105 |         if (stream->base != NULL) {
                  |      |            ~~~~~~~~~~~~~
                  |      |            |      |
                  |      |            |      (17) ...to here
                  |      |            (18) following ‘false’ branch...
                  |......
                  | 2111 |             stream->oriFilePos = ftell(stream->pf);   /* Save original file read position */
                  |      |                                  ~~~~~~~~~~~~~~~~~
                  |      |                                  |
                  |      |                                  (19) ...to here
                  | 2112 |             if (stream->oriFilePos == -1) {
                  |      |                ~
                  |      |                |
                  |      |                (20) following ‘false’ branch...
                  |
                ‘SecGetCharFromFile’: event 21
                  |
                  |src/securecutil.h:304:27:
                  |  304 | #define SECUREC_MALLOC(x) malloc((size_t)(x))
                  |      |                           ^~~~~~~~~~~~~~~~~~~
                  |      |                           |
                  |      |                           (21) ...to here
src/input.inl:2118:36: note: in expansion of macro ‘SECUREC_MALLOC’
                  | 2118 |             stream->base = (char *)SECUREC_MALLOC(SECUREC_BUFFERED_BLOK_SIZE +
                  |      |                                    ^~~~~~~~~~~~~~
                  |
                ‘SecGetCharFromFile’: event 22
                  |
                  |src/securecutil.h:304:27:
                  |  304 | #define SECUREC_MALLOC(x) malloc((size_t)(x))
                  |      |                           ^~~~~~~~~~~~~~~~~~~
                  |      |                           |
                  |      |                           (22) allocated here
src/input.inl:2118:36: note: in expansion of macro ‘SECUREC_MALLOC’
                  | 2118 |             stream->base = (char *)SECUREC_MALLOC(SECUREC_BUFFERED_BLOK_SIZE +
                  |      |                                    ^~~~~~~~~~~~~~
                  |
                ‘SecGetCharFromFile’: events 23-28
                  |
                  | 2120 |             if (stream->base == NULL) {
                  |      |                ^~~~~~~~~~~~~
                  |      |                |      |
                  |      |                |      (28) ‘<unknown>’ leaks here; was allocated at (22)
                  |      |                (23) assuming ‘<unknown>’ is non-NULL
                  |      |                (24) following ‘false’ branch...
                  |......
                  | 2124 |             if (stream->oriFilePos == 0) {
                  |      |                ~~~~~~~~~~~~~~~~~~~
                  |      |                |      |
                  |      |                |      (25) ...to here
                  |      |                (26) following ‘false’ branch...
                  |......
                  | 2131 |         len = fread(stream->base + stream->count, (size_t)1, (size_t)SECUREC_BUFFERED_BLOK_SIZE, stream->pf);
                  |      |               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                  |      |               |
                  |      |               (27) ...to here
                  |
src/input.inl:2124:23: warning: leak of ‘<unknown>’ [CWE-401] [-Wanalyzer-malloc-leak]
 2124 |             if (stream->oriFilePos == 0) {
      |                 ~~~~~~^~~~~~~~~~~~
  ‘SecInputSW’: events 1-3
    |
    | 1785 | int SecInputSW(SecFileStream *stream, const wchar_t *cFormat, va_list argList)
    |      |     ^~~~~~~~~~
    |      |     |
    |      |     (1) entry to ‘SecInputSW’
    |......
    | 1809 |     while (errRet < 1 && *format != SECUREC_CHAR('\0')) {
    |      |           ~              ~~~~~~~
    |      |           |              |
    |      |           |              (3) ...to here
    |      |           (2) following ‘true’ branch (when ‘errRet <= 0’)...
    |
  ‘SecInputSW’: events 4-8
    |
    | 1809 |     while (errRet < 1 && *format != SECUREC_CHAR('\0')) {
    | 1810 |         /* Skip space in format and space in input */
    | 1811 |         if (SecIsSpace((SecInt)(int)(*format)) != 0) {
    |      |                                     ~~~~~~~~~
    |      |                                      |
    |      |                                      (5) ...to here
    |......
    | 1821 |         if (*format != SECUREC_CHAR('%')) {
    |      |            ~
    |      |            |
    |      |            (6) following ‘true’ branch...
    | 1822 |             spec.ch = SecGetChar(stream, &(spec.charCount));
    |      |                       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    |      |                       |
    |      |                       (7) ...to here
    |      |                       (8) calling ‘SecGetChar’ from ‘SecInputSW’
    |
    +--> ‘SecGetChar’: events 9-14
           |
           | 2152 | SECUREC_INLINE SecInt SecGetChar(SecFileStream *stream, int *counter)
           |      |                       ^~~~~~~~~~
           |      |                       |
           |      |                       (9) entry to ‘SecGetChar’
           |......
           | 2156 |     if ((stream->flag & SECUREC_MEM_STR_FLAG) != 0) {
           |      |        ~
           |      |        |
           |      |        (10) following ‘false’ branch...
           |......
           | 2162 |     if ((stream->flag & SECUREC_FILE_STREAM_FLAG) != 0) {
           |      |        ~ ~~~~~~~~~~~~
           |      |        |       |
           |      |        |       (11) ...to here
           |      |        (12) following ‘true’ branch...
           | 2163 |         return SecGetCharFromFile(stream);
           |      |                ~~~~~~~~~~~~~~~~~~~~~~~~~~
           |      |                |
           |      |                (13) ...to here
           |      |                (14) calling ‘SecGetCharFromFile’ from ‘SecGetChar’
           |
           +--> ‘SecGetCharFromFile’: events 15-20
                  |
                  | 2099 | SECUREC_INLINE SecInt SecGetCharFromFile(SecFileStream *stream)
                  |      |                       ^~~~~~~~~~~~~~~~~~
                  |      |                       |
                  |      |                       (15) entry to ‘SecGetCharFromFile’
                  |......
                  | 2102 |     if (stream->count < sizeof(SecChar)) {
                  |      |        ~
                  |      |        |
                  |      |        (16) following ‘true’ branch...
                  |......
                  | 2105 |         if (stream->base != NULL) {
                  |      |            ~~~~~~~~~~~~~
                  |      |            |      |
                  |      |            |      (17) ...to here
                  |      |            (18) following ‘false’ branch...
                  |......
                  | 2111 |             stream->oriFilePos = ftell(stream->pf);   /* Save original file read position */
                  |      |                                  ~~~~~~~~~~~~~~~~~
                  |      |                                  |
                  |      |                                  (19) ...to here
                  | 2112 |             if (stream->oriFilePos == -1) {
                  |      |                ~
                  |      |                |
                  |      |                (20) following ‘false’ branch...
                  |
                ‘SecGetCharFromFile’: event 21
                  |
                  |src/securecutil.h:304:27:
                  |  304 | #define SECUREC_MALLOC(x) malloc((size_t)(x))
                  |      |                           ^~~~~~~~~~~~~~~~~~~
                  |      |                           |
                  |      |                           (21) ...to here
src/input.inl:2118:36: note: in expansion of macro ‘SECUREC_MALLOC’
                  | 2118 |             stream->base = (char *)SECUREC_MALLOC(SECUREC_BUFFERED_BLOK_SIZE +
                  |      |                                    ^~~~~~~~~~~~~~
                  |
                ‘SecGetCharFromFile’: event 22
                  |
                  |src/securecutil.h:304:27:
                  |  304 | #define SECUREC_MALLOC(x) malloc((size_t)(x))
                  |      |                           ^~~~~~~~~~~~~~~~~~~
                  |      |                           |
                  |      |                           (22) allocated here
src/input.inl:2118:36: note: in expansion of macro ‘SECUREC_MALLOC’
                  | 2118 |             stream->base = (char *)SECUREC_MALLOC(SECUREC_BUFFERED_BLOK_SIZE +
                  |      |                                    ^~~~~~~~~~~~~~
                  |
                ‘SecGetCharFromFile’: events 23-29
                  |
                  | 2120 |             if (stream->base == NULL) {
                  |      |                ~~~~~~~^~~~~~
                  |      |                |      |
                  |      |                |      (23) allocated here
                  |      |                (24) assuming ‘<unknown>’ is non-NULL
                  |      |                (25) following ‘false’ branch...
                  |......
                  | 2124 |             if (stream->oriFilePos == 0) {
                  |      |                ~~~~~~~~~~~~~~~~~~~
                  |      |                |      |
                  |      |                |      (26) ...to here
                  |      |                |      (29) ‘<unknown>’ leaks here; was allocated at (23)
                  |      |                (27) following ‘false’ branch...
                  |......
                  | 2131 |         len = fread(stream->base + stream->count, (size_t)1, (size_t)SECUREC_BUFFERED_BLOK_SIZE, stream->pf);
                  |      |               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                  |      |               |
                  |      |               (28) ...to here
                  |

Comments (1)

Zygmunt Krynicki created任务
Expand operation logs

这个函数入口是SecInputS,在这个函数执行的最后阶段,会调用SecAdjustStream(stream);这个接口,在这个接口中会进行释放。

输入图片说明

Sign in to comment

Status
Assignees
Projects
Milestones
Pull Requests
Successfully merging a pull request will close this issue.
Branches
Planed to start   -   Planed to end
-
Top level
Priority
Duration (hours)
Confirm
参与者(2)
1
https://git.oschina.net/openharmony/third_party_bounds_checking_function.git
git@git.oschina.net:openharmony/third_party_bounds_checking_function.git
openharmony
third_party_bounds_checking_function
third_party_bounds_checking_function

Search