commit
8f659a03a0ba9289b9aeb9b4470e6fb263d6f483 upstream.
inet->hdrincl is racy, and could lead to uninitialized stack pointer
usage, so its value should be read only once.
Fixes:
c008ba5bdc9f ("ipv4: Avoid reading user iov twice after raw_probe_proto_opt")
Signed-off-by: Mohamed Ghannam <simo.ghannam@gmail.com>
Reviewed-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
[bwh: Backported to 3.2:
- flowi4 flags don't depend on hdrincl
- Adjust context]
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
int err;
struct ip_options_data opt_copy;
struct raw_frag_vec rfv;
int err;
struct ip_options_data opt_copy;
struct raw_frag_vec rfv;
err = -EMSGSIZE;
if (len > 0xFFFF)
goto out;
err = -EMSGSIZE;
if (len > 0xFFFF)
goto out;
+ /* hdrincl should be READ_ONCE(inet->hdrincl)
+ * but READ_ONCE() doesn't work with bit fields
+ */
+ hdrincl = inet->hdrincl;
/* Linux does not mangle headers on raw sockets,
* so that IP options + IP_HDRINCL is non-sense.
*/
/* Linux does not mangle headers on raw sockets,
* so that IP options + IP_HDRINCL is non-sense.
*/
goto done;
if (ipc.opt->opt.srr) {
if (!daddr)
goto done;
if (ipc.opt->opt.srr) {
if (!daddr)
flowi4_init_output(&fl4, ipc.oif, sk->sk_mark, tos,
RT_SCOPE_UNIVERSE,
flowi4_init_output(&fl4, ipc.oif, sk->sk_mark, tos,
RT_SCOPE_UNIVERSE,
- inet->hdrincl ? IPPROTO_RAW : sk->sk_protocol,
+ hdrincl ? IPPROTO_RAW : sk->sk_protocol,
inet_sk_flowi_flags(sk) | FLOWI_FLAG_CAN_SLEEP,
daddr, saddr, 0, 0);
inet_sk_flowi_flags(sk) | FLOWI_FLAG_CAN_SLEEP,
daddr, saddr, 0, 0);
rfv.iov = msg->msg_iov;
rfv.hlen = 0;
rfv.iov = msg->msg_iov;
rfv.hlen = 0;
goto do_confirm;
back_from_confirm:
goto do_confirm;
back_from_confirm:
err = raw_send_hdrinc(sk, &fl4, msg->msg_iov, len,
&rt, msg->msg_flags);
err = raw_send_hdrinc(sk, &fl4, msg->msg_iov, len,
&rt, msg->msg_flags);