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>] [day] [month] [year] [list]
Date:   Fri, 19 Mar 2021 08:58:01 +0100
From:   "Riccardo Paolo Bestetti" <pbl@...tov.io>
To:     <netdev@...r.kernel.org>
Subject: IP_FREEBIND not working with SOCK_RAW socket

Hey,

I noticed that the IP_FREEBIND socket option doesn't work with the
SOCK_RAW socket type, nor does the net.ipv4.ip_nonlocal_bind kernel
parameter. When attempting to bind a nonlocal address to such a socket,
EADDRNOTAVAIL is returned.

I briefly adventured into the Kernel Source in search of insights, but
soon got lost in the Dark Forest of The Structs and had to get rescued.

I've attach below a small program to reproduce the issue. It gives no
output whatsoever, so you might want to run it through strace.

You should attempt to run it with an actual local address to observe it
works:
# strace ./a.out 127.0.0.1

And then run it with a nonlocal address to observe it doesn't work both
without (ok) or with (not ok?) the IP_FREEBIND socket option:
# strace ./a.out 8.8.8.8
# strace ./a.out 8.8.8.8 freebind

Any insights?

Riccardo P. Bestetti
--

#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <arpa/inet.h>

int main (int argc, char** argv) {
  char src[16];
  unsigned int freebind = 0;

  if (argc < 2) {
    fprintf(stderr, "Usage: out.a ADDR [ freebind ]\n");
    return 1;
  }

  strncpy(src, argv[1], 16);
  src[15] = 0;

  if (argc >= 3 && strcmp(argv[2], "freebind") == 0)
    freebind = 1;

  struct sockaddr_in bind_addr;
  socklen_t laddrlen = sizeof(bind_addr);
  memset(&bind_addr, 0, laddrlen);
  bind_addr.sin_family = AF_INET;
  bind_addr.sin_port = htons(IPPROTO_GRE);
  inet_pton(AF_INET, src, &bind_addr.sin_addr);

  int fd = socket(AF_INET, SOCK_RAW, IPPROTO_GRE);
  setsockopt(fd, IPPROTO_IP, IP_FREEBIND, &freebind, sizeof(freebind));
  bind(fd, (struct sockaddr *)&bind_addr, laddrlen);

  return 0;
}


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ