Skip to content

Commit

Permalink
major cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
netblue30 committed Oct 30, 2016
1 parent 2ef5a3d commit f898290
Show file tree
Hide file tree
Showing 30 changed files with 869 additions and 889 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,5 @@ src/ftee/ftee
src/tags
src/faudit/faudit
src/fnet/fnet
src/fseccomp/fseccomp
uids.h
2 changes: 2 additions & 0 deletions README
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,8 @@ valoq (https://github.com/valoq)
- added support for /srv in --whitelist feature
- Eye of GNOME and Evolution profiles
- blacklist suid binaries in disable-common.inc
Vadim A. Misbakh-Soloviov (https://github.com/msva)
- profile fixes
Rafael Cavalcanti (https://github.com/rccavalcanti)
- chromium profile fixes for Arch Linux
Deelvesh Bunjun (https://github.com/DeelveshBunjun)
Expand Down
5 changes: 0 additions & 5 deletions src/firejail/appimage.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,11 +60,6 @@ void appimage_set(const char *appimage_path) {
exit(1);
}

// populate /run/firejail directory
EUID_ROOT();
fs_build_firejail_dir();
EUID_USER();

// find or allocate a free loop device to use
EUID_ROOT();
int cfd = open("/dev/loop-control", O_RDWR);
Expand Down
186 changes: 1 addition & 185 deletions src/firejail/arp.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ typedef struct arp_hdr_t {
uint8_t target_ip[4];
} ArpHdr;


// returns 0 if the address is not in use, -1 otherwise
int arp_check(const char *dev, uint32_t destaddr, uint32_t srcaddr) {
if (strlen(dev) > IFNAMSIZ) {
Expand Down Expand Up @@ -286,189 +287,4 @@ uint32_t arp_assign(const char *dev, Bridge *br) {
return ip;
}

// scan interface (--scan option)
void arp_scan(const char *dev, uint32_t ifip, uint32_t ifmask) {
assert(dev);
assert(ifip);

// printf("Scanning interface %s (%d.%d.%d.%d/%d)\n",
// dev, PRINT_IP(ifip & ifmask), mask2bits(ifmask));

if (strlen(dev) > IFNAMSIZ) {
fprintf(stderr, "Error: invalid network device name %s\n", dev);
exit(1);
}

// find interface mac address
int sock;
if ((sock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0)
errExit("socket");
struct ifreq ifr;
memset(&ifr, 0, sizeof (ifr));
strncpy(ifr.ifr_name, dev, IFNAMSIZ);
if (ioctl(sock, SIOCGIFHWADDR, &ifr) < 0)
errExit("ioctl");
close(sock);
uint8_t mac[6];
memcpy (mac, ifr.ifr_hwaddr.sa_data, 6);

// open layer2 socket
if ((sock = socket(PF_PACKET, SOCK_RAW, htons (ETH_P_ALL))) < 0)
errExit("socket");

// try all possible ip addresses in ascending order
uint32_t range = ~ifmask + 1; // the number of potential addresses
// this software is not supported for /31 networks
if (range < 4) {
fprintf(stderr, "Warning: this option is not supported for /31 networks\n");
close(sock);
return;
}

uint32_t dest = (ifip & ifmask) + 1;
uint32_t last = dest + range - 1;
uint32_t src = htonl(ifip);

// wait not more than one second for an answer
int header_printed = 0;
uint32_t last_ip = 0;
struct timeval ts;
ts.tv_sec = 2; // 2 seconds receive timeout
ts.tv_usec = 0;

while (1) {
fd_set rfds;
FD_ZERO(&rfds);
FD_SET(sock, &rfds);
fd_set wfds;
FD_ZERO(&wfds);
FD_SET(sock, &wfds);
int maxfd = sock;

uint8_t frame[ETH_FRAME_LEN]; // includes eht header, vlan, and crc
memset(frame, 0, ETH_FRAME_LEN);

int nready;
if (dest < last)
nready = select(maxfd + 1, &rfds, &wfds, (fd_set *) 0, NULL);
else
nready = select(maxfd + 1, &rfds, (fd_set *) 0, (fd_set *) 0, &ts);

if (nready < 0)
errExit("select");

if (nready == 0) { // timeout
break;
}

if (FD_ISSET(sock, &wfds) && dest < last) {
// configure layer2 socket address information
struct sockaddr_ll addr;
memset(&addr, 0, sizeof(addr));
if ((addr.sll_ifindex = if_nametoindex(dev)) == 0)
errExit("if_nametoindex");
addr.sll_family = AF_PACKET;
memcpy (addr.sll_addr, mac, 6);
addr.sll_halen = htons(6);

// build the arp packet header
ArpHdr hdr;
memset(&hdr, 0, sizeof(hdr));
hdr.htype = htons(1);
hdr.ptype = htons(ETH_P_IP);
hdr.hlen = 6;
hdr.plen = 4;
hdr.opcode = htons(1); //ARPOP_REQUEST
memcpy(hdr.sender_mac, mac, 6);
memcpy(hdr.sender_ip, (uint8_t *)&src, 4);
uint32_t dst = htonl(dest);
memcpy(hdr.target_ip, (uint8_t *)&dst, 4);

// build ethernet frame
uint8_t frame[ETH_FRAME_LEN]; // includes eht header, vlan, and crc
memset(frame, 0, sizeof(frame));
frame[0] = frame[1] = frame[2] = frame[3] = frame[4] = frame[5] = 0xff;
memcpy(frame + 6, mac, 6);
frame[12] = ETH_P_ARP / 256;
frame[13] = ETH_P_ARP % 256;
memcpy (frame + 14, &hdr, sizeof(hdr));

// send packet
int len;
if ((len = sendto (sock, frame, 14 + sizeof(ArpHdr), 0, (struct sockaddr *) &addr, sizeof (addr))) <= 0)
errExit("send");
//printf("send %d bytes to %d.%d.%d.%d\n", len, PRINT_IP(dest));
fflush(0);
dest++;
}

if (FD_ISSET(sock, &rfds)) {
// read the incoming packet
int len = recvfrom(sock, frame, ETH_FRAME_LEN, 0, NULL, NULL);
if (len < 0) {
perror("recvfrom");
}

// parse the incoming packet
if ((unsigned int) len < 14 + sizeof(ArpHdr))
continue;

// look only at ARP packets
if (frame[12] != (ETH_P_ARP / 256) || frame[13] != (ETH_P_ARP % 256))
continue;

ArpHdr hdr;
memcpy(&hdr, frame + 14, sizeof(ArpHdr));

if (hdr.opcode == htons(2)) {
// check my mac and my address
if (memcmp(mac, hdr.target_mac, 6) != 0)
continue;
uint32_t ip;
memcpy(&ip, hdr.target_ip, 4);
if (ip != src)
continue;
memcpy(&ip, hdr.sender_ip, 4);
ip = ntohl(ip);

if (ip == last_ip) // filter duplicates
continue;
last_ip = ip;

// printing
if (header_printed == 0) {
printf(" Network scan:\n");

// print parent interface
if (cfg.bridge0.configured && cfg.bridge0.ip && cfg.bridge0.macvlan &&
(cfg.bridge0.ip & cfg.bridge0.mask) == (ifip & cfg.bridge0.mask))
printf(" %02x:%02x:%02x:%02x:%02x:%02x\t%d.%d.%d.%d\n",
PRINT_MAC(cfg.bridge0.mac), PRINT_IP(cfg.bridge0.ip));

if (cfg.bridge1.configured && cfg.bridge1.ip && cfg.bridge1.macvlan &&
(cfg.bridge1.ip & cfg.bridge1.mask) == (ifip & cfg.bridge1.mask))
printf(" %02x:%02x:%02x:%02x:%02x:%02x\t%d.%d.%d.%d\n",
PRINT_MAC(cfg.bridge1.mac), PRINT_IP(cfg.bridge1.ip));

if (cfg.bridge2.configured && cfg.bridge2.ip && cfg.bridge2.macvlan &&
(cfg.bridge2.ip & cfg.bridge2.mask) == (ifip & cfg.bridge2.mask))
printf(" %02x:%02x:%02x:%02x:%02x:%02x\t%d.%d.%d.%d\n",
PRINT_MAC(cfg.bridge2.mac), PRINT_IP(cfg.bridge2.ip));

if (cfg.bridge3.configured && cfg.bridge3.ip && cfg.bridge3.macvlan &&
(cfg.bridge3.ip & cfg.bridge3.mask) == (ifip & cfg.bridge3.mask))
printf(" %02x:%02x:%02x:%02x:%02x:%02x\t%d.%d.%d.%d\n",
PRINT_MAC(cfg.bridge3.mac), PRINT_IP(cfg.bridge3.ip));

header_printed = 1;
}
printf(" %02x:%02x:%02x:%02x:%02x:%02x\t%d.%d.%d.%d\n",
PRINT_MAC(hdr.sender_mac), PRINT_IP(ip));
}
}
}

close(sock);
}


31 changes: 15 additions & 16 deletions src/firejail/firejail.h
Original file line number Diff line number Diff line change
Expand Up @@ -363,20 +363,19 @@ void net_if_ip(const char *ifname, uint32_t ip, uint32_t mask, int mtu);
void net_if_ip6(const char *ifname, const char *addr6);
int net_get_if_addr(const char *bridge, uint32_t *ip, uint32_t *mask, uint8_t mac[6], int *mtu);
int net_add_route(uint32_t dest, uint32_t mask, uint32_t gw);
void net_ifprint(void);
uint32_t network_get_defaultgw(void);
int net_config_mac(const char *ifname, const unsigned char mac[6]);
int net_get_mac(const char *ifname, unsigned char mac[6]);
void net_config_interface(const char *dev, uint32_t ip, uint32_t mask, int mtu);

// preproc.c
void preproc_build_firejail_dir(void);
void preproc_mount_mnt_dir(void);
void preproc_build_cp_command(void);
void preproc_delete_cp_command(void) ;
void preproc_remount_mnt_dir(void);

// fs.c
// build /run/firejail directory
void fs_build_firejail_dir(void);
// build /run/firejail/mnt directory
void fs_build_mnt_dir(void);
// grab a copy of cp command
void fs_build_cp_command(void);
// delete the temporary cp command
void fs_delete_cp_command(void) ;
// blacklist files or directoies by mounting empty files on top of them
void fs_blacklist(void);
// remount a directory read-only
Expand All @@ -393,7 +392,6 @@ void fs_overlayfs(void);
// chroot into an existing directory; mount exiting /dev and update /etc/resolv.conf
void fs_chroot(const char *rootdir);
int fs_check_chroot_dir(const char *rootdir);
void fs_private_tmp(void);

// profile.c
// find and read the profile specified by name from dir directory
Expand Down Expand Up @@ -430,8 +428,6 @@ int restricted_shell(const char *user);
int arp_check(const char *dev, uint32_t destaddr, uint32_t srcaddr);
// assign an IP address using arp scanning
uint32_t arp_assign(const char *dev, Bridge *br);
// scan interface (--scan option)
void arp_scan(const char *dev, uint32_t srcaddr, uint32_t srcmask);

// util.c
void drop_privs(int nogroups);
Expand Down Expand Up @@ -459,6 +455,8 @@ void invalid_filename(const char *fname);
uid_t get_group_id(const char *group);
int remove_directory(const char *path);
void flush_stdin(void);
void create_empty_dir_as_root(const char *dir, mode_t mode);
void create_empty_file_as_root(const char *dir, mode_t mode);

// fs_var.c
void fs_var_log(void); // mounting /var/log
Expand Down Expand Up @@ -687,10 +685,11 @@ void build_cmdline(char **command_line, char **window_title, int argc, char **ar
#define PATH_FIREMON (PREFIX "/bin/firemon")
#define PATH_FSECCOMP (LIBDIR "/firejail/fseccomp")
// bitmapped filters for sbox_run
#define SBOX_ROOT 1
#define SBOX_USER 2
#define SBOX_CAPS 4
#define SBOX_SECCOMP 8
#define SBOX_ROOT (1 << 0)
#define SBOX_USER (1 << 1)
#define SBOX_SECCOMP (1 << 2)
#define SBOX_CAPS_NONE (1 << 3) // drop all capabilities
#define SBOX_CAPS_NETWORK (1 << 4) // caps filter for programs running network programs
// run sbox
int sbox_run(unsigned filter, int num, ...);

Expand Down
Loading

0 comments on commit f898290

Please sign in to comment.