Commit dcadaec2 authored by David S. Miller's avatar David S. Miller

Merge branch 'net-Use-scnprintf-for-avoiding-potential-buffer-overflow'

Takashi Iwai says:

====================
net: Use scnprintf() for avoiding potential buffer overflow

here is a respin of trivial patch series just to convert suspicious
snprintf() usages with the more safer one, scnprintf().

v1->v2: Align the remaining lines to the open parenthesis
        Excluded i40e patch that was already queued
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents cb851c01 2da222f6
...@@ -141,28 +141,28 @@ static ssize_t dbgfs_state(struct file *file, char __user *user_buf, ...@@ -141,28 +141,28 @@ static ssize_t dbgfs_state(struct file *file, char __user *user_buf,
return 0; return 0;
/* Print out debug information. */ /* Print out debug information. */
len += snprintf((buf + len), (DEBUGFS_BUF_SIZE - len), len += scnprintf((buf + len), (DEBUGFS_BUF_SIZE - len),
"CAIF SPI debug information:\n"); "CAIF SPI debug information:\n");
len += snprintf((buf + len), (DEBUGFS_BUF_SIZE - len), FLAVOR); len += scnprintf((buf + len), (DEBUGFS_BUF_SIZE - len), FLAVOR);
len += snprintf((buf + len), (DEBUGFS_BUF_SIZE - len), len += scnprintf((buf + len), (DEBUGFS_BUF_SIZE - len),
"STATE: %d\n", cfspi->dbg_state); "STATE: %d\n", cfspi->dbg_state);
len += snprintf((buf + len), (DEBUGFS_BUF_SIZE - len), len += scnprintf((buf + len), (DEBUGFS_BUF_SIZE - len),
"Previous CMD: 0x%x\n", cfspi->pcmd); "Previous CMD: 0x%x\n", cfspi->pcmd);
len += snprintf((buf + len), (DEBUGFS_BUF_SIZE - len), len += scnprintf((buf + len), (DEBUGFS_BUF_SIZE - len),
"Current CMD: 0x%x\n", cfspi->cmd); "Current CMD: 0x%x\n", cfspi->cmd);
len += snprintf((buf + len), (DEBUGFS_BUF_SIZE - len), len += scnprintf((buf + len), (DEBUGFS_BUF_SIZE - len),
"Previous TX len: %d\n", cfspi->tx_ppck_len); "Previous TX len: %d\n", cfspi->tx_ppck_len);
len += snprintf((buf + len), (DEBUGFS_BUF_SIZE - len), len += scnprintf((buf + len), (DEBUGFS_BUF_SIZE - len),
"Previous RX len: %d\n", cfspi->rx_ppck_len); "Previous RX len: %d\n", cfspi->rx_ppck_len);
len += snprintf((buf + len), (DEBUGFS_BUF_SIZE - len), len += scnprintf((buf + len), (DEBUGFS_BUF_SIZE - len),
"Current TX len: %d\n", cfspi->tx_cpck_len); "Current TX len: %d\n", cfspi->tx_cpck_len);
len += snprintf((buf + len), (DEBUGFS_BUF_SIZE - len), len += scnprintf((buf + len), (DEBUGFS_BUF_SIZE - len),
"Current RX len: %d\n", cfspi->rx_cpck_len); "Current RX len: %d\n", cfspi->rx_cpck_len);
len += snprintf((buf + len), (DEBUGFS_BUF_SIZE - len), len += scnprintf((buf + len), (DEBUGFS_BUF_SIZE - len),
"Next TX len: %d\n", cfspi->tx_npck_len); "Next TX len: %d\n", cfspi->tx_npck_len);
len += snprintf((buf + len), (DEBUGFS_BUF_SIZE - len), len += scnprintf((buf + len), (DEBUGFS_BUF_SIZE - len),
"Next RX len: %d\n", cfspi->rx_npck_len); "Next RX len: %d\n", cfspi->rx_npck_len);
if (len > DEBUGFS_BUF_SIZE) if (len > DEBUGFS_BUF_SIZE)
...@@ -180,23 +180,23 @@ static ssize_t print_frame(char *buf, size_t size, char *frm, ...@@ -180,23 +180,23 @@ static ssize_t print_frame(char *buf, size_t size, char *frm,
int len = 0; int len = 0;
int i; int i;
for (i = 0; i < count; i++) { for (i = 0; i < count; i++) {
len += snprintf((buf + len), (size - len), len += scnprintf((buf + len), (size - len),
"[0x" BYTE_HEX_FMT "]", "[0x" BYTE_HEX_FMT "]",
frm[i]); frm[i]);
if ((i == cut) && (count > (cut * 2))) { if ((i == cut) && (count > (cut * 2))) {
/* Fast forward. */ /* Fast forward. */
i = count - cut; i = count - cut;
len += snprintf((buf + len), (size - len), len += scnprintf((buf + len), (size - len),
"--- %zu bytes skipped ---\n", "--- %zu bytes skipped ---\n",
count - (cut * 2)); count - (cut * 2));
} }
if ((!(i % 10)) && i) { if ((!(i % 10)) && i) {
len += snprintf((buf + len), (DEBUGFS_BUF_SIZE - len), len += scnprintf((buf + len), (DEBUGFS_BUF_SIZE - len),
"\n"); "\n");
} }
} }
len += snprintf((buf + len), (DEBUGFS_BUF_SIZE - len), "\n"); len += scnprintf((buf + len), (DEBUGFS_BUF_SIZE - len), "\n");
return len; return len;
} }
...@@ -214,17 +214,17 @@ static ssize_t dbgfs_frame(struct file *file, char __user *user_buf, ...@@ -214,17 +214,17 @@ static ssize_t dbgfs_frame(struct file *file, char __user *user_buf,
return 0; return 0;
/* Print out debug information. */ /* Print out debug information. */
len += snprintf((buf + len), (DEBUGFS_BUF_SIZE - len), len += scnprintf((buf + len), (DEBUGFS_BUF_SIZE - len),
"Current frame:\n"); "Current frame:\n");
len += snprintf((buf + len), (DEBUGFS_BUF_SIZE - len), len += scnprintf((buf + len), (DEBUGFS_BUF_SIZE - len),
"Tx data (Len: %d):\n", cfspi->tx_cpck_len); "Tx data (Len: %d):\n", cfspi->tx_cpck_len);
len += print_frame((buf + len), (DEBUGFS_BUF_SIZE - len), len += print_frame((buf + len), (DEBUGFS_BUF_SIZE - len),
cfspi->xfer.va_tx[0], cfspi->xfer.va_tx[0],
(cfspi->tx_cpck_len + SPI_CMD_SZ), 100); (cfspi->tx_cpck_len + SPI_CMD_SZ), 100);
len += snprintf((buf + len), (DEBUGFS_BUF_SIZE - len), len += scnprintf((buf + len), (DEBUGFS_BUF_SIZE - len),
"Rx data (Len: %d):\n", cfspi->rx_cpck_len); "Rx data (Len: %d):\n", cfspi->rx_cpck_len);
len += print_frame((buf + len), (DEBUGFS_BUF_SIZE - len), len += print_frame((buf + len), (DEBUGFS_BUF_SIZE - len),
......
...@@ -906,32 +906,32 @@ static void mlx4_err_rule(struct mlx4_dev *dev, char *str, ...@@ -906,32 +906,32 @@ static void mlx4_err_rule(struct mlx4_dev *dev, char *str,
int len = 0; int len = 0;
mlx4_err(dev, "%s", str); mlx4_err(dev, "%s", str);
len += snprintf(buf + len, BUF_SIZE - len, len += scnprintf(buf + len, BUF_SIZE - len,
"port = %d prio = 0x%x qp = 0x%x ", "port = %d prio = 0x%x qp = 0x%x ",
rule->port, rule->priority, rule->qpn); rule->port, rule->priority, rule->qpn);
list_for_each_entry(cur, &rule->list, list) { list_for_each_entry(cur, &rule->list, list) {
switch (cur->id) { switch (cur->id) {
case MLX4_NET_TRANS_RULE_ID_ETH: case MLX4_NET_TRANS_RULE_ID_ETH:
len += snprintf(buf + len, BUF_SIZE - len, len += scnprintf(buf + len, BUF_SIZE - len,
"dmac = %pM ", &cur->eth.dst_mac); "dmac = %pM ", &cur->eth.dst_mac);
if (cur->eth.ether_type) if (cur->eth.ether_type)
len += snprintf(buf + len, BUF_SIZE - len, len += scnprintf(buf + len, BUF_SIZE - len,
"ethertype = 0x%x ", "ethertype = 0x%x ",
be16_to_cpu(cur->eth.ether_type)); be16_to_cpu(cur->eth.ether_type));
if (cur->eth.vlan_id) if (cur->eth.vlan_id)
len += snprintf(buf + len, BUF_SIZE - len, len += scnprintf(buf + len, BUF_SIZE - len,
"vlan-id = %d ", "vlan-id = %d ",
be16_to_cpu(cur->eth.vlan_id)); be16_to_cpu(cur->eth.vlan_id));
break; break;
case MLX4_NET_TRANS_RULE_ID_IPV4: case MLX4_NET_TRANS_RULE_ID_IPV4:
if (cur->ipv4.src_ip) if (cur->ipv4.src_ip)
len += snprintf(buf + len, BUF_SIZE - len, len += scnprintf(buf + len, BUF_SIZE - len,
"src-ip = %pI4 ", "src-ip = %pI4 ",
&cur->ipv4.src_ip); &cur->ipv4.src_ip);
if (cur->ipv4.dst_ip) if (cur->ipv4.dst_ip)
len += snprintf(buf + len, BUF_SIZE - len, len += scnprintf(buf + len, BUF_SIZE - len,
"dst-ip = %pI4 ", "dst-ip = %pI4 ",
&cur->ipv4.dst_ip); &cur->ipv4.dst_ip);
break; break;
...@@ -939,25 +939,25 @@ static void mlx4_err_rule(struct mlx4_dev *dev, char *str, ...@@ -939,25 +939,25 @@ static void mlx4_err_rule(struct mlx4_dev *dev, char *str,
case MLX4_NET_TRANS_RULE_ID_TCP: case MLX4_NET_TRANS_RULE_ID_TCP:
case MLX4_NET_TRANS_RULE_ID_UDP: case MLX4_NET_TRANS_RULE_ID_UDP:
if (cur->tcp_udp.src_port) if (cur->tcp_udp.src_port)
len += snprintf(buf + len, BUF_SIZE - len, len += scnprintf(buf + len, BUF_SIZE - len,
"src-port = %d ", "src-port = %d ",
be16_to_cpu(cur->tcp_udp.src_port)); be16_to_cpu(cur->tcp_udp.src_port));
if (cur->tcp_udp.dst_port) if (cur->tcp_udp.dst_port)
len += snprintf(buf + len, BUF_SIZE - len, len += scnprintf(buf + len, BUF_SIZE - len,
"dst-port = %d ", "dst-port = %d ",
be16_to_cpu(cur->tcp_udp.dst_port)); be16_to_cpu(cur->tcp_udp.dst_port));
break; break;
case MLX4_NET_TRANS_RULE_ID_IB: case MLX4_NET_TRANS_RULE_ID_IB:
len += snprintf(buf + len, BUF_SIZE - len, len += scnprintf(buf + len, BUF_SIZE - len,
"dst-gid = %pI6\n", cur->ib.dst_gid); "dst-gid = %pI6\n", cur->ib.dst_gid);
len += snprintf(buf + len, BUF_SIZE - len, len += scnprintf(buf + len, BUF_SIZE - len,
"dst-gid-mask = %pI6\n", "dst-gid-mask = %pI6\n",
cur->ib.dst_gid_msk); cur->ib.dst_gid_msk);
break; break;
case MLX4_NET_TRANS_RULE_ID_VXLAN: case MLX4_NET_TRANS_RULE_ID_VXLAN:
len += snprintf(buf + len, BUF_SIZE - len, len += scnprintf(buf + len, BUF_SIZE - len,
"VNID = %d ", be32_to_cpu(cur->vxlan.vni)); "VNID = %d ", be32_to_cpu(cur->vxlan.vni));
break; break;
case MLX4_NET_TRANS_RULE_ID_IPV6: case MLX4_NET_TRANS_RULE_ID_IPV6:
...@@ -967,7 +967,7 @@ static void mlx4_err_rule(struct mlx4_dev *dev, char *str, ...@@ -967,7 +967,7 @@ static void mlx4_err_rule(struct mlx4_dev *dev, char *str,
break; break;
} }
} }
len += snprintf(buf + len, BUF_SIZE - len, "\n"); len += scnprintf(buf + len, BUF_SIZE - len, "\n");
mlx4_err(dev, "%s", buf); mlx4_err(dev, "%s", buf);
if (len >= BUF_SIZE) if (len >= BUF_SIZE)
......
...@@ -616,7 +616,7 @@ static int enable_bars(struct nfp6000_pcie *nfp, u16 interface) ...@@ -616,7 +616,7 @@ static int enable_bars(struct nfp6000_pcie *nfp, u16 interface)
if (bar->iomem) { if (bar->iomem) {
int pf; int pf;
msg += snprintf(msg, end - msg, "0.0: General/MSI-X SRAM, "); msg += scnprintf(msg, end - msg, "0.0: General/MSI-X SRAM, ");
atomic_inc(&bar->refcnt); atomic_inc(&bar->refcnt);
bars_free--; bars_free--;
...@@ -661,7 +661,7 @@ static int enable_bars(struct nfp6000_pcie *nfp, u16 interface) ...@@ -661,7 +661,7 @@ static int enable_bars(struct nfp6000_pcie *nfp, u16 interface)
/* Configure, and lock, BAR0.1 for PCIe XPB (MSI-X PBA) */ /* Configure, and lock, BAR0.1 for PCIe XPB (MSI-X PBA) */
bar = &nfp->bar[1]; bar = &nfp->bar[1];
msg += snprintf(msg, end - msg, "0.1: PCIe XPB/MSI-X PBA, "); msg += scnprintf(msg, end - msg, "0.1: PCIe XPB/MSI-X PBA, ");
atomic_inc(&bar->refcnt); atomic_inc(&bar->refcnt);
bars_free--; bars_free--;
...@@ -680,7 +680,7 @@ static int enable_bars(struct nfp6000_pcie *nfp, u16 interface) ...@@ -680,7 +680,7 @@ static int enable_bars(struct nfp6000_pcie *nfp, u16 interface)
bar->iomem = ioremap(nfp_bar_resource_start(bar), bar->iomem = ioremap(nfp_bar_resource_start(bar),
nfp_bar_resource_len(bar)); nfp_bar_resource_len(bar));
if (bar->iomem) { if (bar->iomem) {
msg += snprintf(msg, end - msg, msg += scnprintf(msg, end - msg,
"0.%d: Explicit%d, ", 4 + i, i); "0.%d: Explicit%d, ", 4 + i, i);
atomic_inc(&bar->refcnt); atomic_inc(&bar->refcnt);
bars_free--; bars_free--;
......
...@@ -948,18 +948,18 @@ static void ionic_lif_rx_mode(struct ionic_lif *lif, unsigned int rx_mode) ...@@ -948,18 +948,18 @@ static void ionic_lif_rx_mode(struct ionic_lif *lif, unsigned int rx_mode)
int i; int i;
#define REMAIN(__x) (sizeof(buf) - (__x)) #define REMAIN(__x) (sizeof(buf) - (__x))
i = snprintf(buf, sizeof(buf), "rx_mode 0x%04x -> 0x%04x:", i = scnprintf(buf, sizeof(buf), "rx_mode 0x%04x -> 0x%04x:",
lif->rx_mode, rx_mode); lif->rx_mode, rx_mode);
if (rx_mode & IONIC_RX_MODE_F_UNICAST) if (rx_mode & IONIC_RX_MODE_F_UNICAST)
i += snprintf(&buf[i], REMAIN(i), " RX_MODE_F_UNICAST"); i += scnprintf(&buf[i], REMAIN(i), " RX_MODE_F_UNICAST");
if (rx_mode & IONIC_RX_MODE_F_MULTICAST) if (rx_mode & IONIC_RX_MODE_F_MULTICAST)
i += snprintf(&buf[i], REMAIN(i), " RX_MODE_F_MULTICAST"); i += scnprintf(&buf[i], REMAIN(i), " RX_MODE_F_MULTICAST");
if (rx_mode & IONIC_RX_MODE_F_BROADCAST) if (rx_mode & IONIC_RX_MODE_F_BROADCAST)
i += snprintf(&buf[i], REMAIN(i), " RX_MODE_F_BROADCAST"); i += scnprintf(&buf[i], REMAIN(i), " RX_MODE_F_BROADCAST");
if (rx_mode & IONIC_RX_MODE_F_PROMISC) if (rx_mode & IONIC_RX_MODE_F_PROMISC)
i += snprintf(&buf[i], REMAIN(i), " RX_MODE_F_PROMISC"); i += scnprintf(&buf[i], REMAIN(i), " RX_MODE_F_PROMISC");
if (rx_mode & IONIC_RX_MODE_F_ALLMULTI) if (rx_mode & IONIC_RX_MODE_F_ALLMULTI)
i += snprintf(&buf[i], REMAIN(i), " RX_MODE_F_ALLMULTI"); i += scnprintf(&buf[i], REMAIN(i), " RX_MODE_F_ALLMULTI");
netdev_dbg(lif->netdev, "lif%d %s\n", lif->index, buf); netdev_dbg(lif->netdev, "lif%d %s\n", lif->index, buf);
err = ionic_adminq_post_wait(lif, &ctx); err = ionic_adminq_post_wait(lif, &ctx);
......
...@@ -212,12 +212,14 @@ static void efx_mcdi_send_request(struct efx_nic *efx, unsigned cmd, ...@@ -212,12 +212,14 @@ static void efx_mcdi_send_request(struct efx_nic *efx, unsigned cmd,
* progress on a NIC at any one time. So no need for locking. * progress on a NIC at any one time. So no need for locking.
*/ */
for (i = 0; i < hdr_len / 4 && bytes < PAGE_SIZE; i++) for (i = 0; i < hdr_len / 4 && bytes < PAGE_SIZE; i++)
bytes += snprintf(buf + bytes, PAGE_SIZE - bytes, bytes += scnprintf(buf + bytes, PAGE_SIZE - bytes,
" %08x", le32_to_cpu(hdr[i].u32[0])); " %08x",
le32_to_cpu(hdr[i].u32[0]));
for (i = 0; i < inlen / 4 && bytes < PAGE_SIZE; i++) for (i = 0; i < inlen / 4 && bytes < PAGE_SIZE; i++)
bytes += snprintf(buf + bytes, PAGE_SIZE - bytes, bytes += scnprintf(buf + bytes, PAGE_SIZE - bytes,
" %08x", le32_to_cpu(inbuf[i].u32[0])); " %08x",
le32_to_cpu(inbuf[i].u32[0]));
netif_info(efx, hw, efx->net_dev, "MCDI RPC REQ:%s\n", buf); netif_info(efx, hw, efx->net_dev, "MCDI RPC REQ:%s\n", buf);
} }
...@@ -302,14 +304,14 @@ static void efx_mcdi_read_response_header(struct efx_nic *efx) ...@@ -302,14 +304,14 @@ static void efx_mcdi_read_response_header(struct efx_nic *efx)
*/ */
for (i = 0; i < hdr_len && bytes < PAGE_SIZE; i++) { for (i = 0; i < hdr_len && bytes < PAGE_SIZE; i++) {
efx->type->mcdi_read_response(efx, &hdr, (i * 4), 4); efx->type->mcdi_read_response(efx, &hdr, (i * 4), 4);
bytes += snprintf(buf + bytes, PAGE_SIZE - bytes, bytes += scnprintf(buf + bytes, PAGE_SIZE - bytes,
" %08x", le32_to_cpu(hdr.u32[0])); " %08x", le32_to_cpu(hdr.u32[0]));
} }
for (i = 0; i < data_len && bytes < PAGE_SIZE; i++) { for (i = 0; i < data_len && bytes < PAGE_SIZE; i++) {
efx->type->mcdi_read_response(efx, &hdr, efx->type->mcdi_read_response(efx, &hdr,
mcdi->resp_hdr_len + (i * 4), 4); mcdi->resp_hdr_len + (i * 4), 4);
bytes += snprintf(buf + bytes, PAGE_SIZE - bytes, bytes += scnprintf(buf + bytes, PAGE_SIZE - bytes,
" %08x", le32_to_cpu(hdr.u32[0])); " %08x", le32_to_cpu(hdr.u32[0]));
} }
...@@ -1417,9 +1419,11 @@ void efx_mcdi_print_fwver(struct efx_nic *efx, char *buf, size_t len) ...@@ -1417,9 +1419,11 @@ void efx_mcdi_print_fwver(struct efx_nic *efx, char *buf, size_t len)
} }
ver_words = (__le16 *)MCDI_PTR(outbuf, GET_VERSION_OUT_VERSION); ver_words = (__le16 *)MCDI_PTR(outbuf, GET_VERSION_OUT_VERSION);
offset = snprintf(buf, len, "%u.%u.%u.%u", offset = scnprintf(buf, len, "%u.%u.%u.%u",
le16_to_cpu(ver_words[0]), le16_to_cpu(ver_words[1]), le16_to_cpu(ver_words[0]),
le16_to_cpu(ver_words[2]), le16_to_cpu(ver_words[3])); le16_to_cpu(ver_words[1]),
le16_to_cpu(ver_words[2]),
le16_to_cpu(ver_words[3]));
/* EF10 may have multiple datapath firmware variants within a /* EF10 may have multiple datapath firmware variants within a
* single version. Report which variants are running. * single version. Report which variants are running.
...@@ -1427,7 +1431,7 @@ void efx_mcdi_print_fwver(struct efx_nic *efx, char *buf, size_t len) ...@@ -1427,7 +1431,7 @@ void efx_mcdi_print_fwver(struct efx_nic *efx, char *buf, size_t len)
if (efx_nic_rev(efx) >= EFX_REV_HUNT_A0) { if (efx_nic_rev(efx) >= EFX_REV_HUNT_A0) {
struct efx_ef10_nic_data *nic_data = efx->nic_data; struct efx_ef10_nic_data *nic_data = efx->nic_data;
offset += snprintf(buf + offset, len - offset, " rx%x tx%x", offset += scnprintf(buf + offset, len - offset, " rx%x tx%x",
nic_data->rx_dpcpu_fw_id, nic_data->rx_dpcpu_fw_id,
nic_data->tx_dpcpu_fw_id); nic_data->tx_dpcpu_fw_id);
......
...@@ -29,7 +29,7 @@ static ssize_t nsim_dbg_netdev_ops_read(struct file *filp, ...@@ -29,7 +29,7 @@ static ssize_t nsim_dbg_netdev_ops_read(struct file *filp,
return -ENOMEM; return -ENOMEM;
p = buf; p = buf;
p += snprintf(p, bufsize - (p - buf), p += scnprintf(p, bufsize - (p - buf),
"SA count=%u tx=%u\n", "SA count=%u tx=%u\n",
ipsec->count, ipsec->tx); ipsec->count, ipsec->tx);
...@@ -39,15 +39,15 @@ static ssize_t nsim_dbg_netdev_ops_read(struct file *filp, ...@@ -39,15 +39,15 @@ static ssize_t nsim_dbg_netdev_ops_read(struct file *filp,
if (!sap->used) if (!sap->used)
continue; continue;
p += snprintf(p, bufsize - (p - buf), p += scnprintf(p, bufsize - (p - buf),
"sa[%i] %cx ipaddr=0x%08x %08x %08x %08x\n", "sa[%i] %cx ipaddr=0x%08x %08x %08x %08x\n",
i, (sap->rx ? 'r' : 't'), sap->ipaddr[0], i, (sap->rx ? 'r' : 't'), sap->ipaddr[0],
sap->ipaddr[1], sap->ipaddr[2], sap->ipaddr[3]); sap->ipaddr[1], sap->ipaddr[2], sap->ipaddr[3]);
p += snprintf(p, bufsize - (p - buf), p += scnprintf(p, bufsize - (p - buf),
"sa[%i] spi=0x%08x proto=0x%x salt=0x%08x crypt=%d\n", "sa[%i] spi=0x%08x proto=0x%x salt=0x%08x crypt=%d\n",
i, be32_to_cpu(sap->xs->id.spi), i, be32_to_cpu(sap->xs->id.spi),
sap->xs->id.proto, sap->salt, sap->crypt); sap->xs->id.proto, sap->salt, sap->crypt);
p += snprintf(p, bufsize - (p - buf), p += scnprintf(p, bufsize - (p - buf),
"sa[%i] key=0x%08x %08x %08x %08x\n", "sa[%i] key=0x%08x %08x %08x %08x\n",
i, sap->key[0], sap->key[1], i, sap->key[0], sap->key[1],
sap->key[2], sap->key[3]); sap->key[2], sap->key[3]);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment