lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Date:   Tue, 15 Jan 2019 18:52:43 -0800
From:   Benedict Wong <benedictwong@...gle.com>
To:     netdev@...r.kernel.org
Cc:     Nathan Harold <nharold@...gle.com>,
        Florian Fainelli <f.fainelli@...il.com>,
        Lorenzo Colitti <lorenzo@...gle.com>,
        Maciej Żenczykowski <maze@...gle.com>
Subject: Re: [PATCH iproute2] xfrm: add option to hide keys in state output

Friendly ping for review. If there are no concerns, I think this would
be useful especially in the logging/bugreport use cases.

On Mon, Jan 7, 2019 at 3:10 PM Benedict Wong <benedictwong@...gle.com> wrote:
>
> (Accidentally sent previously as direct reply. Re-sending as reply-all)
>
> > ... would not it be better to not request the
> > kernel not to dump the keys to begin with ...
>
> I think it's still valid to have it in iproute2, since it does allow for
> backward compatibility against older kernels. Adding it to the
> kernels would mean it hits 5.1+ at the very most.
>
> > ... that way a process ptracing
> > iproute2 or whatever, would also not have a chance to ex-filtrate those
> > keys? ...
>
> That is a good point. I suspect the kernel will still need to have the
> keys dumped default in order to maintain backwards compatibility, so
> this does also add some safety. The primary goal of this patch was to
> allow someone with (permanent) access to the to automatically
> generate a debug log that doesn't compromise (eg a privileged system
> daemon, or a superuser). Just my 2c though :)
>
> On Mon, Jan 7, 2019 at 2:23 PM Florian Fainelli <f.fainelli@...il.com> wrote:
> >
> > On 1/7/19 1:31 PM, Benedict Wong wrote:
> > > ip xfrm state show currently dumps keys unconditionally. This limits its
> > > use in logging, as security information can be leaked.
> > >
> > > This patch adds a nokeys option to ip xfrm ( state show | monitor ), which
> > > prevents the printing of keys. This allows ip xfrm state show to be used
> > > in logging without exposing keys.
> >
> > I have not yet looked at the kernel side, but assuming the keys are
> > stored on the kernel side as well (which is quite conceivably what is
> > happening for software IPsec), would not it be better to not request the
> > kernel not to dump the keys to begin with, that way a process ptracing
> > iproute2 or whatever, would also not have a chance to ex-filtrate those
> > keys? If this is not how this is implemented, apologies :)
> >
> > >
> > > Signed-off-by: Benedict Wong <benedictwong@...gle.com>
> > > ---
> > >  ip/ipxfrm.c        | 45 +++++++++++++++++++++++++--------------------
> > >  ip/xfrm.h          |  5 +++--
> > >  ip/xfrm_monitor.c  |  7 +++++--
> > >  ip/xfrm_state.c    | 27 ++++++++++++++++++++++-----
> > >  man/man8/ip-xfrm.8 | 15 ++++++++++++++-
> > >  5 files changed, 69 insertions(+), 30 deletions(-)
> > >
> > > diff --git a/ip/ipxfrm.c b/ip/ipxfrm.c
> > > index 2dea4e37..1334ca9f 100644
> > > --- a/ip/ipxfrm.c
> > > +++ b/ip/ipxfrm.c
> > > @@ -497,7 +497,8 @@ void xfrm_selector_print(struct xfrm_selector *sel, __u16 family,
> > >  }
> > >
> > >  static void __xfrm_algo_print(struct xfrm_algo *algo, int type, int len,
> > > -                           FILE *fp, const char *prefix, int newline)
> > > +                           FILE *fp, const char *prefix, int newline,
> > > +                           bool nokeys)
> > >  {
> > >       int keylen;
> > >       int i;
> > > @@ -521,7 +522,9 @@ static void __xfrm_algo_print(struct xfrm_algo *algo, int type, int len,
> > >               goto fin;
> > >       }
> > >
> > > -     if (keylen > 0) {
> > > +     if (nokeys)
> > > +             fprintf(fp, "<<Keys hidden>>");
> > > +     else if (keylen > 0) {
> > >               fprintf(fp, "0x");
> > >               for (i = 0; i < keylen; i++)
> > >                       fprintf(fp, "%.2x", (unsigned char)algo->alg_key[i]);
> > > @@ -536,13 +539,13 @@ static void __xfrm_algo_print(struct xfrm_algo *algo, int type, int len,
> > >  }
> > >
> > >  static inline void xfrm_algo_print(struct xfrm_algo *algo, int type, int len,
> > > -                                FILE *fp, const char *prefix)
> > > +                                FILE *fp, const char *prefix, bool nokeys)
> > >  {
> > > -     return __xfrm_algo_print(algo, type, len, fp, prefix, 1);
> > > +     return __xfrm_algo_print(algo, type, len, fp, prefix, 1, nokeys);
> > >  }
> > >
> > >  static void xfrm_aead_print(struct xfrm_algo_aead *algo, int len,
> > > -                         FILE *fp, const char *prefix)
> > > +                         FILE *fp, const char *prefix, bool nokeys)
> > >  {
> > >       struct xfrm_algo *base_algo = alloca(sizeof(*base_algo) + algo->alg_key_len / 8);
> > >
> > > @@ -550,7 +553,8 @@ static void xfrm_aead_print(struct xfrm_algo_aead *algo, int len,
> > >       base_algo->alg_key_len = algo->alg_key_len;
> > >       memcpy(base_algo->alg_key, algo->alg_key, algo->alg_key_len / 8);
> > >
> > > -     __xfrm_algo_print(base_algo, XFRMA_ALG_AEAD, len, fp, prefix, 0);
> > > +     __xfrm_algo_print(base_algo,
> > > +                       XFRMA_ALG_AEAD, len, fp, prefix, 0, nokeys);
> > >
> > >       fprintf(fp, " %d", algo->alg_icv_len);
> > >
> > > @@ -558,7 +562,7 @@ static void xfrm_aead_print(struct xfrm_algo_aead *algo, int len,
> > >  }
> > >
> > >  static void xfrm_auth_trunc_print(struct xfrm_algo_auth *algo, int len,
> > > -                               FILE *fp, const char *prefix)
> > > +                               FILE *fp, const char *prefix, bool nokeys)
> > >  {
> > >       struct xfrm_algo *base_algo = alloca(sizeof(*base_algo) + algo->alg_key_len / 8);
> > >
> > > @@ -566,7 +570,8 @@ static void xfrm_auth_trunc_print(struct xfrm_algo_auth *algo, int len,
> > >       base_algo->alg_key_len = algo->alg_key_len;
> > >       memcpy(base_algo->alg_key, algo->alg_key, algo->alg_key_len / 8);
> > >
> > > -     __xfrm_algo_print(base_algo, XFRMA_ALG_AUTH_TRUNC, len, fp, prefix, 0);
> > > +     __xfrm_algo_print(base_algo,
> > > +                       XFRMA_ALG_AUTH_TRUNC, len, fp, prefix, 0, nokeys);
> > >
> > >       fprintf(fp, " %d", algo->alg_trunc_len);
> > >
> > > @@ -679,7 +684,7 @@ done:
> > >  }
> > >
> > >  void xfrm_xfrma_print(struct rtattr *tb[], __u16 family,
> > > -                   FILE *fp, const char *prefix)
> > > +                   FILE *fp, const char *prefix, bool nokeys)
> > >  {
> > >       if (tb[XFRMA_MARK]) {
> > >               struct rtattr *rta = tb[XFRMA_MARK];
> > > @@ -700,36 +705,36 @@ void xfrm_xfrma_print(struct rtattr *tb[], __u16 family,
> > >       if (tb[XFRMA_ALG_AUTH] && !tb[XFRMA_ALG_AUTH_TRUNC]) {
> > >               struct rtattr *rta = tb[XFRMA_ALG_AUTH];
> > >
> > > -             xfrm_algo_print(RTA_DATA(rta),
> > > -                             XFRMA_ALG_AUTH, RTA_PAYLOAD(rta), fp, prefix);
> > > +             xfrm_algo_print(RTA_DATA(rta), XFRMA_ALG_AUTH,
> > > +                             RTA_PAYLOAD(rta), fp, prefix, nokeys);
> > >       }
> > >
> > >       if (tb[XFRMA_ALG_AUTH_TRUNC]) {
> > >               struct rtattr *rta = tb[XFRMA_ALG_AUTH_TRUNC];
> > >
> > >               xfrm_auth_trunc_print(RTA_DATA(rta),
> > > -                                   RTA_PAYLOAD(rta), fp, prefix);
> > > +                                   RTA_PAYLOAD(rta), fp, prefix, nokeys);
> > >       }
> > >
> > >       if (tb[XFRMA_ALG_AEAD]) {
> > >               struct rtattr *rta = tb[XFRMA_ALG_AEAD];
> > >
> > >               xfrm_aead_print(RTA_DATA(rta),
> > > -                             RTA_PAYLOAD(rta), fp, prefix);
> > > +                             RTA_PAYLOAD(rta), fp, prefix, nokeys);
> > >       }
> > >
> > >       if (tb[XFRMA_ALG_CRYPT]) {
> > >               struct rtattr *rta = tb[XFRMA_ALG_CRYPT];
> > >
> > > -             xfrm_algo_print(RTA_DATA(rta),
> > > -                             XFRMA_ALG_CRYPT, RTA_PAYLOAD(rta), fp, prefix);
> > > +             xfrm_algo_print(RTA_DATA(rta), XFRMA_ALG_CRYPT,
> > > +                             RTA_PAYLOAD(rta), fp, prefix, nokeys);
> > >       }
> > >
> > >       if (tb[XFRMA_ALG_COMP]) {
> > >               struct rtattr *rta = tb[XFRMA_ALG_COMP];
> > >
> > > -             xfrm_algo_print(RTA_DATA(rta),
> > > -                             XFRMA_ALG_COMP, RTA_PAYLOAD(rta), fp, prefix);
> > > +             xfrm_algo_print(RTA_DATA(rta), XFRMA_ALG_COMP,
> > > +                             RTA_PAYLOAD(rta), fp, prefix, nokeys);
> > >       }
> > >
> > >       if (tb[XFRMA_ENCAP]) {
> > > @@ -897,7 +902,7 @@ static int xfrm_selector_iszero(struct xfrm_selector *s)
> > >
> > >  void xfrm_state_info_print(struct xfrm_usersa_info *xsinfo,
> > >                           struct rtattr *tb[], FILE *fp, const char *prefix,
> > > -                         const char *title)
> > > +                         const char *title, bool nokeys)
> > >  {
> > >       char buf[STRBUF_SIZE] = {};
> > >       int force_spi = xfrm_xfrmproto_is_ipsec(xsinfo->id.proto);
> > > @@ -943,7 +948,7 @@ void xfrm_state_info_print(struct xfrm_usersa_info *xsinfo,
> > >               fprintf(fp, " (0x%s)", strxf_mask8(xsinfo->flags));
> > >       fprintf(fp, "%s", _SL_);
> > >
> > > -     xfrm_xfrma_print(tb, xsinfo->family, fp, buf);
> > > +     xfrm_xfrma_print(tb, xsinfo->family, fp, buf, nokeys);
> > >
> > >       if (!xfrm_selector_iszero(&xsinfo->sel)) {
> > >               char sbuf[STRBUF_SIZE];
> > > @@ -1071,7 +1076,7 @@ void xfrm_policy_info_print(struct xfrm_userpolicy_info *xpinfo,
> > >       if (show_stats > 0)
> > >               xfrm_lifetime_print(&xpinfo->lft, &xpinfo->curlft, fp, buf);
> > >
> > > -     xfrm_xfrma_print(tb, xpinfo->sel.family, fp, buf);
> > > +     xfrm_xfrma_print(tb, xpinfo->sel.family, fp, buf, false);
> > >  }
> > >
> > >  int xfrm_id_parse(xfrm_address_t *saddr, struct xfrm_id *id, __u16 *family,
> > > diff --git a/ip/xfrm.h b/ip/xfrm.h
> > > index 72390d79..9ba5ca61 100644
> > > --- a/ip/xfrm.h
> > > +++ b/ip/xfrm.h
> > > @@ -105,6 +105,7 @@ struct xfrm_filter {
> > >  extern struct xfrm_filter filter;
> > >
> > >  int xfrm_state_print(struct nlmsghdr *n, void *arg);
> > > +int xfrm_state_print_nokeys(struct nlmsghdr *n, void *arg);
> > >  int xfrm_policy_print(struct nlmsghdr *n, void *arg);
> > >  int do_xfrm_state(int argc, char **argv);
> > >  int do_xfrm_policy(int argc, char **argv);
> > > @@ -124,10 +125,10 @@ const char *strxf_ptype(__u8 ptype);
> > >  void xfrm_selector_print(struct xfrm_selector *sel, __u16 family,
> > >                        FILE *fp, const char *prefix);
> > >  void xfrm_xfrma_print(struct rtattr *tb[], __u16 family,
> > > -                   FILE *fp, const char *prefix);
> > > +                   FILE *fp, const char *prefix, bool nokeys);
> > >  void xfrm_state_info_print(struct xfrm_usersa_info *xsinfo,
> > >                           struct rtattr *tb[], FILE *fp, const char *prefix,
> > > -                        const char *title);
> > > +                        const char *title, bool nokeys);
> > >  void xfrm_policy_info_print(struct xfrm_userpolicy_info *xpinfo,
> > >                           struct rtattr *tb[], FILE *fp, const char *prefix,
> > >                           const char *title);
> > > diff --git a/ip/xfrm_monitor.c b/ip/xfrm_monitor.c
> > > index 76905ed3..17117f41 100644
> > > --- a/ip/xfrm_monitor.c
> > > +++ b/ip/xfrm_monitor.c
> > > @@ -35,10 +35,11 @@
> > >
> > >  static void usage(void) __attribute__((noreturn));
> > >  static int listen_all_nsid;
> > > +static bool nokeys;
> > >
> > >  static void usage(void)
> > >  {
> > > -     fprintf(stderr, "Usage: ip xfrm monitor [all-nsid] [ all | OBJECTS | help ]\n");
> > > +     fprintf(stderr, "Usage: ip xfrm monitor [ nokeys ] [ all-nsid ] [ all | OBJECTS | help ]\n");
> > >       fprintf(stderr, "OBJECTS := { acquire | expire | SA | aevent | policy | report }\n");
> > >       exit(-1);
> > >  }
> > > @@ -197,7 +198,7 @@ static int xfrm_report_print(struct nlmsghdr *n, void *arg)
> > >
> > >       parse_rtattr(tb, XFRMA_MAX, XFRMREP_RTA(xrep), len);
> > >
> > > -     xfrm_xfrma_print(tb, family, fp, "  ");
> > > +     xfrm_xfrma_print(tb, family, fp, "  ", nokeys);
> > >
> > >       if (oneline)
> > >               fprintf(fp, "\n");
> > > @@ -352,6 +353,8 @@ int do_xfrm_monitor(int argc, char **argv)
> > >               if (matches(*argv, "file") == 0) {
> > >                       NEXT_ARG();
> > >                       file = *argv;
> > > +             } else if (strcmp(*argv, "nokeys") == 0) {
> > > +                     nokeys = true;
> > >               } else if (strcmp(*argv, "all") == 0) {
> > >                       /* fall out */
> > >               } else if (matches(*argv, "all-nsid") == 0) {
> > > diff --git a/ip/xfrm_state.c b/ip/xfrm_state.c
> > > index e8c01746..d8f9350e 100644
> > > --- a/ip/xfrm_state.c
> > > +++ b/ip/xfrm_state.c
> > > @@ -65,7 +65,9 @@ static void usage(void)
> > >       fprintf(stderr, "Usage: ip xfrm state allocspi ID [ mode MODE ] [ mark MARK [ mask MASK ] ]\n");
> > >       fprintf(stderr, "        [ reqid REQID ] [ seq SEQ ] [ min SPI max SPI ]\n");
> > >       fprintf(stderr, "Usage: ip xfrm state { delete | get } ID [ mark MARK [ mask MASK ] ]\n");
> > > -     fprintf(stderr, "Usage: ip xfrm state { deleteall | list } [ ID ] [ mode MODE ] [ reqid REQID ]\n");
> > > +     fprintf(stderr, "Usage: ip xfrm state { deleteall } [ ID ] [ mode MODE ] [ reqid REQID ]\n");
> > > +     fprintf(stderr, "        [ flag FLAG-LIST ]\n");
> > > +     fprintf(stderr, "Usage: ip xfrm state { list } [ nokeys ] [ ID ] [ mode MODE ] [ reqid REQID ]\n");
> > >       fprintf(stderr, "        [ flag FLAG-LIST ]\n");
> > >       fprintf(stderr, "Usage: ip xfrm state flush [ proto XFRM-PROTO ]\n");
> > >       fprintf(stderr, "Usage: ip xfrm state count\n");
> > > @@ -908,7 +910,7 @@ static int xfrm_state_filter_match(struct xfrm_usersa_info *xsinfo)
> > >       return 1;
> > >  }
> > >
> > > -int xfrm_state_print(struct nlmsghdr *n, void *arg)
> > > +static int __do_xfrm_state_print(struct nlmsghdr *n, void *arg, bool nokeys)
> > >  {
> > >       FILE *fp = (FILE *)arg;
> > >       struct rtattr *tb[XFRMA_MAX+1];
> > > @@ -979,7 +981,7 @@ int xfrm_state_print(struct nlmsghdr *n, void *arg)
> > >               xsinfo = RTA_DATA(tb[XFRMA_SA]);
> > >       }
> > >
> > > -     xfrm_state_info_print(xsinfo, tb, fp, NULL, NULL);
> > > +     xfrm_state_info_print(xsinfo, tb, fp, NULL, NULL, nokeys);
> > >
> > >       if (n->nlmsg_type == XFRM_MSG_EXPIRE) {
> > >               fprintf(fp, "\t");
> > > @@ -994,6 +996,16 @@ int xfrm_state_print(struct nlmsghdr *n, void *arg)
> > >       return 0;
> > >  }
> > >
> > > +int xfrm_state_print(struct nlmsghdr *n, void *arg)
> > > +{
> > > +     return __do_xfrm_state_print(n, arg, false);
> > > +}
> > > +
> > > +int xfrm_state_print_nokeys(struct nlmsghdr *n, void *arg)
> > > +{
> > > +     return __do_xfrm_state_print(n, arg, true);
> > > +}
> > > +
> > >  static int xfrm_state_get_or_delete(int argc, char **argv, int delete)
> > >  {
> > >       struct rtnl_handle rth;
> > > @@ -1145,13 +1157,16 @@ static int xfrm_state_list_or_deleteall(int argc, char **argv, int deleteall)
> > >  {
> > >       char *idp = NULL;
> > >       struct rtnl_handle rth;
> > > +     bool nokeys = false;
> > >
> > >       if (argc > 0)
> > >               filter.use = 1;
> > >       filter.xsinfo.family = preferred_family;
> > >
> > >       while (argc > 0) {
> > > -             if (strcmp(*argv, "mode") == 0) {
> > > +             if (strcmp(*argv, "nokeys") == 0) {
> > > +                     nokeys = true;
> > > +             } else if (strcmp(*argv, "mode") == 0) {
> > >                       NEXT_ARG();
> > >                       xfrm_mode_parse(&filter.xsinfo.mode, &argc, &argv);
> > >
> > > @@ -1267,7 +1282,9 @@ static int xfrm_state_list_or_deleteall(int argc, char **argv, int deleteall)
> > >                       exit(1);
> > >               }
> > >
> > > -             if (rtnl_dump_filter(&rth, xfrm_state_print, stdout) < 0) {
> > > +             rtnl_filter_t filter = nokeys ?
> > > +                             xfrm_state_print_nokeys : xfrm_state_print;
> > > +             if (rtnl_dump_filter(&rth, filter, stdout) < 0) {
> > >                       fprintf(stderr, "Dump terminated\n");
> > >                       exit(1);
> > >               }
> > > diff --git a/man/man8/ip-xfrm.8 b/man/man8/ip-xfrm.8
> > > index 839e06aa..0fdf97d9 100644
> > > --- a/man/man8/ip-xfrm.8
> > > +++ b/man/man8/ip-xfrm.8
> > > @@ -89,7 +89,7 @@ ip-xfrm \- transform configuration
> > >  .IR MASK " ] ]"
> > >
> > >  .ti -8
> > > -.BR "ip xfrm state" " { " deleteall " | " list " } ["
> > > +.BR "ip xfrm state" " { " deleteall " } ["
> > >  .IR ID " ]"
> > >  .RB "[ " mode
> > >  .IR MODE " ]"
> > > @@ -98,6 +98,17 @@ ip-xfrm \- transform configuration
> > >  .RB "[ " flag
> > >  .IR FLAG-LIST " ]"
> > >
> > > +.ti -8
> > > +.BR "ip xfrm state" " { " list " } ["
> > > +.IR ID " ]"
> > > +.RB "[ " nokeys " ]"
> > > +.RB "[ " mode
> > > +.IR MODE " ]"
> > > +.RB "[ " reqid
> > > +.IR REQID " ]"
> > > +.RB "[ " flag
> > > +.IR FLAG-LIST " ]"
> > > +
> > >  .ti -8
> > >  .BR "ip xfrm state flush" " [ " proto
> > >  .IR XFRM-PROTO " ]"
> > > @@ -381,6 +392,8 @@ ip-xfrm \- transform configuration
> > >  .BR "ip xfrm monitor" " ["
> > >  .BI all-nsid
> > >  ] [
> > > +.BI nokeys
> > > +] [
> > >  .BI all
> > >   |
> > >  .IR LISTofXFRM-OBJECTS " ]"
> > >
> >
> >
> > --
> > Florian

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ