diff --git a/plugins/tensorboard-plugins/tb_graph_ascend/monvis_plugin/fe/src/graph/components/HeatMap/useHeatMap.ts b/plugins/tensorboard-plugins/tb_graph_ascend/monvis_plugin/fe/src/graph/components/HeatMap/useHeatMap.ts index eccbc1daf7e34af3376028aee19700365859aaf2..f1a7b6d2ecedddd79fde13fa95bb2c810724fe23 100644 --- a/plugins/tensorboard-plugins/tb_graph_ascend/monvis_plugin/fe/src/graph/components/HeatMap/useHeatMap.ts +++ b/plugins/tensorboard-plugins/tb_graph_ascend/monvis_plugin/fe/src/graph/components/HeatMap/useHeatMap.ts @@ -184,10 +184,10 @@ const useHeatMap = () => { }, grid: { - height: '80%', - width: '90%', - left: '5%', - top: '12%' + left: 120, + right: 30, + top: 100, + bottom: 70 }, xAxis: { @@ -246,7 +246,7 @@ const useHeatMap = () => { show: true, startValue: 0, endValue: 500, - bottom: 30, + bottom: 20, realtime: false, }, { diff --git a/plugins/tensorboard-plugins/tb_graph_ascend/monvis_plugin/fe/src/graph/components/LineChart/index.tsx b/plugins/tensorboard-plugins/tb_graph_ascend/monvis_plugin/fe/src/graph/components/LineChart/index.tsx index 8f38a695b91f697bd5b2cb93189d8e2a56665a11..9222e50bd38a4a70ef0cea81dbfa18d73932c987 100644 --- a/plugins/tensorboard-plugins/tb_graph_ascend/monvis_plugin/fe/src/graph/components/LineChart/index.tsx +++ b/plugins/tensorboard-plugins/tb_graph_ascend/monvis_plugin/fe/src/graph/components/LineChart/index.tsx @@ -50,7 +50,7 @@ const LineChart = () => { title: { text: `${metric} 分布图 (${heatMapXAxisName}: ${dimX || ' '} / ${heatMapYAxisName}: ${dimY || ' '}) `, left: 'center', - top: '2%', + top: 20, textStyle: { fontSize: 14, color: '#666', @@ -58,9 +58,10 @@ const LineChart = () => { }, }, grid: { - width: '90%', - top: '20%', - left: '5%', + top: 80, + bottom: 80, + left: 140, + right: 140, }, tooltip: { trigger: 'axis', diff --git a/plugins/tensorboard-plugins/tb_graph_ascend/monvis_plugin/server/database/db_connection.py b/plugins/tensorboard-plugins/tb_graph_ascend/monvis_plugin/server/database/db_connection.py index 8f27a73fd0f9fe6fb07c6e3c6ba7ba61ebd80b4a..5609271cc5c2e9d19bd76066b63273cc87f111b7 100644 --- a/plugins/tensorboard-plugins/tb_graph_ascend/monvis_plugin/server/database/db_connection.py +++ b/plugins/tensorboard-plugins/tb_graph_ascend/monvis_plugin/server/database/db_connection.py @@ -13,11 +13,20 @@ # See the License for the specific language governing permissions and # limitations under the License. # ============================================================================== - +import os +import stat import sqlite3 +import json +from pathlib import Path from tensorboard.util import tb_logging logger = tb_logging.get_logger() +FILE_PATH_MAX_LENGTH = 4096 +# 权限码 +PERM_GROUP_WRITE = 0o020 +PERM_OTHER_WRITE = 0o002 +MAX_FILE_SIZE = 3 * 1024 * 1024 * 1024 # 最大文件大小限制 + class DBConnection: @@ -25,6 +34,27 @@ class DBConnection: self.db_path = db_path self.conn = self._initialize_db_connection() + @classmethod + def _bytes_to_human_readable(cls, size_bytes, decimal_places=2): + """ + 将字节大小转换为更易读的格式(如 KB、MB、GB 等)。 + + :param size_bytes: int 或 float,表示字节大小 + :param decimal_places: 保留的小数位数,默认为 2 + :return: str,人类可读的大小表示 + """ + if size_bytes == 0: + return "0 B" + + units = ['B', 'KB', 'MB', 'GB', 'TB', 'PB'] + unit_index = 0 + + while size_bytes >= 1024 and unit_index < len(units) - 1: + size_bytes /= 1024.0 + unit_index += 1 + + return f"{size_bytes:.{decimal_places}f} {units[unit_index]}" + def is_connected(self) -> bool: """Check if database is connected.""" return self.conn is not None @@ -32,9 +62,67 @@ class DBConnection: def _initialize_db_connection(self) -> None: """Initialize database connection.""" try: + # 目录安全校验 + directory = str(os.path.dirname(self.db_path)) + success, error = self._safe_check_load_file_path(directory, True) + if not success: + raise PermissionError(error) + # 文件安全校验 + success, error = self._safe_check_load_file_path(self.db_path) + if not success: + raise PermissionError(error) conn = sqlite3.connect(self.db_path, check_same_thread=False) conn.row_factory = sqlite3.Row return conn except sqlite3.Error as e: logger.error(f"Error connecting to database: {e}") return None + + def _safe_check_load_file_path(self, file_path, is_dir=False): + # 权限常量定义 + file_path = os.path.normpath(file_path) # 标准化路径 + real_path = os.path.realpath(file_path) + st = os.stat(real_path) + try: + # 安全验证:路径长度检查 + if len(real_path) > FILE_PATH_MAX_LENGTH: + raise PermissionError(f"Path length exceeds limit") + # 安全检查:文件存在性验证 + if not os.path.exists(real_path): + raise FileNotFoundError(f"File does not exist") + # 安全验证:禁止符号链接文件 + if os.path.islink(file_path): + raise PermissionError(f"Detected symbolic link file") + # 安全验证:文件类型检查(防御TOCTOU攻击) + # 文件类型 + if not is_dir and not os.path.isfile(real_path): + raise PermissionError(f"Path is not a regular file") + # 目录类型 + if is_dir and not Path(real_path).is_dir(): + raise PermissionError(f"Directory does not exist") + # 可读性检查 + if not st.st_mode & stat.S_IRUSR: + raise PermissionError( + f"Directory lacks read permission for others, there may be a risk of data tampering.") + # 文件大小校验 + if not is_dir and os.path.getsize(file_path) > MAX_FILE_SIZE: + file_size = self._bytes_to_human_readable(os.path.getsize(file_path)) + max_size = self._bytes_to_human_readable(MAX_FILE_SIZE) + raise PermissionError( + f"File size exceeds limit ({file_size} > {max_size})") + # 非windows系统下,属主检查 + if os.name != 'nt': + current_uid = os.getuid() + # 如果是root用户,跳过后续权限检查 + if current_uid == 0: + return True, None + # 属主检查 + if st.st_uid != current_uid: + raise PermissionError(f"Directory is not owned by the current user") + # group和其他用户不可写检查 + if st.st_mode & PERM_GROUP_WRITE or st.st_mode & PERM_OTHER_WRITE: + raise PermissionError(f"Directory has group or other write permission") + return True, None + except Exception as e: + logger.error(e) + return False, e