¿Por qué no puedo crear un socket sin formato en Ubuntu?

3 minutos de lectura

¿Por que no puedo crear un socket sin formato en
encantador

Estoy aprendiendo a trabajar con sockets sin procesar en Linux. Estoy tratando de crear un socket como ese:

if ((sd = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP)) < 0) {
    perror("socket() failed");
    exit(-1);
}

Pero todo lo que obtuve después del lanzamiento es:

socket () falló: operación no permitida

Sé que solo la raíz puede crear sockets sin procesar, pero si lo ejecuto con SUID bit o Sudo, el problema es el mismo. ¿Qué ocurre? El sistema es Ubuntu 11.04.

¿Quizás estoy incluyendo encabezados innecesarios?

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/ip.h>
#include <netinet/ip_icmp.h>
#include <netdb.h>
#include <sys/time.h>
#include <signal.h>
#include <unistd.h>

Y me pregunto: ¿por qué SUID es inútil?

  • interesante; ¿Trató de ser realmente root? (¿y los privilegios marcados no se eliminan antes de ejecutar esa línea?)

    – ShinTakezou

    26 de julio de 2011 a las 7:02

  • no, solo llamo a setuid(getuid()); justo después de la creación del socket, pero ni siquiera llega a eso.

    – Encantador

    26 de julio de 2011 a las 7:07

  • si lo hace: sudo bash (o sudo any-shell-you-use) y luego ejecuta el programa…? ¿Funciona?

    – ShinTakezou

    26 de julio de 2011 a las 7:09

  • Hmm, sí, funciona de esta manera. Pero, ¿por qué suid es inútil?

    – Encantador

    26 de julio de 2011 a las 7:19

  • ¿Has intentado hacer seteuid — el bit setuid en el programa no establece el uid efectivo, y es posible que deba establecerse programáticamente.

    – Sorén

    26 de julio de 2011 a las 7:25


1647734287 505 ¿Por que no puedo crear un socket sin formato en
NPE

Mi dinero es que no ejecutas tu código correctamente.

He copiado y pegado tu código exacto en un vacío main(). Recibo el mismo error si lo ejecuto como yo mismo, pero se ejecuta correctamente bajo sudo. Esto es en Ubuntu.

El código:

#include <sys/socket.h>
#include <netinet/in.h>

int main()
{ 
  int sd;
  if ((sd = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP)) < 0) {
    perror("socket() failed");
    return -1;
  }
  return 0;
} 

Ejecutar como yo mismo:

[email protected]:~$ ./a.out 
socket() failed: Operation not permitted
[email protected]:~$

Ejecutar como root:

[email protected]:~$ sudo ./a.out 
[email protected]:~$

  • Su código también funciona perfectamente. Pero mi código difiere del tuyo solo por los encabezados. He incluido todas esas cosas (agregado en cuestión).

    – Encantador

    26 de julio de 2011 a las 7:25

  • lo que los sudoers pueden hacer de verdad es configurable; ¿Es posible que el valor predeterminado de ubuntu 11 para sudoers no sea proporcionar un usuario real con raíz?

    – ShinTakezou

    26 de julio de 2011 a las 9:04

  • Me ahorró bastante tiempo. NPE muy apreciada.

    – Mizmor

    3 de diciembre de 2013 a las 15:04

según man: solo los procesos con una identificación de usuario efectiva de 0 o la capacidad CAP_NET_RAW pueden abrir sockets sin formato

Por lo tanto, puede ejecutar su aplicación con sudo como se sugiere a continuación o configurar la capacidad CAP_NET_RAW (en realidad, también necesitará CAP_NET_ADMIN):

# setcap cap_net_raw,cap_net_admin=eip PATH_TO_YOUR_APPLICATION

Los detalles se pueden encontrar en http://ftp.kernel.org/pub/linux/libs/security/linux-privs/kernel-2.4/capfaq-0.2.txt

El encabezado no lo afectará de ninguna manera.

Incluso si agregara más archivos innecesarios, no afectará el funcionamiento del programa.

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad