Prevent buffer overflow on reading value
[platform/core/api/system-info.git] / src / system_info_external.c
1 /*
2  * system-info
3  *
4  * Copyright (c) 2015 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  */
19
20 #include "system_info_private.h"
21 #include "system_info_type.h"
22 #include "system_info_intf.h"
23 #include <string.h>
24 #include <unistd.h>
25 #include <dlfcn.h>
26
27 #define BUF_MAX 256
28
29 #define EXTERNAL_SYSTEM_INFO "/usr/lib/libsystem-info-external-plugin.so"
30
31
32 //LCOV_EXCL_START
33 int external_get_value(const char *tag, const char *key,
34                 const char *type, char **val)
35 {
36         void *handle = NULL;
37         int ret;
38         char buf[BUF_MAX];
39         const system_info_external_plugin_interface *plugin;
40         const system_info_external_plugin_interface *(*system_info_get_external_plugin_interface)(void);
41
42
43         if (access(EXTERNAL_SYSTEM_INFO, F_OK) != 0) {
44                 _E("No external system info library");
45                 return SYSTEM_INFO_ERROR_IO_ERROR;
46         }
47
48         handle = dlopen(EXTERNAL_SYSTEM_INFO, RTLD_NOW);
49         if (!handle) {
50                 _E("dlopen(%s) failed(%s)", EXTERNAL_SYSTEM_INFO, dlerror());
51                 ret = SYSTEM_INFO_ERROR_IO_ERROR;
52                 goto out;
53         }
54
55         system_info_get_external_plugin_interface = dlsym(handle, "system_info_get_external_plugin_interface");
56         if (!system_info_get_external_plugin_interface) {
57                 _E("dlsym failed(%s)", dlerror());
58                 ret = SYSTEM_INFO_ERROR_IO_ERROR;
59                 goto out;
60         }
61
62         plugin = system_info_get_external_plugin_interface();
63         if (!plugin) {
64                 _E("Failed to get plugin");
65                 ret = SYSTEM_INFO_ERROR_IO_ERROR;
66                 goto out;
67         }
68
69         if (plugin->get_value_external == NULL) {
70                 _E("Invalid plugin function");
71                 ret = SYSTEM_INFO_ERROR_IO_ERROR;
72                 goto out;
73         }
74
75         ret = plugin->get_value_external(tag, key, type, buf, sizeof(buf));
76         if (ret < 0) {
77                 _E("Failed to get value from plugin (ret:%d)", ret);
78                 ret = SYSTEM_INFO_ERROR_IO_ERROR;
79                 goto out;
80         }
81
82         *val = strdup(buf);
83         if (*val == NULL) {
84                 _E("strdup() failed");
85                 ret = SYSTEM_INFO_ERROR_OUT_OF_MEMORY;
86                 goto out;
87         }
88
89         ret = SYSTEM_INFO_ERROR_NONE;
90
91 out:
92         if (handle)
93                 dlclose(handle);
94
95         return ret;
96 }
97
98 int external_get_type(const char *tag, const char *key, char **type)
99 {
100         void *handle = NULL;
101         int ret;
102         char buf[BUF_MAX];
103         const system_info_external_plugin_interface *plugin;
104         const system_info_external_plugin_interface *(*system_info_get_external_plugin_interface)(void);
105
106
107         if (access(EXTERNAL_SYSTEM_INFO, F_OK) != 0) {
108                 _E("No external system info library");
109                 return SYSTEM_INFO_ERROR_IO_ERROR;
110         }
111
112         handle = dlopen(EXTERNAL_SYSTEM_INFO, RTLD_NOW);
113         if (!handle) {
114                 _E("dlopen(%s) failed(%s)", EXTERNAL_SYSTEM_INFO, dlerror());
115                 ret = SYSTEM_INFO_ERROR_IO_ERROR;
116                 goto out;
117         }
118
119         system_info_get_external_plugin_interface = dlsym(handle, "system_info_get_external_plugin_interface");
120         if (!system_info_get_external_plugin_interface) {
121                 _E("dlsym failed(%s)", dlerror());
122                 ret = SYSTEM_INFO_ERROR_IO_ERROR;
123                 goto out;
124         }
125
126         plugin = system_info_get_external_plugin_interface();
127         if (!plugin) {
128                 _E("Failed to get plugin");
129                 ret = SYSTEM_INFO_ERROR_IO_ERROR;
130                 goto out;
131         }
132
133         if (plugin->get_type_external == NULL) {
134                 _E("Invalid plugin function");
135                 ret = SYSTEM_INFO_ERROR_IO_ERROR;
136                 goto out;
137         }
138
139         ret = plugin->get_type_external(tag, key, buf, sizeof(buf));
140         if (ret < 0) {
141                 _E("Failed to get value from plugin (ret:%d)", ret);
142                 ret = SYSTEM_INFO_ERROR_IO_ERROR;
143                 goto out;
144         }
145
146         *type = strdup(buf);
147         if (*type == NULL) {
148                 _E("strdup() failed");
149                 ret = SYSTEM_INFO_ERROR_OUT_OF_MEMORY;
150                 goto out;
151         }
152
153         ret = SYSTEM_INFO_ERROR_NONE;
154
155 out:
156         if (handle)
157                 dlclose(handle);
158
159         return ret;
160 }
161 //LCOV_EXCL_STOP