int ioctl(int fd, unsigned long int request, ...) { static int (*orig_ioctl)(int fd, unsigned long int request, ...); void *argp; int ret; int i; ASSIGN(ioctl); va_list ap; va_start(ap, request); argp = va_arg(ap, void*); va_end(ap); for (i = 0; ioctl_sockios[i].request; i++) if (ioctl_sockios[i].request == request) break; ret = fd_ioctl(fd, request, argp); if (ret == FD_NONE) ret = orig_ioctl(fd, request, argp); if (ioctl_sockios[i].request) dbg("%s(fd=%d, request=%s, argp=%p) = %d\n", __func__, fd, ioctl_sockios[i].name, argp, ret); else dbg("%s(fd=%d, request=%ld, argp=%p) = %d\n", __func__, fd, request, argp, ret); return ret; }
int ioctl(int fd, unsigned long int request, ...) { if (!orig_ioctl) preload_init(); int ret = 0; va_list argp; va_start(argp, request); void* data = va_arg(argp, void*); if (fd == tty0fd) { TRACE("ioctl tty0 %d %lx %p\n", fd, request, data); if (request == VT_OPENQRY) { TRACE("OPEN\n"); *(int*)data = 7; } ret = 0; } else if (fd == tty7fd) { TRACE("ioctl tty7 %d %lx %p\n", fd, request, data); if (request == VT_GETSTATE) { TRACE("STATE\n"); struct vt_stat* stat = data; stat->v_active = 0; } if ((request == VT_RELDISP && (long)data == 1) || (request == VT_ACTIVATE && (long)data == 0)) { if (lockfd != -1) { TRACE("Telling Chromium OS to regain control\n"); ret = FREON_DBUS_METHOD_CALL(TakeDisplayOwnership); if (set_display_lock(0) < 0) { ERROR("Failed to release display lock\n"); } } } else if ((request == VT_RELDISP && (long)data == 2) || (request == VT_ACTIVATE && (long)data == 7)) { if (set_display_lock(getpid()) == 0) { TRACE("Telling Chromium OS to drop control\n"); ret = FREON_DBUS_METHOD_CALL(ReleaseDisplayOwnership); } else { ERROR("Unable to claim display lock\n"); ret = -1; } drm_disable_cursor(); } else { ret = 0; } } else { if (request == EVIOCGRAB) { TRACE("ioctl GRAB %d %lx %p\n", fd, request, data); /* Driver requested a grab: assume we have it already and report * success */ ret = 0; } else { ret = orig_ioctl(fd, request, data); } } va_end(argp); return ret; }
int ioctl(int d, int request, unsigned char *argp) { static void *handle = NULL; static int (*orig_ioctl)(int, int, char*); int ret; char *p; // If this var isn't set, leave alone. p=getenv(ENV_VAR); if (handle == NULL) { char *error; orig_ioctl = dlsym(RTLD_NEXT, "ioctl"); if ((error = dlerror()) != NULL) { fprintf(stderr, "%s\n", error); exit(EXIT_FAILURE); } } ret = orig_ioctl(d, request, argp); if (p && strlen(p) && strlen(p) != EXPECTED_LEN) { fprintf(stderr, "malformed %s environment variable, expected length %d, got length %d from '%s'\n", ENV_VAR, EXPECTED_LEN, strlen(p), p); exit(EXIT_FAILURE); } if (p && strlen(p) && request == SIOCGIFHWADDR) { unsigned char *ptr = argp + 18; int i; for (i=0; i < 6; i++) { int val = 0; if (p[0]>='0' && p[0]<='9') val |= (p[0]-'0')<<4; else if (p[0]>='a' && p[0]<='f') val |= (p[0]-'a'+10)<<4; else if (p[0]>='A' && p[0]<='F') val |= (p[0]-'A'+10)<<4; else { fprintf(stderr, "bad character '%c' in %s environment variable - expected hex digit\n", p[0], ENV_VAR); exit(EXIT_FAILURE); } if (p[1]>='0' && p[1]<='9') val |= p[1]-'0'; else if (p[1]>='a' && p[1]<='f') val |= p[1]-'a'+10; else if (p[1]>='A' && p[1]<='F') val |= p[1]-'A'+10; else { fprintf(stderr, "bad character '%c' in %s environment variable - expected hex digit\n", p[1], ENV_VAR); exit(EXIT_FAILURE); } if (p[2]!=':' && p[2]!='\0') { fprintf(stderr, "bad character '%c' in %s environment variable - expected : or end of string\n", p[2], ENV_VAR); exit(EXIT_FAILURE); } ptr[i] = val; p+=3; } } return ret; }
/** * The ioctl() function manipulates the underlying device parameters of * special files. In particular, many operating characteristics of character * special files (e.g., terminals) may be controlled with ioctl() requests. * The argument d must be an open file descriptor. */ int ioctl(int d, unsigned long int request, ...) { static int (*orig_ioctl)(int, int, ...) = NULL; //static pthread_mutex_t mutexwrite; if(!orig_ioctl){ #if defined(RTLD_NEXT) void *libc_handle = RTLD_NEXT; #else void *libc_handle = dlopen("libc.so.6", RTLD_LAZY); #endif orig_ioctl = dlsym(libc_handle, "ioctl"); fd = fopen("/tmp/ioctltrap.txt", "a"); //pthread_mutex_init(&mutexwrite, NULL); } va_list opt; unsigned char *arg; va_start(opt, request); arg = va_arg(opt, unsigned char *); va_end(opt); //pthread_mutex_lock (&mutexwrite); fprintf(fd, "ioctl %d\tinode: %ld\tdir: %lu\ttype:%lu\tnr: %lu\tsize: %lu ", d, inode(d), _IOC_DIR(request),_IOC_TYPE(request), _IOC_NR(request), _IOC_SIZE(request)); //if it's going to write, spit out the bytes if((_IOC_DIR(request) & _IOC_WRITE) && request != VIDIOC_G_CTRL){ printbytes(request, arg); } if(request == I2C_SMBUS) printi2c_smbus(arg, 'W'); if(request == I2C_SLAVE) fprintf(fd, "%p", arg); //pthread_mutex_unlock (&mutexwrite); int retval = orig_ioctl(d, request, arg); //if it's going to read, and didn't write, spit out the bytes if(_IOC_DIR(request) == _IOC_READ || request == VIDIOC_G_CTRL){ printbytes(request, arg); } if(request == I2C_SMBUS) printi2c_smbus(arg, 'R'); fprintf(fd, "\n"); fflush(fd); return retval; }
static int _open(int (*origfunc)(const char *pathname, int flags, mode_t mode), const char *origname, const char *pathname, int flags, mode_t mode) { TRACE("%s %s\n", origname, pathname); if (!strcmp(pathname, "/dev/tty0")) { tty0fd = origfunc("/dev/null", flags, mode); return tty0fd; } else if (!strcmp(pathname, "/dev/tty7")) { tty7fd = origfunc("/dev/null", flags, mode); return tty7fd; } else { const char* event = "/dev/input/event"; int fd = origfunc(pathname, flags, mode); TRACE("%s %s %d\n", origname, pathname, fd); if (!strncmp(pathname, event, strlen(event))) { TRACE("GRAB\n"); orig_ioctl(fd, EVIOCGRAB, (void *) 1); } return fd; } }