From d8d60f17dad9d2e9a01729d9f21b0a99f1aeb4ce Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Wed, 18 Oct 2017 16:58:55 +0100 Subject: [PATCH] fishdescriptor: debugging Signed-off-by: Ian Jackson --- fishdescriptor/donate.c | 92 --------------------- fishdescriptor/fishdescriptor | 11 +++ fishdescriptor/py/fishdescriptor/fish.py | 8 +- fishdescriptor/py/fishdescriptor/indonor.py | 10 +-- 4 files changed, 20 insertions(+), 101 deletions(-) delete mode 100644 fishdescriptor/donate.c create mode 100755 fishdescriptor/fishdescriptor diff --git a/fishdescriptor/donate.c b/fishdescriptor/donate.c deleted file mode 100644 index 11c51db..0000000 --- a/fishdescriptor/donate.c +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright (C) 2009 Citrix Ltd. - * Copyright (C) 2017 Citrix Ltd. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include -#include -#include - -#include -#include -#include - -static int fishdescriptor_sendmsg_fds(int carrier, - int nfds, const int fds[]) { - /* return convention: like a syscall */ - struct msghdr msg = { 0 }; - struct cmsghdr *cmsg; - size_t spaceneeded = nfds * sizeof(fds[0]); - char control[CMSG_SPACE(spaceneeded)]; - struct iovec iov; - int r; - - iov.iov_base = &nfds; - iov.iov_len = sizeof(nfds); - - /* compose the message */ - msg.msg_iov = &iov; - msg.msg_iovlen = 1; - msg.msg_control = control; - msg.msg_controllen = sizeof(control); - - /* attach open fd */ - cmsg = CMSG_FIRSTHDR(&msg); - cmsg->cmsg_level = SOL_SOCKET; - cmsg->cmsg_type = SCM_RIGHTS; - cmsg->cmsg_len = CMSG_LEN(spaceneeded); - memcpy(CMSG_DATA(cmsg), fds, spaceneeded); - - msg.msg_controllen = cmsg->cmsg_len; - - r = sendmsg(carrier, &msg, 0); - if (r < 0) return -1; - - return 0; -} - -int fishdescriptor_donate(const char *path, const int *fds) { - /* return convention: returns errno value */ - /* within function: r is like syscall return, errno value is in errno */ - int r; - int esave = errno; - int carrier=-1; - - carrier = socket(AF_UNIX, SOCK_STREAM, 0); - if (carrier < 0) { r=-1; goto out; } - - struct sockaddr_un suna; - memset(&suna,0,sizeof(suna)); - suna.sun_family = AF_UNIX; - if (strlen(path) >= sizeof(suna.sun_path)) { errno=E2BIG; r=-1; goto out; } - strcpy(suna.sun_path, path); - - r = connect(carrier, (const struct sockaddr*)&suna, sizeof(suna)); - if (r) goto out; - - int nfds; - for (nfds=0; fds[nfds] > 0; nfds++); - - r = fishdescriptor_sendmsg_fds(carrier, nfds, fds); - if (r) goto out; - - r = 0; - out: - if (carrier >= 0) close(carrier); - r = !r ? 0 : !errno ? EIO : errno; - errno = esave; - return r; -} diff --git a/fishdescriptor/fishdescriptor b/fishdescriptor/fishdescriptor new file mode 100755 index 0000000..4708401 --- /dev/null +++ b/fishdescriptor/fishdescriptor @@ -0,0 +1,11 @@ +#!/usr/bin/python3 + +import sys +import fishdescriptor.fish + +pid = int(sys.argv[1]) +fds = map(int, sys.argv[2:]) + +d = fishdescriptor.fish.Donor(pid) +r = d.fish(fds) +print(repr(r)) diff --git a/fishdescriptor/py/fishdescriptor/fish.py b/fishdescriptor/py/fishdescriptor/fish.py index 95694ff..9c7fca8 100644 --- a/fishdescriptor/py/fishdescriptor/fish.py +++ b/fishdescriptor/py/fishdescriptor/fish.py @@ -6,18 +6,18 @@ import os import pwd def _shuffle_fd3(): - os.dup(1,3) - os.dup(2,1) + os.dup2(1,3) + os.dup2(2,1) class Donor(): def __init__(d, pid): d._pid = pid d._sp = subprocess.Popen( - preexec_fn = _suffle_fd3, + preexec_fn = _shuffle_fd3, stdin = subprocess.PIPE, stdout = subprocess.PIPE, close_fds = False, - args = ['gdb', '-p', pid, '-batch', '-ex' + args = ['gdb', '-p', str(pid), '-batch', '-ex', 'python import fishdescriptor.indonor as id;'+ ' id.DonorImplementation().eval_loop()' ] diff --git a/fishdescriptor/py/fishdescriptor/indonor.py b/fishdescriptor/py/fishdescriptor/indonor.py index 046e6f5..1f3c689 100644 --- a/fishdescriptor/py/fishdescriptor/indonor.py +++ b/fishdescriptor/py/fishdescriptor/indonor.py @@ -51,7 +51,7 @@ class DonorStructLayout(): l._posns = { } for f in x.type.fields(): l._posns[f.name] = len(l._template) - try f.type.fields(): blank = '{ }' + try: f.type.fields(); blank = '{ }' except AttributeError: blank = '0' l._template.append(blank) def substitute(l, values): @@ -68,7 +68,7 @@ class DonorImplementation(): # assembling structs # sigh, we have to record the order of the arguments! - def di._find_fields(typename): + def _find_fields(typename): try: fields = di._structs[typename] except AttributeError: @@ -76,7 +76,7 @@ class DonorImplementation(): di._structs[typename] = fields return fields - def di._make(typename, values): + def _make(typename, values): fields = di._find_fields(typename) return fields.substitute(values) @@ -133,7 +133,7 @@ class DonorImplementation(): 'int (*)(int, const struct sockaddr*, socklen_t)', 'connect', '(%d, (const struct sockaddr*)%s, sizeof(struct sockaddr_un))' - % (fd, _lit_addressof(addr) + % (fd, _lit_addressof(addr)) ) def _close(di, fd): @@ -160,7 +160,7 @@ class DonorImplementation(): to_restore = di._saved_errno di._saved_errno = None if to_restore is not None: - gdb.parse_and_eval('errno = %d' % to_restore)) + gdb.parse_and_eval('errno = %d' % to_restore) # main entrypoints -- 2.30.2