Skip to content

Commit

Permalink
Merge remote-tracking branch 'aosp-common/android-3.0' into ts
Browse files Browse the repository at this point in the history
  • Loading branch information
didhiy committed Feb 18, 2014
2 parents dfc3d10 + f88ea89 commit 6fec3c5
Show file tree
Hide file tree
Showing 6 changed files with 77 additions and 28 deletions.
32 changes: 27 additions & 5 deletions drivers/usb/gadget/f_accessory.c
Expand Up @@ -261,8 +261,10 @@ static void acc_complete_in(struct usb_ep *ep, struct usb_request *req)
{
struct acc_dev *dev = _acc_dev;

if (req->status != 0)
if (req->status == -ESHUTDOWN) {
pr_debug("acc_complete_in set disconnected");
acc_set_disconnected(dev);
}

req_put(dev, &dev->tx_idle, req);

Expand All @@ -274,8 +276,10 @@ static void acc_complete_out(struct usb_ep *ep, struct usb_request *req)
struct acc_dev *dev = _acc_dev;

dev->rx_done = 1;
if (req->status != 0)
if (req->status == -ESHUTDOWN) {
pr_debug("acc_complete_out set disconnected");
acc_set_disconnected(dev);
}

wake_up(&dev->read_wq);
}
Expand Down Expand Up @@ -557,8 +561,10 @@ static ssize_t acc_read(struct file *fp, char __user *buf,

pr_debug("acc_read(%d)\n", count);

if (dev->disconnected)
if (dev->disconnected) {
pr_debug("acc_read disconnected");
return -ENODEV;
}

if (count > BULK_BUFFER_SIZE)
count = BULK_BUFFER_SIZE;
Expand All @@ -571,6 +577,12 @@ static ssize_t acc_read(struct file *fp, char __user *buf,
goto done;
}

if (dev->rx_done) {
// last req cancelled. try to get it.
req = dev->rx_req[0];
goto copy_data;
}

requeue_req:
/* queue a request */
req = dev->rx_req[0];
Expand All @@ -588,9 +600,17 @@ static ssize_t acc_read(struct file *fp, char __user *buf,
ret = wait_event_interruptible(dev->read_wq, dev->rx_done);
if (ret < 0) {
r = ret;
usb_ep_dequeue(dev->ep_out, req);
ret = usb_ep_dequeue(dev->ep_out, req);
if (ret != 0) {
// cancel failed. There can be a data already received.
// it will be retrieved in the next read.
pr_debug("acc_read: cancelling failed %d", ret);
}
goto done;
}

copy_data:
dev->rx_done = 0;
if (dev->online) {
/* If we got a 0-len packet, throw it back and try again. */
if (req->actual == 0)
Expand Down Expand Up @@ -619,8 +639,10 @@ static ssize_t acc_write(struct file *fp, const char __user *buf,

pr_debug("acc_write(%d)\n", count);

if (!dev->online || dev->disconnected)
if (!dev->online || dev->disconnected) {
pr_debug("acc_write disconnected or not online");
return -ENODEV;
}

while (count > 0) {
if (!dev->online) {
Expand Down
32 changes: 18 additions & 14 deletions net/ipv4/ping.c
Expand Up @@ -877,10 +877,12 @@ int ping_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
/* Copy the address and add cmsg data. */
if (family == AF_INET) {
sin = (struct sockaddr_in *) msg->msg_name;
sin->sin_family = AF_INET;
sin->sin_port = 0 /* skb->h.uh->source */;
sin->sin_addr.s_addr = ip_hdr(skb)->saddr;
memset(sin->sin_zero, 0, sizeof(sin->sin_zero));
if (sin) {
sin->sin_family = AF_INET;
sin->sin_port = 0 /* skb->h.uh->source */;
sin->sin_addr.s_addr = ip_hdr(skb)->saddr;
memset(sin->sin_zero, 0, sizeof(sin->sin_zero));
}

if (isk->cmsg_flags)
ip_cmsg_recv(msg, skb);
Expand All @@ -890,17 +892,19 @@ int ping_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
struct ipv6_pinfo *np = inet6_sk(sk);
struct ipv6hdr *ip6 = ipv6_hdr(skb);
sin6 = (struct sockaddr_in6 *) msg->msg_name;
sin6->sin6_family = AF_INET6;
sin6->sin6_port = 0;
sin6->sin6_addr = ip6->saddr;

sin6->sin6_flowinfo = 0;
if (np->sndflow)
sin6->sin6_flowinfo =
*(__be32 *)ip6 & IPV6_FLOWINFO_MASK;

sin6->sin6_scope_id = ipv6_iface_scope_id(&sin6->sin6_addr,
IP6CB(skb)->iif);
if (sin6) {
sin6->sin6_family = AF_INET6;
sin6->sin6_port = 0;
sin6->sin6_addr = ip6->saddr;
sin6->sin6_flowinfo = 0;
if (np->sndflow)
sin6->sin6_flowinfo =
*(__be32 *)ip6 & IPV6_FLOWINFO_MASK;
sin6->sin6_scope_id =
ipv6_iface_scope_id(&sin6->sin6_addr,
IP6CB(skb)->iif);
}

if (inet6_sk(sk)->rxopt.all)
pingv6_ops.datagram_recv_ctl(sk, msg, skb);
Expand Down
12 changes: 6 additions & 6 deletions net/netfilter/xt_IDLETIMER.c
Expand Up @@ -68,15 +68,15 @@ static DEFINE_MUTEX(list_mutex);

static struct kobject *idletimer_tg_kobj;

static void notify_netlink_uevent(const char *label, struct idletimer_tg *timer)
static void notify_netlink_uevent(const char *iface, struct idletimer_tg *timer)
{
char label_msg[NLMSG_MAX_SIZE];
char iface_msg[NLMSG_MAX_SIZE];
char state_msg[NLMSG_MAX_SIZE];
char *envp[] = { label_msg, state_msg, NULL };
char *envp[] = { iface_msg, state_msg, NULL };
int res;

res = snprintf(label_msg, NLMSG_MAX_SIZE, "LABEL=%s",
label);
res = snprintf(iface_msg, NLMSG_MAX_SIZE, "INTERFACE=%s",
iface);
if (NLMSG_MAX_SIZE <= res) {
pr_err("message too long (%d)", res);
return;
Expand All @@ -87,7 +87,7 @@ static void notify_netlink_uevent(const char *label, struct idletimer_tg *timer)
pr_err("message too long (%d)", res);
return;
}
pr_debug("putting nlmsg: <%s> <%s>\n", label_msg, state_msg);
pr_debug("putting nlmsg: <%s> <%s>\n", iface_msg, state_msg);
kobject_uevent_env(idletimer_tg_kobj, KOBJ_CHANGE, envp);
return;

Expand Down
20 changes: 18 additions & 2 deletions security/selinux/hooks.c
Expand Up @@ -215,6 +215,14 @@ static int inode_alloc_security(struct inode *inode)
return 0;
}

static void inode_free_rcu(struct rcu_head *head)
{
struct inode_security_struct *isec;

isec = container_of(head, struct inode_security_struct, rcu);
kmem_cache_free(sel_inode_cache, isec);
}

static void inode_free_security(struct inode *inode)
{
struct inode_security_struct *isec = inode->i_security;
Expand All @@ -225,8 +233,16 @@ static void inode_free_security(struct inode *inode)
list_del_init(&isec->list);
spin_unlock(&sbsec->isec_lock);

inode->i_security = NULL;
kmem_cache_free(sel_inode_cache, isec);
/*
* The inode may still be referenced in a path walk and
* a call to selinux_inode_permission() can be made
* after inode_free_security() is called. Ideally, the VFS
* wouldn't do this, but fixing that is a much harder
* job. For now, simply free the i_security via RCU, and
* leave the current inode->i_security pointer intact.
* The inode will be freed after the RCU grace period too.
*/
call_rcu(&isec->rcu, inode_free_rcu);
}

static int file_alloc_security(struct file *file)
Expand Down
5 changes: 4 additions & 1 deletion security/selinux/include/objsec.h
Expand Up @@ -38,7 +38,10 @@ struct task_security_struct {

struct inode_security_struct {
struct inode *inode; /* back pointer to inode object */
struct list_head list; /* list of inode_security_struct */
union {
struct list_head list; /* list of inode_security_struct */
struct rcu_head rcu; /* for freeing the inode_security_struct */
};
u32 task_sid; /* SID of creating task */
u32 sid; /* SID of this object */
u16 sclass; /* security class of this object */
Expand Down
4 changes: 4 additions & 0 deletions security/selinux/ss/services.c
Expand Up @@ -1231,6 +1231,10 @@ static int security_context_to_sid_core(const char *scontext, u32 scontext_len,
struct context context;
int rc = 0;

/* An empty security context is never valid. */
if (!scontext_len)
return -EINVAL;

if (!ss_initialized) {
int i;

Expand Down

0 comments on commit 6fec3c5

Please sign in to comment.