diff --git a/genl/ctrl.c b/genl/ctrl.c index 6abd5258..448988eb 100644 --- a/genl/ctrl.c +++ b/genl/ctrl.c @@ -313,7 +313,7 @@ static int ctrl_list(int cmd, int argc, char **argv) if (matches(*argv, "name") == 0) { NEXT_ARG(); - strncpy(d, *argv, sizeof (d) - 1); + strlcpy(d, *argv, sizeof(d)); addattr_l(nlh, 128, CTRL_ATTR_FAMILY_NAME, d, strlen(d) + 1); } else if (matches(*argv, "id") == 0) { diff --git a/include/utils.h b/include/utils.h index 1bb6d6a2..c9ed230b 100644 --- a/include/utils.h +++ b/include/utils.h @@ -252,4 +252,7 @@ int make_path(const char *path, mode_t mode); char *find_cgroup2_mount(void); int get_command_name(const char *pid, char *comm, size_t len); +size_t strlcpy(char *dst, const char *src, size_t size); +size_t strlcat(char *dst, const char *src, size_t size); + #endif /* __UTILS_H__ */ diff --git a/ip/ipnetns.c b/ip/ipnetns.c index 9ee1fe6a..afb4978a 100644 --- a/ip/ipnetns.c +++ b/ip/ipnetns.c @@ -518,8 +518,7 @@ int netns_identify_pid(const char *pidstr, char *name, int len) if ((st.st_dev == netst.st_dev) && (st.st_ino == netst.st_ino)) { - strncpy(name, entry->d_name, len - 1); - name[len - 1] = '\0'; + strlcpy(name, entry->d_name, len); } } closedir(dir); diff --git a/ip/iproute_lwtunnel.c b/ip/iproute_lwtunnel.c index 02f36ef7..1c8adbe7 100644 --- a/ip/iproute_lwtunnel.c +++ b/ip/iproute_lwtunnel.c @@ -493,8 +493,7 @@ static int parse_encap_seg6(struct rtattr *rta, size_t len, int *argcp, invarg("\"segs\" provided before \"mode\"\n", *argv); - strncpy(segbuf, *argv, 1024); - segbuf[1023] = 0; + strlcpy(segbuf, *argv, 1024); } else if (strcmp(*argv, "hmac") == 0) { NEXT_ARG(); if (hmac_ok++) diff --git a/ip/ipvrf.c b/ip/ipvrf.c index e6fad32a..f9277e1e 100644 --- a/ip/ipvrf.c +++ b/ip/ipvrf.c @@ -74,7 +74,7 @@ static int vrf_identify(pid_t pid, char *name, size_t len) if (end) *end = '\0'; - strncpy(name, vrf, len - 1); + strlcpy(name, vrf, len); break; } } @@ -336,8 +336,7 @@ static int vrf_path(char *vpath, size_t len) if (vrf) *vrf = '\0'; - strncpy(vpath, start, len - 1); - vpath[len - 1] = '\0'; + strlcpy(vpath, start, len); /* if vrf path is just / then return nothing */ if (!strcmp(vpath, "/")) diff --git a/ip/ipxfrm.c b/ip/ipxfrm.c index d5eb22e2..12c2f721 100644 --- a/ip/ipxfrm.c +++ b/ip/ipxfrm.c @@ -40,17 +40,6 @@ #include "ip_common.h" #define STRBUF_SIZE (128) -#define STRBUF_CAT(buf, str) \ - do { \ - int rest = sizeof(buf) - 1 - strlen(buf); \ - if (rest > 0) { \ - int len = strlen(str); \ - if (len > rest) \ - len = rest; \ - strncat(buf, str, len); \ - buf[sizeof(buf) - 1] = '\0'; \ - } \ - } while (0); struct xfrm_filter filter; @@ -902,8 +891,8 @@ void xfrm_state_info_print(struct xfrm_usersa_info *xsinfo, prefix, title); if (prefix) - STRBUF_CAT(buf, prefix); - STRBUF_CAT(buf, "\t"); + strlcat(buf, prefix, sizeof(buf)); + strlcat(buf, "\t", sizeof(buf)); fputs(buf, fp); fprintf(fp, "replay-window %u ", xsinfo->replay_window); @@ -944,7 +933,7 @@ void xfrm_state_info_print(struct xfrm_usersa_info *xsinfo, char sbuf[STRBUF_SIZE]; memcpy(sbuf, buf, sizeof(sbuf)); - STRBUF_CAT(sbuf, "sel "); + strlcat(sbuf, "sel ", sizeof(sbuf)); xfrm_selector_print(&xsinfo->sel, xsinfo->family, fp, sbuf); } @@ -992,8 +981,8 @@ void xfrm_policy_info_print(struct xfrm_userpolicy_info *xpinfo, } if (prefix) - STRBUF_CAT(buf, prefix); - STRBUF_CAT(buf, "\t"); + strlcat(buf, prefix, sizeof(buf)); + strlcat(buf, "\t", sizeof(buf)); fputs(buf, fp); if (xpinfo->dir >= XFRM_POLICY_MAX) { diff --git a/ip/link_gre6.c b/ip/link_gre6.c index 957853d6..7d07932a 100644 --- a/ip/link_gre6.c +++ b/ip/link_gre6.c @@ -288,6 +288,7 @@ get_failed: else { if (get_u8(&uval, *argv, 16)) invarg("invalid TClass", *argv); + flowinfo &= ~IP6_FLOWINFO_TCLASS; flowinfo |= htonl((__u32)uval << 20) & IP6_FLOWINFO_TCLASS; flags &= ~IP6_TNL_F_USE_ORIG_TCLASS; } @@ -303,6 +304,7 @@ get_failed: invarg("invalid Flowlabel", *argv); if (uval > 0xFFFFF) invarg("invalid Flowlabel", *argv); + flowinfo &= ~IP6_FLOWINFO_FLOWLABEL; flowinfo |= htonl(uval) & IP6_FLOWINFO_FLOWLABEL; flags &= ~IP6_TNL_F_USE_ORIG_FLOWLABEL; } @@ -488,6 +490,24 @@ static void gre_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[]) } } + if (flags & IP6_TNL_F_USE_ORIG_TCLASS) { + print_bool(PRINT_ANY, + "ip6_tnl_f_use_orig_tclass", + "tclass inherit ", + true); + } else { + if (is_json_context()) { + SPRINT_BUF(b1); + + snprintf(b1, sizeof(b1), "0x%05x", + ntohl(flowinfo & IP6_FLOWINFO_TCLASS) >> 20); + print_string(PRINT_JSON, "tclass", NULL, b1); + } else { + fprintf(f, "tclass 0x%02x ", + ntohl(flowinfo & IP6_FLOWINFO_TCLASS) >> 20); + } + } + if (flags & IP6_TNL_F_RCV_DSCP_COPY) print_bool(PRINT_ANY, "ip6_tnl_f_rcv_dscp_copy", diff --git a/ip/xfrm_state.c b/ip/xfrm_state.c index e11c93bf..4483fb8f 100644 --- a/ip/xfrm_state.c +++ b/ip/xfrm_state.c @@ -125,7 +125,7 @@ static int xfrm_algo_parse(struct xfrm_algo *alg, enum xfrm_attr_type_t type, fprintf(stderr, "warning: ALGO-NAME/ALGO-KEYMAT values will be sent to the kernel promiscuously! (verifying them isn't implemented yet)\n"); #endif - strncpy(alg->alg_name, name, sizeof(alg->alg_name)); + strlcpy(alg->alg_name, name, sizeof(alg->alg_name)); if (slen > 2 && strncmp(key, "0x", 2) == 0) { /* split two chars "0x" from the top */ diff --git a/lib/bpf.c b/lib/bpf.c index 0bd0a95e..c180934a 100644 --- a/lib/bpf.c +++ b/lib/bpf.c @@ -512,8 +512,7 @@ static const char *bpf_find_mntpt_single(unsigned long magic, char *mnt, ret = bpf_valid_mntpt(mntpt, magic); if (!ret) { - strncpy(mnt, mntpt, len - 1); - mnt[len - 1] = 0; + strlcpy(mnt, mntpt, len); return mnt; } diff --git a/lib/fs.c b/lib/fs.c index ebe05cd4..86efd4ed 100644 --- a/lib/fs.c +++ b/lib/fs.c @@ -172,8 +172,7 @@ int get_command_name(const char *pid, char *comm, size_t len) if (nl) *nl = '\0'; - strncpy(comm, name, len - 1); - comm[len - 1] = '\0'; + strlcpy(comm, name, len); break; } diff --git a/lib/inet_proto.c b/lib/inet_proto.c index 53c02903..bdfd52fd 100644 --- a/lib/inet_proto.c +++ b/lib/inet_proto.c @@ -38,8 +38,7 @@ const char *inet_proto_n2a(int proto, char *buf, int len) free(ncache); icache = proto; ncache = strdup(pe->p_name); - strncpy(buf, pe->p_name, len - 1); - buf[len - 1] = '\0'; + strlcpy(buf, pe->p_name, len); return buf; } snprintf(buf, len, "ipproto-%d", proto); diff --git a/lib/utils.c b/lib/utils.c index 9143ed22..330ab073 100644 --- a/lib/utils.c +++ b/lib/utils.c @@ -1230,3 +1230,22 @@ int get_real_family(int rtm_type, int rtm_family) return rtm_family; } + +size_t strlcpy(char *dst, const char *src, size_t size) +{ + if (size) { + strncpy(dst, src, size - 1); + dst[size - 1] = '\0'; + } + return strlen(src); +} + +size_t strlcat(char *dst, const char *src, size_t size) +{ + size_t dlen = strlen(dst); + + if (dlen > size) + return dlen + strlen(src); + + return dlen + strlcpy(dst + dlen, src, size - dlen); +} diff --git a/misc/lnstat_util.c b/misc/lnstat_util.c index ec19238c..c2dc42ec 100644 --- a/misc/lnstat_util.c +++ b/misc/lnstat_util.c @@ -150,7 +150,8 @@ static int lnstat_scan_compat_rtstat_fields(struct lnstat_file *lf) { char buf[FGETS_BUF_SIZE]; - strncpy(buf, RTSTAT_COMPAT_LINE, sizeof(buf)-1); + strncpy(buf, RTSTAT_COMPAT_LINE, sizeof(buf) - 1); + buf[sizeof(buf) - 1] = '\0'; return __lnstat_scan_fields(lf, buf); } diff --git a/misc/ss.c b/misc/ss.c index 2c9e80e6..dd8dfaa4 100644 --- a/misc/ss.c +++ b/misc/ss.c @@ -425,8 +425,7 @@ static void user_ent_hash_build(void) user_ent_hash_build_init = 1; - strncpy(name, root, sizeof(name)-1); - name[sizeof(name)-1] = 0; + strlcpy(name, root, sizeof(name)); if (strlen(name) == 0 || name[strlen(name)-1] != '/') strcat(name, "/"); diff --git a/tc/em_ipset.c b/tc/em_ipset.c index b5975651..48b287f5 100644 --- a/tc/em_ipset.c +++ b/tc/em_ipset.c @@ -145,8 +145,7 @@ get_set_byname(const char *setname, struct xt_set_info *info) int res; req.op = IP_SET_OP_GET_BYNAME; - strncpy(req.set.name, setname, IPSET_MAXNAMELEN); - req.set.name[IPSET_MAXNAMELEN - 1] = '\0'; + strlcpy(req.set.name, setname, IPSET_MAXNAMELEN); res = do_getsockopt(&req); if (res != 0) return -1; diff --git a/tc/tc_util.c b/tc/tc_util.c index 37104683..50d35504 100644 --- a/tc/tc_util.c +++ b/tc/tc_util.c @@ -434,7 +434,6 @@ static const char *action_n2a(int action) return "trap"; default: snprintf(buf, 64, "%d", action); - buf[63] = '\0'; return buf; } }