summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMattias Jernberg <mattiasj@axis.com>2022-09-29 18:37:13 +0200
committerRichard Purdie <richard.purdie@linuxfoundation.org>2022-09-29 21:26:04 +0100
commit0d317209d4234c5f05a9fcdc13c52f502f104018 (patch)
tree0474370065750fc6ec58c3e1023b1e4c5bec8a7a
parentc014281f72f4f54ec8e681ef2b8e1080de9ab5cf (diff)
downloadbitbake-0d317209d4234c5f05a9fcdc13c52f502f104018.tar.gz
utils: Add enable_loopback_networking()
It can be used to enable the loopback interface, typically after calling disable_network(). Also correct a typo in a debug message. Signed-off-by: Mattias Jernberg <mattias.jernberg@axis.com> Signed-off-by: Peter Kjellerstedt <peter.kjellerstedt@axis.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
-rw-r--r--lib/bb/utils.py42
1 files changed, 41 insertions, 1 deletions
diff --git a/lib/bb/utils.py b/lib/bb/utils.py
index 92d44c526..e6e21e20f 100644
--- a/lib/bb/utils.py
+++ b/lib/bb/utils.py
@@ -29,6 +29,8 @@ import collections
import copy
import ctypes
import random
+import socket
+import struct
import tempfile
from subprocess import getstatusoutput
from contextlib import contextmanager
@@ -1603,6 +1605,44 @@ def set_process_name(name):
except:
pass
+def enable_loopback_networking():
+ # From bits/ioctls.h
+ SIOCGIFFLAGS = 0x8913
+ SIOCSIFFLAGS = 0x8914
+ SIOCSIFADDR = 0x8916
+ SIOCSIFNETMASK = 0x891C
+
+ # if.h
+ IFF_UP = 0x1
+ IFF_RUNNING = 0x40
+
+ # bits/socket.h
+ AF_INET = 2
+
+ # char ifr_name[IFNAMSIZ=16]
+ ifr_name = struct.pack("@16s", b"lo")
+ def netdev_req(fd, req, data = b""):
+ # Pad and add interface name
+ data = ifr_name + data + (b'\x00' * (16 - len(data)))
+ # Return all data after interface name
+ return fcntl.ioctl(fd, req, data)[16:]
+
+ with socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_IP) as sock:
+ fd = sock.fileno()
+
+ # struct sockaddr_in ifr_addr { unsigned short family; uint16_t sin_port ; uint32_t in_addr; }
+ req = struct.pack("@H", AF_INET) + struct.pack("=H4B", 0, 127, 0, 0, 1)
+ netdev_req(fd, SIOCSIFADDR, req)
+
+ # short ifr_flags
+ flags = struct.unpack_from('@h', netdev_req(fd, SIOCGIFFLAGS))[0]
+ flags |= IFF_UP | IFF_RUNNING
+ netdev_req(fd, SIOCSIFFLAGS, struct.pack('@h', flags))
+
+ # struct sockaddr_in ifr_netmask
+ req = struct.pack("@H", AF_INET) + struct.pack("=H4B", 0, 255, 0, 0, 0)
+ netdev_req(fd, SIOCSIFNETMASK, req)
+
def disable_network(uid=None, gid=None):
"""
Disable networking in the current process if the kernel supports it, else
@@ -1624,7 +1664,7 @@ def disable_network(uid=None, gid=None):
ret = libc.unshare(CLONE_NEWNET | CLONE_NEWUSER)
if ret != 0:
- logger.debug("System doesn't suport disabling network without admin privs")
+ logger.debug("System doesn't support disabling network without admin privs")
return
with open("/proc/self/uid_map", "w") as f:
f.write("%s %s 1" % (uid, uid))