summaryrefslogtreecommitdiff
path: root/libshouldbeinlibc
diff options
context:
space:
mode:
authorSamuel Thibault <samuel.thibault@ens-lyon.org>2022-01-04 01:25:04 +0100
committerSamuel Thibault <samuel.thibault@ens-lyon.org>2022-01-04 01:25:04 +0100
commit6bbb65d6885eba9ac380757515a21ae9cca62727 (patch)
treeeb85f6c557523d3055aa0e0dedd651748ec2827a /libshouldbeinlibc
parentd60191077b494d6a60181dd4967fe9dafa7003cc (diff)
portinfo: Use benign RPCs to discover what ports are all about
Most servers have at least one RPC which is benign enough to be used to identify whether a port supports the server and provides some useful information to identify what the port is about. This adds support for most of these, allowing to identify auth ports, file descriptors, sockets, etc.
Diffstat (limited to 'libshouldbeinlibc')
-rw-r--r--libshouldbeinlibc/portinfo.c445
1 files changed, 419 insertions, 26 deletions
diff --git a/libshouldbeinlibc/portinfo.c b/libshouldbeinlibc/portinfo.c
index f3c540f5..de087de9 100644
--- a/libshouldbeinlibc/portinfo.c
+++ b/libshouldbeinlibc/portinfo.c
@@ -19,6 +19,18 @@
#include <sys/types.h>
#include <sys/mman.h>
+#include <arpa/inet.h>
+#include <sys/un.h>
+
+#include <mach/default_pager.h>
+#include <hurd/fsys.h>
+#include <hurd/msg.h>
+#include <hurd/pci.h>
+#include <hurd/process.h>
+#include <hurd/socket.h>
+#include <hurd/term.h>
+#include <hurd/tioctl.h>
+#include <hurd.h>
#include "portinfo.h"
@@ -30,7 +42,7 @@ print_port_info (mach_port_t name, mach_port_type_t type, task_t task,
unsigned show, FILE *stream)
{
int hex_names = (show & PORTINFO_HEX_NAMES);
- int first = 1;
+ int first = 1, subfirst = 1;
void comma ()
{
if (first)
@@ -38,6 +50,13 @@ print_port_info (mach_port_t name, mach_port_type_t type, task_t task,
else
fprintf (stream, ", ");
}
+ void subcomma ()
+ {
+ if (subfirst)
+ subfirst = 0;
+ else
+ fprintf (stream, ",");
+ }
void prefs (mach_port_right_t right)
{
mach_port_urefs_t refs;
@@ -59,7 +78,397 @@ print_port_info (mach_port_t name, mach_port_type_t type, task_t task,
{
comma ();
fprintf (stream, "receive");
- if (show & PORTINFO_DETAILS)
+ }
+ if (type & MACH_PORT_TYPE_SEND)
+ {
+ comma ();
+ fprintf (stream, "send");
+ }
+ if (type & MACH_PORT_TYPE_SEND_ONCE)
+ {
+ comma ();
+ fprintf (stream, "send-once");
+ }
+ if (type & MACH_PORT_TYPE_DEAD_NAME)
+ {
+ comma ();
+ fprintf (stream, "dead-name");
+ }
+ if (type & MACH_PORT_TYPE_PORT_SET)
+ {
+ comma ();
+ fprintf (stream, "port-set");
+ }
+
+ if (show & PORTINFO_DETAILS)
+ {
+ error_t err;
+ mach_port_t port;
+ mach_msg_type_name_t acquired_type;
+
+ /* Get the port itself. */
+ err = mach_port_extract_right (task, name,
+ (type & MACH_PORT_TYPE_RECEIVE
+ ? MACH_MSG_TYPE_MAKE_SEND
+ : MACH_MSG_TYPE_COPY_SEND),
+ &port, &acquired_type);
+
+ if (!err)
+ {
+ process_t proc = getproc ();
+ mach_port_t msgport;
+ pid_t pid;
+
+ err = proc_task2pid (proc, task, &pid);
+ if (!err)
+ err = proc_getmsgport (proc, pid, &msgport);
+ if (!err)
+ {
+ /* Check if it is installed as an FD. */
+ mach_port_t *dtable = NULL;
+ mach_msg_type_number_t ndtable = 0;
+ unsigned i;
+
+ msg_get_dtable (msgport, task, &dtable, &ndtable);
+
+ for (i = 0; i < ndtable; i++)
+ {
+ if (dtable[i] == port)
+ fprintf (stream, " fd(%d)", i);
+ mach_port_deallocate (mach_task_self (), dtable[i]);
+ }
+ vm_deallocate (mach_task_self (), (vm_address_t) dtable, ndtable * sizeof (*dtable));
+
+ /* First check for init ports. */
+ void check_init_port (int num, const char *name)
+ {
+ mach_port_t init_port;
+
+ err = msg_get_init_port (msgport, task, num, &init_port);
+ if (!err)
+ {
+ if (port == init_port)
+ fprintf (stream, " %s", name);
+ mach_port_deallocate (mach_task_self (), init_port);
+ }
+ }
+
+ check_init_port (INIT_PORT_CWDIR, "CWDIR");
+ check_init_port (INIT_PORT_CRDIR, "CRDIR");
+ check_init_port (INIT_PORT_AUTH, "AUTH");
+ check_init_port (INIT_PORT_PROC, "PROC");
+ check_init_port (INIT_PORT_CTTYID, "CTTYID");
+ check_init_port (INIT_PORT_BOOTSTRAP, "BOOTSTRAP");
+
+ mach_port_deallocate (mach_task_self (), msgport);
+ }
+
+ /* Then try to use the ports to see what they are. */
+ if (type & MACH_PORT_TYPE_RECEIVE)
+ {
+ if (port == msgport)
+ fprintf (stream, " msg");
+ }
+ else if (type & MACH_PORT_TYPE_SEND)
+ {
+ /* auth_t */
+ {
+ uid_t *euids = 0, *auids = 0, *egids = 0, *agids = 0;
+ mach_msg_type_number_t neuids = 0, nauids = 0, negids = 0, nagids = 0, i;
+
+ err = auth_getids (port,
+ &euids, &neuids,
+ &auids, &nauids,
+ &egids, &negids,
+ &agids, &nagids);
+
+ if (!err)
+ {
+ fprintf (stream, " auth([");
+ subfirst = 1;
+ for (i = 0; i < neuids; i++)
+ {
+ subcomma ();
+ fprintf (stream, "%d", euids[i]);
+ }
+ fprintf (stream, "],[");
+ subfirst = 1;
+ for (i = 0; i < nauids; i++)
+ {
+ subcomma ();
+ fprintf (stream, "%d", auids[i]);
+ }
+ fprintf (stream, "],[");
+ subfirst = 1;
+ for (i = 0; i < negids; i++)
+ {
+ subcomma ();
+ fprintf (stream, "%d", egids[i]);
+ }
+ fprintf (stream, "],[");
+ subfirst = 1;
+ for (i = 0; i < nagids; i++)
+ {
+ subcomma ();
+ fprintf (stream, "%d", agids[i]);
+ }
+ fprintf (stream, "])");
+ munmap (euids, neuids * sizeof (*euids));
+ munmap (auids, nauids * sizeof (*auids));
+ munmap (egids, negids * sizeof (*egids));
+ munmap (agids, nagids * sizeof (*agids));
+ }
+ }
+
+ /* file_t */
+ {
+ int allowed;
+
+ err = file_check_access (port, &allowed);
+
+ if (!err)
+ {
+ int printbar = 0;
+ void bar (void)
+ {
+ if (printbar)
+ fprintf (stream, "|");
+ else
+ printbar = 1;
+ }
+
+ fprintf (stream, " file(");
+ if (allowed & O_READ)
+ {
+ bar ();
+ fprintf (stream, "READ");
+ }
+ if (allowed & O_WRITE)
+ {
+ bar ();
+ fprintf (stream, "WRITE");
+ }
+ if (allowed & O_EXEC)
+ {
+ bar ();
+ fprintf (stream, "EXEC");
+ }
+ fprintf (stream, ")");
+ }
+ }
+
+ /* fsys_t */
+ {
+ string_t source;
+
+ err = fsys_get_source (port, source);
+
+ if (!err)
+ fprintf (stream, " fsys(%s)", source);
+ }
+
+ /* io_t */
+ {
+ struct stat st;
+
+ err = io_stat (port, &st);
+
+ if (!err)
+ fprintf (stream, " io(%llu,%llu)",
+ (unsigned long long) st.st_ino,
+ (unsigned long long) st.st_dev);
+ }
+
+ /* msg */
+ {
+ mach_port_t proc;
+
+ err = msg_get_init_port (port, task, INIT_PORT_PROC, &proc);
+ if (!err)
+ {
+ pid_t pid, ppid;
+ int orphaned;
+
+ fprintf (stream, " msg");
+ err = proc_getpids (port, &pid, &ppid, &orphaned);
+ if (!err)
+ fprintf (stream, "(%d)", pid);
+
+ mach_port_deallocate (mach_task_self (), proc);
+ }
+ }
+
+ /* pci_t */
+ {
+ vm_size_t ndevs;
+
+ err = pci_get_ndevs (port, &ndevs);
+
+ if (!err)
+ fprintf (stream, " pci(%d)", ndevs);
+ }
+
+ /* process_t */
+ {
+ pid_t pid, ppid;
+ int orphaned;
+
+ err = proc_getpids (port, &pid, &ppid, &orphaned);
+
+ if (!err)
+ fprintf (stream, " proc(%d)", pid);
+ }
+
+ /* socket_t */
+ {
+ mach_port_t addr = MACH_PORT_NULL;
+ int type;
+ struct sockaddr_storage sa;
+ char *psa = (char*) &sa;
+ mach_msg_type_number_t salen = sizeof (sa);
+
+ err = socket_name (port, &addr);
+
+ if (!err)
+ fprintf (stream, " socket");
+ else
+ addr = port;
+
+ err = socket_whatis_address (addr, &type, &psa, &salen);
+ if (!err)
+ {
+ if (addr == port)
+ fprintf (stream, " addr_port");
+
+ if (type == AF_UNIX)
+ {
+ struct sockaddr_un *sa_un = (struct sockaddr_un *) psa;
+
+ fprintf (stream, "(UNIX:%s)", sa_un->sun_path);
+ }
+ else if (type == AF_INET)
+ {
+ struct sockaddr_in *sa_in = (struct sockaddr_in *) psa;
+
+ fprintf (stream, "(INET:%s:%d)",
+ inet_ntoa (sa_in->sin_addr),
+ ntohs (sa_in->sin_port));
+ }
+ else if (type == AF_INET6)
+ {
+ struct sockaddr_in6 *sa_in6 = (struct sockaddr_in6 *) psa;
+ char buf[INET6_ADDRSTRLEN];
+ const char *s;
+
+ s = inet_ntop (type, &sa_in6->sin6_addr, buf, sizeof (buf));
+ fprintf (stream, "(INET6:%s:%d)", s,
+ ntohs (sa_in6->sin6_port));
+ }
+ else
+ fprintf (stream, "(%d)", type);
+ }
+ if (psa != (char*) &sa)
+ vm_deallocate (mach_task_self (), (vm_address_t) psa, salen);
+
+ if (addr != port)
+ mach_port_deallocate (mach_task_self (), addr);
+ }
+
+ /* terminal */
+ {
+ string_t name;
+
+ err = term_get_nodename (port, name);
+
+ if (!err)
+ fprintf (stream, " term(%s)", name);
+ }
+
+ /* default pager */
+ {
+ struct default_pager_info def_pager_info;
+
+ err = default_pager_info (port, &def_pager_info);
+
+ if (!err)
+ fprintf (stream, " default_pager(%llu)",
+ (unsigned long long) def_pager_info.dpi_total_space);
+ }
+
+ /* host_t */
+ {
+ struct host_basic_info info;
+ mach_msg_type_number_t count = HOST_BASIC_INFO_COUNT;
+
+ err = host_info (port, HOST_BASIC_INFO,
+ (host_info_t) &info, &count);
+
+ if (!err)
+ fprintf (stream, " host");
+ if (port == mach_host_self ())
+ fprintf (stream, "(self)");
+ }
+
+ /* memory_object */
+ {
+ boolean_t ready, may_cache;
+ memory_object_copy_strategy_t strategy;
+
+ err = memory_object_get_attributes (port, &ready, &may_cache, &strategy);
+
+ if (!err)
+ fprintf (stream, " memory_object");
+ }
+
+ /* processor_t */
+ {
+ struct processor_basic_info info;
+ host_t host;
+ mach_msg_type_number_t count = PROCESSOR_BASIC_INFO_COUNT;
+
+ err = processor_info (port, PROCESSOR_BASIC_INFO,
+ &host, (processor_info_t) &info, &count);
+
+ if (!err)
+ {
+ fprintf (stream, " processor(%d)", info.slot_num);
+ mach_port_deallocate (mach_task_self (), host);
+ }
+ }
+
+ /* task_t */
+ {
+ pid_t pid;
+
+ err = proc_task2pid (proc, port, &pid);
+ if (!err)
+ fprintf (stream, " task(%d)", pid);
+ if (port == task)
+ {
+ if (err)
+ fprintf (stream, " task");
+ fprintf (stream, "(self)");
+ }
+ }
+
+ /* thread_t */
+ {
+ struct thread_basic_info info;
+ mach_msg_type_number_t count = THREAD_BASIC_INFO_COUNT;
+
+ err = thread_info (port, THREAD_BASIC_INFO,
+ (thread_info_t) &info, &count);
+
+ if (!err)
+ fprintf (stream, " thread");
+ }
+ }
+
+ mach_port_deallocate (mach_task_self (), proc);
+ mach_port_deallocate (mach_task_self (), port);
+ }
+
+ if (type & MACH_PORT_TYPE_RECEIVE)
{
struct mach_port_status status;
error_t err = mach_port_get_receive_status (task, name, &status);
@@ -83,31 +492,14 @@ print_port_info (mach_port_t name, mach_port_type_t type, task_t task,
status.mps_nsrequest ? ", ns-req" : "");
}
}
- }
- if (type & MACH_PORT_TYPE_SEND)
- {
- comma ();
- fprintf (stream, "send");
- if (show & PORTINFO_DETAILS)
+
+ if (type & MACH_PORT_TYPE_SEND)
prefs (MACH_PORT_RIGHT_SEND);
- }
- if (type & MACH_PORT_TYPE_SEND_ONCE)
- {
- comma ();
- fprintf (stream, "send-once");
- }
- if (type & MACH_PORT_TYPE_DEAD_NAME)
- {
- comma ();
- fprintf (stream, "dead-name");
- if (show & PORTINFO_DETAILS)
+
+ if (type & MACH_PORT_TYPE_DEAD_NAME)
prefs (MACH_PORT_RIGHT_DEAD_NAME);
- }
- if (type & MACH_PORT_TYPE_PORT_SET)
- {
- comma ();
- fprintf (stream, "port-set");
- if (show & PORTINFO_DETAILS)
+
+ if (type & MACH_PORT_TYPE_PORT_SET)
{
mach_port_t *members = 0;
mach_msg_type_number_t members_len = 0, i;
@@ -127,8 +519,9 @@ print_port_info (mach_port_t name, mach_port_type_t type, task_t task,
munmap ((caddr_t) members, members_len * sizeof *members);
}
}
- }
+ }
}
+
putc ('\n', stream);
return 0;