From: Greg Kroah-Hartman Date: Sat, 2 Feb 2019 11:19:31 +0000 (+0100) Subject: 3.18-stable patches X-Git-Tag: v4.20.7~44 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=dfc32e79b2c6bc4680284d2693c5c8d442e72770;p=thirdparty%2Fkernel%2Fstable-queue.git 3.18-stable patches added patches: ipv6-consider-sk_bound_dev_if-when-binding-a-socket-to-an-address.patch l2tp-copy-4-more-bytes-to-linear-part-if-necessary.patch l2tp-fix-reading-optional-fields-of-l2tpv3.patch l2tp-remove-l2specific_len-dependency-in-l2tp_core.patch net-rose-fix-null-ax25_cb-kernel-panic.patch netrom-switch-to-sock-timer-api.patch ucc_geth-reset-bql-queue-when-stopping-device.patch --- diff --git a/queue-3.18/ipv6-consider-sk_bound_dev_if-when-binding-a-socket-to-an-address.patch b/queue-3.18/ipv6-consider-sk_bound_dev_if-when-binding-a-socket-to-an-address.patch new file mode 100644 index 00000000000..e4ec7a1e6d0 --- /dev/null +++ b/queue-3.18/ipv6-consider-sk_bound_dev_if-when-binding-a-socket-to-an-address.patch @@ -0,0 +1,37 @@ +From foo@baz Sat Feb 2 11:44:37 CET 2019 +From: David Ahern +Date: Wed, 2 Jan 2019 18:57:09 -0800 +Subject: ipv6: Consider sk_bound_dev_if when binding a socket to an address + +From: David Ahern + +[ Upstream commit c5ee066333ebc322a24a00a743ed941a0c68617e ] + +IPv6 does not consider if the socket is bound to a device when binding +to an address. The result is that a socket can be bound to eth0 and then +bound to the address of eth1. If the device is a VRF, the result is that +a socket can only be bound to an address in the default VRF. + +Resolve by considering the device if sk_bound_dev_if is set. + +This problem exists from the beginning of git history. + +Signed-off-by: David Ahern +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv6/af_inet6.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/net/ipv6/af_inet6.c ++++ b/net/ipv6/af_inet6.c +@@ -333,6 +333,9 @@ int inet6_bind(struct socket *sock, stru + err = -EINVAL; + goto out_unlock; + } ++ } ++ ++ if (sk->sk_bound_dev_if) { + dev = dev_get_by_index_rcu(net, sk->sk_bound_dev_if); + if (!dev) { + err = -ENODEV; diff --git a/queue-3.18/l2tp-copy-4-more-bytes-to-linear-part-if-necessary.patch b/queue-3.18/l2tp-copy-4-more-bytes-to-linear-part-if-necessary.patch new file mode 100644 index 00000000000..a0e4a23fe0b --- /dev/null +++ b/queue-3.18/l2tp-copy-4-more-bytes-to-linear-part-if-necessary.patch @@ -0,0 +1,51 @@ +From foo@baz Sat Feb 2 11:44:37 CET 2019 +From: Jacob Wen +Date: Thu, 31 Jan 2019 15:18:56 +0800 +Subject: l2tp: copy 4 more bytes to linear part if necessary + +From: Jacob Wen + +[ Upstream commit 91c524708de6207f59dd3512518d8a1c7b434ee3 ] + +The size of L2TPv2 header with all optional fields is 14 bytes. +l2tp_udp_recv_core only moves 10 bytes to the linear part of a +skb. This may lead to l2tp_recv_common read data outside of a skb. + +This patch make sure that there is at least 14 bytes in the linear +part of a skb to meet the maximum need of l2tp_udp_recv_core and +l2tp_recv_common. The minimum size of both PPP HDLC-like frame and +Ethernet frame is larger than 14 bytes, so we are safe to do so. + +Also remove L2TP_HDR_SIZE_NOSEQ, it is unused now. + +Fixes: fd558d186df2 ("l2tp: Split pppol2tp patch into separate l2tp and ppp parts") +Suggested-by: Guillaume Nault +Signed-off-by: Jacob Wen +Acked-by: Guillaume Nault +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/l2tp/l2tp_core.c | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +--- a/net/l2tp/l2tp_core.c ++++ b/net/l2tp/l2tp_core.c +@@ -83,8 +83,7 @@ + #define L2TP_SLFLAG_S 0x40000000 + #define L2TP_SL_SEQ_MASK 0x00ffffff + +-#define L2TP_HDR_SIZE_SEQ 10 +-#define L2TP_HDR_SIZE_NOSEQ 6 ++#define L2TP_HDR_SIZE_MAX 14 + + /* Default trace flags */ + #define L2TP_DEFAULT_DEBUG_FLAGS 0 +@@ -856,7 +855,7 @@ static int l2tp_udp_recv_core(struct l2t + __skb_pull(skb, sizeof(struct udphdr)); + + /* Short packet? */ +- if (!pskb_may_pull(skb, L2TP_HDR_SIZE_SEQ)) { ++ if (!pskb_may_pull(skb, L2TP_HDR_SIZE_MAX)) { + l2tp_info(tunnel, L2TP_MSG_DATA, + "%s: recv short packet (len=%d)\n", + tunnel->name, skb->len); diff --git a/queue-3.18/l2tp-fix-reading-optional-fields-of-l2tpv3.patch b/queue-3.18/l2tp-fix-reading-optional-fields-of-l2tpv3.patch new file mode 100644 index 00000000000..05d28f26148 --- /dev/null +++ b/queue-3.18/l2tp-fix-reading-optional-fields-of-l2tpv3.patch @@ -0,0 +1,112 @@ +From foo@baz Sat Feb 2 10:57:42 CET 2019 +From: Jacob Wen +Date: Wed, 30 Jan 2019 14:55:14 +0800 +Subject: l2tp: fix reading optional fields of L2TPv3 + +From: Jacob Wen + +[ Upstream commit 4522a70db7aa5e77526a4079628578599821b193 ] + +Use pskb_may_pull() to make sure the optional fields are in skb linear +parts, so we can safely read them later. + +It's easy to reproduce the issue with a net driver that supports paged +skb data. Just create a L2TPv3 over IP tunnel and then generates some +network traffic. +Once reproduced, rx err in /sys/kernel/debug/l2tp/tunnels will increase. + +Changes in v4: +1. s/l2tp_v3_pull_opt/l2tp_v3_ensure_opt_in_linear/ +2. s/tunnel->version != L2TP_HDR_VER_2/tunnel->version == L2TP_HDR_VER_3/ +3. Add 'Fixes' in commit messages. + +Changes in v3: +1. To keep consistency, move the code out of l2tp_recv_common. +2. Use "net" instead of "net-next", since this is a bug fix. + +Changes in v2: +1. Only fix L2TPv3 to make code simple. + To fix both L2TPv3 and L2TPv2, we'd better refactor l2tp_recv_common. + It's complicated to do so. +2. Reloading pointers after pskb_may_pull + +Fixes: f7faffa3ff8e ("l2tp: Add L2TPv3 protocol support") +Fixes: 0d76751fad77 ("l2tp: Add L2TPv3 IP encapsulation (no UDP) support") +Fixes: a32e0eec7042 ("l2tp: introduce L2TPv3 IP encapsulation support for IPv6") +Signed-off-by: Jacob Wen +Acked-by: Guillaume Nault +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/l2tp/l2tp_core.c | 4 ++++ + net/l2tp/l2tp_core.h | 20 ++++++++++++++++++++ + net/l2tp/l2tp_ip.c | 3 +++ + net/l2tp/l2tp_ip6.c | 3 +++ + 4 files changed, 30 insertions(+) + +--- a/net/l2tp/l2tp_core.c ++++ b/net/l2tp/l2tp_core.c +@@ -926,6 +926,10 @@ static int l2tp_udp_recv_core(struct l2t + goto error; + } + ++ if (tunnel->version == L2TP_HDR_VER_3 && ++ l2tp_v3_ensure_opt_in_linear(session, skb, &ptr, &optr)) ++ goto error; ++ + l2tp_recv_common(session, skb, ptr, optr, hdrflags, length, payload_hook); + + return 0; +--- a/net/l2tp/l2tp_core.h ++++ b/net/l2tp/l2tp_core.h +@@ -323,6 +323,26 @@ static inline int l2tp_get_l2specific_le + } + } + ++static inline int l2tp_v3_ensure_opt_in_linear(struct l2tp_session *session, struct sk_buff *skb, ++ unsigned char **ptr, unsigned char **optr) ++{ ++ int opt_len = session->peer_cookie_len + l2tp_get_l2specific_len(session); ++ ++ if (opt_len > 0) { ++ int off = *ptr - *optr; ++ ++ if (!pskb_may_pull(skb, off + opt_len)) ++ return -1; ++ ++ if (skb->data != *optr) { ++ *optr = skb->data; ++ *ptr = skb->data + off; ++ } ++ } ++ ++ return 0; ++} ++ + #define l2tp_printk(ptr, type, func, fmt, ...) \ + do { \ + if (((ptr)->debug) & (type)) \ +--- a/net/l2tp/l2tp_ip.c ++++ b/net/l2tp/l2tp_ip.c +@@ -163,6 +163,9 @@ static int l2tp_ip_recv(struct sk_buff * + print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, ptr, length); + } + ++ if (l2tp_v3_ensure_opt_in_linear(session, skb, &ptr, &optr)) ++ goto discard; ++ + l2tp_recv_common(session, skb, ptr, optr, 0, skb->len, tunnel->recv_payload_hook); + + return 0; +--- a/net/l2tp/l2tp_ip6.c ++++ b/net/l2tp/l2tp_ip6.c +@@ -174,6 +174,9 @@ static int l2tp_ip6_recv(struct sk_buff + print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, ptr, length); + } + ++ if (l2tp_v3_ensure_opt_in_linear(session, skb, &ptr, &optr)) ++ goto discard; ++ + l2tp_recv_common(session, skb, ptr, optr, 0, skb->len, + tunnel->recv_payload_hook); + return 0; diff --git a/queue-3.18/l2tp-remove-l2specific_len-dependency-in-l2tp_core.patch b/queue-3.18/l2tp-remove-l2specific_len-dependency-in-l2tp_core.patch new file mode 100644 index 00000000000..7e82da2fe56 --- /dev/null +++ b/queue-3.18/l2tp-remove-l2specific_len-dependency-in-l2tp_core.patch @@ -0,0 +1,119 @@ +From 62e7b6a57c7b9bf3c6fd99418eeec05b08a85c38 Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Tue, 16 Jan 2018 23:01:55 +0100 +Subject: l2tp: remove l2specific_len dependency in l2tp_core + +From: Lorenzo Bianconi + +commit 62e7b6a57c7b9bf3c6fd99418eeec05b08a85c38 upstream. + +Remove l2specific_len dependency while building l2tpv3 header or +parsing the received frame since default L2-Specific Sublayer is +always four bytes long and we don't need to rely on a user supplied +value. +Moreover in l2tp netlink code there are no sanity checks to +enforce the relation between l2specific_len and l2specific_type, +so sending a malformed netlink message is possible to set +l2specific_type to L2TP_L2SPECTYPE_DEFAULT (or even +L2TP_L2SPECTYPE_NONE) and set l2specific_len to a value greater than +4 leaking memory on the wire and sending corrupted frames. + +Reviewed-by: Guillaume Nault +Tested-by: Guillaume Nault +Signed-off-by: Lorenzo Bianconi +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + net/l2tp/l2tp_core.c | 34 ++++++++++++++++------------------ + net/l2tp/l2tp_core.h | 11 +++++++++++ + 2 files changed, 27 insertions(+), 18 deletions(-) + +--- a/net/l2tp/l2tp_core.c ++++ b/net/l2tp/l2tp_core.c +@@ -700,11 +700,9 @@ void l2tp_recv_common(struct l2tp_sessio + "%s: recv data ns=%u, session nr=%u\n", + session->name, ns, session->nr); + } ++ ptr += 4; + } + +- /* Advance past L2-specific header, if present */ +- ptr += session->l2specific_len; +- + if (L2TP_SKB_CB(skb)->has_seq) { + /* Received a packet with sequence numbers. If we're the LNS, + * check if we sre sending sequence numbers and if not, +@@ -1026,21 +1024,20 @@ static int l2tp_build_l2tpv3_header(stru + memcpy(bufp, &session->cookie[0], session->cookie_len); + bufp += session->cookie_len; + } +- if (session->l2specific_len) { +- if (session->l2specific_type == L2TP_L2SPECTYPE_DEFAULT) { +- u32 l2h = 0; +- if (session->send_seq) { +- l2h = 0x40000000 | session->ns; +- session->ns++; +- session->ns &= 0xffffff; +- l2tp_dbg(session, L2TP_MSG_SEQ, +- "%s: updated ns to %u\n", +- session->name, session->ns); +- } ++ if (session->l2specific_type == L2TP_L2SPECTYPE_DEFAULT) { ++ u32 l2h = 0; + +- *((__be32 *) bufp) = htonl(l2h); ++ if (session->send_seq) { ++ l2h = 0x40000000 | session->ns; ++ session->ns++; ++ session->ns &= 0xffffff; ++ l2tp_dbg(session, L2TP_MSG_SEQ, ++ "%s: updated ns to %u\n", ++ session->name, session->ns); + } +- bufp += session->l2specific_len; ++ ++ *((__be32 *)bufp) = htonl(l2h); ++ bufp += 4; + } + if (session->offset) + bufp += session->offset; +@@ -1722,7 +1719,7 @@ int l2tp_session_delete(struct l2tp_sess + EXPORT_SYMBOL_GPL(l2tp_session_delete); + + /* We come here whenever a session's send_seq, cookie_len or +- * l2specific_len parameters are set. ++ * l2specific_type parameters are set. + */ + void l2tp_session_set_header_len(struct l2tp_session *session, int version) + { +@@ -1731,7 +1728,8 @@ void l2tp_session_set_header_len(struct + if (session->send_seq) + session->hdr_len += 4; + } else { +- session->hdr_len = 4 + session->cookie_len + session->l2specific_len + session->offset; ++ session->hdr_len = 4 + session->cookie_len + session->offset; ++ session->hdr_len += l2tp_get_l2specific_len(session); + if (session->tunnel->encap == L2TP_ENCAPTYPE_UDP) + session->hdr_len += 4; + } +--- a/net/l2tp/l2tp_core.h ++++ b/net/l2tp/l2tp_core.h +@@ -312,6 +312,17 @@ do { \ + #define l2tp_session_dec_refcount(s) l2tp_session_dec_refcount_1(s) + #endif + ++static inline int l2tp_get_l2specific_len(struct l2tp_session *session) ++{ ++ switch (session->l2specific_type) { ++ case L2TP_L2SPECTYPE_DEFAULT: ++ return 4; ++ case L2TP_L2SPECTYPE_NONE: ++ default: ++ return 0; ++ } ++} ++ + #define l2tp_printk(ptr, type, func, fmt, ...) \ + do { \ + if (((ptr)->debug) & (type)) \ diff --git a/queue-3.18/net-rose-fix-null-ax25_cb-kernel-panic.patch b/queue-3.18/net-rose-fix-null-ax25_cb-kernel-panic.patch new file mode 100644 index 00000000000..33e6ad2f7fb --- /dev/null +++ b/queue-3.18/net-rose-fix-null-ax25_cb-kernel-panic.patch @@ -0,0 +1,66 @@ +From foo@baz Sat Feb 2 11:44:37 CET 2019 +From: Bernard Pidoux +Date: Fri, 25 Jan 2019 11:46:40 +0100 +Subject: net/rose: fix NULL ax25_cb kernel panic + +From: Bernard Pidoux + +[ Upstream commit b0cf029234f9b18e10703ba5147f0389c382bccc ] + +When an internally generated frame is handled by rose_xmit(), +rose_route_frame() is called: + + if (!rose_route_frame(skb, NULL)) { + dev_kfree_skb(skb); + stats->tx_errors++; + return NETDEV_TX_OK; + } + +We have the same code sequence in Net/Rom where an internally generated +frame is handled by nr_xmit() calling nr_route_frame(skb, NULL). +However, in this function NULL argument is tested while it is not in +rose_route_frame(). +Then kernel panic occurs later on when calling ax25cmp() with a NULL +ax25_cb argument as reported many times and recently with syzbot. + +We need to test if ax25 is NULL before using it. + +Testing: +Built kernel with CONFIG_ROSE=y. + +Signed-off-by: Bernard Pidoux +Acked-by: Dmitry Vyukov +Reported-by: syzbot+1a2c456a1ea08fa5b5f7@syzkaller.appspotmail.com +Cc: "David S. Miller" +Cc: Ralf Baechle +Cc: Bernard Pidoux +Cc: linux-hams@vger.kernel.org +Cc: netdev@vger.kernel.org +Cc: linux-kernel@vger.kernel.org +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/rose/rose_route.c | 5 +++++ + 1 file changed, 5 insertions(+) + +--- a/net/rose/rose_route.c ++++ b/net/rose/rose_route.c +@@ -849,6 +849,7 @@ void rose_link_device_down(struct net_de + + /* + * Route a frame to an appropriate AX.25 connection. ++ * A NULL ax25_cb indicates an internally generated frame. + */ + int rose_route_frame(struct sk_buff *skb, ax25_cb *ax25) + { +@@ -866,6 +867,10 @@ int rose_route_frame(struct sk_buff *skb + + if (skb->len < ROSE_MIN_LEN) + return res; ++ ++ if (!ax25) ++ return rose_loopback_queue(skb, NULL); ++ + frametype = skb->data[2]; + lci = ((skb->data[0] << 8) & 0xF00) + ((skb->data[1] << 0) & 0x0FF); + if (frametype == ROSE_CALL_REQUEST && diff --git a/queue-3.18/netrom-switch-to-sock-timer-api.patch b/queue-3.18/netrom-switch-to-sock-timer-api.patch new file mode 100644 index 00000000000..11bff83bc3e --- /dev/null +++ b/queue-3.18/netrom-switch-to-sock-timer-api.patch @@ -0,0 +1,95 @@ +From foo@baz Sat Feb 2 11:44:37 CET 2019 +From: Cong Wang +Date: Thu, 24 Jan 2019 14:18:18 -0800 +Subject: netrom: switch to sock timer API + +From: Cong Wang + +[ Upstream commit 63346650c1a94a92be61a57416ac88c0a47c4327 ] + +sk_reset_timer() and sk_stop_timer() properly handle +sock refcnt for timer function. Switching to them +could fix a refcounting bug reported by syzbot. + +Reported-and-tested-by: syzbot+defa700d16f1bd1b9a05@syzkaller.appspotmail.com +Cc: Ralf Baechle +Cc: linux-hams@vger.kernel.org +Signed-off-by: Cong Wang +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/netrom/nr_timer.c | 20 ++++++++++---------- + 1 file changed, 10 insertions(+), 10 deletions(-) + +--- a/net/netrom/nr_timer.c ++++ b/net/netrom/nr_timer.c +@@ -53,21 +53,21 @@ void nr_start_t1timer(struct sock *sk) + { + struct nr_sock *nr = nr_sk(sk); + +- mod_timer(&nr->t1timer, jiffies + nr->t1); ++ sk_reset_timer(sk, &nr->t1timer, jiffies + nr->t1); + } + + void nr_start_t2timer(struct sock *sk) + { + struct nr_sock *nr = nr_sk(sk); + +- mod_timer(&nr->t2timer, jiffies + nr->t2); ++ sk_reset_timer(sk, &nr->t2timer, jiffies + nr->t2); + } + + void nr_start_t4timer(struct sock *sk) + { + struct nr_sock *nr = nr_sk(sk); + +- mod_timer(&nr->t4timer, jiffies + nr->t4); ++ sk_reset_timer(sk, &nr->t4timer, jiffies + nr->t4); + } + + void nr_start_idletimer(struct sock *sk) +@@ -75,37 +75,37 @@ void nr_start_idletimer(struct sock *sk) + struct nr_sock *nr = nr_sk(sk); + + if (nr->idle > 0) +- mod_timer(&nr->idletimer, jiffies + nr->idle); ++ sk_reset_timer(sk, &nr->idletimer, jiffies + nr->idle); + } + + void nr_start_heartbeat(struct sock *sk) + { +- mod_timer(&sk->sk_timer, jiffies + 5 * HZ); ++ sk_reset_timer(sk, &sk->sk_timer, jiffies + 5 * HZ); + } + + void nr_stop_t1timer(struct sock *sk) + { +- del_timer(&nr_sk(sk)->t1timer); ++ sk_stop_timer(sk, &nr_sk(sk)->t1timer); + } + + void nr_stop_t2timer(struct sock *sk) + { +- del_timer(&nr_sk(sk)->t2timer); ++ sk_stop_timer(sk, &nr_sk(sk)->t2timer); + } + + void nr_stop_t4timer(struct sock *sk) + { +- del_timer(&nr_sk(sk)->t4timer); ++ sk_stop_timer(sk, &nr_sk(sk)->t4timer); + } + + void nr_stop_idletimer(struct sock *sk) + { +- del_timer(&nr_sk(sk)->idletimer); ++ sk_stop_timer(sk, &nr_sk(sk)->idletimer); + } + + void nr_stop_heartbeat(struct sock *sk) + { +- del_timer(&sk->sk_timer); ++ sk_stop_timer(sk, &sk->sk_timer); + } + + int nr_t1timer_running(struct sock *sk) diff --git a/queue-3.18/series b/queue-3.18/series index ef05f14f52e..0e7f0b81c78 100644 --- a/queue-3.18/series +++ b/queue-3.18/series @@ -14,3 +14,10 @@ vt-invoke-notifier-on-screen-size-change.patch perf-unwind-unwind-with-libdw-doesn-t-take-symfs-int.patch perf-unwind-take-pgoff-into-account-when-reporting-e.patch f2fs-read-page-index-before-freeing.patch +ipv6-consider-sk_bound_dev_if-when-binding-a-socket-to-an-address.patch +l2tp-copy-4-more-bytes-to-linear-part-if-necessary.patch +netrom-switch-to-sock-timer-api.patch +net-rose-fix-null-ax25_cb-kernel-panic.patch +ucc_geth-reset-bql-queue-when-stopping-device.patch +l2tp-remove-l2specific_len-dependency-in-l2tp_core.patch +l2tp-fix-reading-optional-fields-of-l2tpv3.patch diff --git a/queue-3.18/ucc_geth-reset-bql-queue-when-stopping-device.patch b/queue-3.18/ucc_geth-reset-bql-queue-when-stopping-device.patch new file mode 100644 index 00000000000..26d844e0624 --- /dev/null +++ b/queue-3.18/ucc_geth-reset-bql-queue-when-stopping-device.patch @@ -0,0 +1,33 @@ +From foo@baz Sat Feb 2 11:44:37 CET 2019 +From: Mathias Thore +Date: Mon, 28 Jan 2019 10:07:47 +0100 +Subject: ucc_geth: Reset BQL queue when stopping device + +From: Mathias Thore + +[ Upstream commit e15aa3b2b1388c399c1a2ce08550d2cc4f7e3e14 ] + +After a timeout event caused by for example a broadcast storm, when +the MAC and PHY are reset, the BQL TX queue needs to be reset as +well. Otherwise, the device will exhibit severe performance issues +even after the storm has ended. + +Co-authored-by: David Gounaris +Signed-off-by: Mathias Thore +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/freescale/ucc_geth.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/net/ethernet/freescale/ucc_geth.c ++++ b/drivers/net/ethernet/freescale/ucc_geth.c +@@ -1882,6 +1882,8 @@ static void ucc_geth_free_tx(struct ucc_ + u16 i, j; + u8 __iomem *bd; + ++ netdev_reset_queue(ugeth->ndev); ++ + ug_info = ugeth->ug_info; + uf_info = &ug_info->uf_info; +