blob: 5d000b799304cb3264d68570aa6d29e33481f30d [file] [log] [blame]
// Copyright 2016 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "broker_client.h"
#define _GNU_SOURCE
#include <dlfcn.h> // dlsym(...)
#include <errno.h>
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include <unistd.h>
#include <brillo/brillo_export.h>
#define _FCNTL_H
#include <bits/fcntl.h>
// Route all requests starting with /dev/bus/usb to broker_service, which
// talks to permission_broker to get the fds, if they are legit.
#define OUR_USB_PATH "/dev/bus/usb"
BRILLO_EXPORT int (*_open)(const char* pathname, int flags, ...);
BRILLO_EXPORT int (*_open64)(const char* pathname, int flags, ...);
// Returns 1 if 'str' starts with 'prefix' else 0.
int StartsWith(const char* prefix, const char* str) {
size_t lenp = strlen(prefix), lens = strlen(str);
return lens < lenp ? 0 : strncmp(prefix, str, lenp) == 0;
}
static int open_override(const char *func, const char* pathname, int flags, ...)
{
// get the next function call
_open = (int (*)(const char*, int, ...)) dlsym(RTLD_NEXT, func);
// Asking permission_broker to OpenPath(...) is equivalent to opening the
// same thing as root, and with O_RDWR.
if (StartsWith(OUR_USB_PATH, pathname) && ((flags & O_RDWR) != 0)) {
int broker_sockfd = ConnectToBroker(BROKER_SOCKET_PATH, BROKER_SOCKET_PATH_LEN);
int return_val = OpenWithPermissions(broker_sockfd, pathname);
close(broker_sockfd);
// If permission_broker gives -1, behave as if it was never asked.
if (return_val >= 0) {
return return_val;
}
}
if (flags & (O_CREAT | O_TMPFILE)) {
va_list ap;
va_start(ap, flags);
mode_t mode = va_arg(ap, mode_t);
va_end(ap);
return _open(pathname, flags, mode);
}
return _open(pathname, flags);
}
static int open64_override(const char *func, const char* pathname, int flags, ...)
{
// get the next function call
_open64 = (int (*)(const char*, int, ...)) dlsym(RTLD_NEXT, func);
// Asking permission_broker to OpenPath(...) is equivalent to opening the
// same thing as root, and with O_RDWR.
if (StartsWith(OUR_USB_PATH, pathname) && ((flags & O_RDWR) != 0)) {
int broker_sockfd = ConnectToBroker(BROKER_SOCKET_PATH, BROKER_SOCKET_PATH_LEN);
int return_val = OpenWithPermissions(broker_sockfd, pathname);
close(broker_sockfd);
// If permission_broker gives -1, behave as if it was never asked.
if (return_val >= 0) {
return return_val;
}
}
if (flags & (O_CREAT | O_TMPFILE)) {
va_list ap;
va_start(ap, flags);
mode_t mode = va_arg(ap, mode_t);
va_end(ap);
return _open64(pathname, flags, mode);
}
return _open64(pathname, flags);
}
BRILLO_EXPORT int open(const char* pathname, int flags, ...) {
return open_override("open", pathname, flags);
}
BRILLO_EXPORT int __open_2(const char* pathname, int flags, ...) {
return open_override("__open_2", pathname, flags);
}
BRILLO_EXPORT int open64(const char* pathname, int flags, ...) {
return open64_override("open64", pathname, flags);
}
BRILLO_EXPORT int __open64_2(const char* pathname, int flags, ...) {
return open64_override("__open64_2", pathname, flags);
}