/** * @brief Get wireless statistics * * @param dev A pointer to net_device structure * * @return A pointer to iw_statistics buf */ struct iw_statistics * woal_get_uap_wireless_stats(struct net_device *dev) { moal_private *priv = (moal_private *) netdev_priv(dev); t_u16 wait_option = MOAL_NO_WAIT; ENTER(); /* * Since schedule() is not allowed from an atomic context * such as when dev_base_lock for netdevices is acquired * for reading/writing in kernel before this call, HostCmd * is issued in non-blocking way in such contexts and * blocking in other cases. */ if (write_can_lock(&dev_base_lock) && (!in_atomic() || current->exit_state)) wait_option = MOAL_WSTATS_WAIT; priv->w_stats.qual.qual = 0; priv->w_stats.qual.level = 0; priv->w_stats.discard.code = 0; priv->w_stats.status = IW_MODE_MASTER; woal_uap_get_stats(priv, wait_option, NULL); LEAVE(); return &priv->w_stats; }
int ptrace_attach(struct task_struct *task) { int retval; audit_ptrace(task); retval = -EPERM; if (task->pid <= 1) goto out; if (task->tgid == current->tgid) goto out; repeat: /* * Nasty, nasty. * * We want to hold both the task-lock and the * tasklist_lock for writing at the same time. * But that's against the rules (tasklist_lock * is taken for reading by interrupts on other * cpu's that may have task_lock). */ task_lock(task); local_irq_disable(); if (!write_trylock(&tasklist_lock)) { local_irq_enable(); task_unlock(task); do { cpu_relax(); } while (!write_can_lock(&tasklist_lock)); goto repeat; } if (!task->mm) goto bad; /* the same process cannot be attached many times */ if (task->ptrace & PT_PTRACED) goto bad; retval = may_attach(task); if (retval) goto bad; /* Go */ task->ptrace |= PT_PTRACED | ((task->real_parent != current) ? PT_ATTACHED : 0); if (capable(CAP_SYS_PTRACE)) task->ptrace |= PT_PTRACE_CAP; __ptrace_link(task, current); force_sig_specific(SIGSTOP, task); bad: write_unlock_irq(&tasklist_lock); task_unlock(task); out: return retval; }
int ptrace_attach(struct task_struct *task) { int retval; unsigned long flags; audit_ptrace(task); retval = -EPERM; if (same_thread_group(task, current)) goto out; repeat: /* * Nasty, nasty. * * We want to hold both the task-lock and the * tasklist_lock for writing at the same time. * But that's against the rules (tasklist_lock * is taken for reading by interrupts on other * cpu's that may have task_lock). */ task_lock(task); if (!write_trylock_irqsave(&tasklist_lock, flags)) { task_unlock(task); do { cpu_relax(); } while (!write_can_lock(&tasklist_lock)); goto repeat; } if (!task->mm) goto bad; /* the same process cannot be attached many times */ if (task->ptrace & PT_PTRACED) goto bad; retval = __ptrace_may_access(task, PTRACE_MODE_ATTACH); if (retval) goto bad; /* Go */ task->ptrace |= PT_PTRACED; if (capable_nolog(CAP_SYS_PTRACE)) task->ptrace |= PT_PTRACE_CAP; __ptrace_link(task, current); send_sig_info(SIGSTOP, SEND_SIG_FORCED, task); bad: write_unlock_irqrestore(&tasklist_lock, flags); task_unlock(task); out: return retval; }
/** * ptrace_traceme -- helper for PTRACE_TRACEME * * Performs checks and sets PT_PTRACED. * Should be used by all ptrace implementations for PTRACE_TRACEME. */ int ptrace_traceme(void) { int ret = -EPERM; /* * Are we already being traced? */ repeat: task_lock(current); if (!(current->ptrace & PT_PTRACED)) { /* * See ptrace_attach() comments about the locking here. */ unsigned long flags; if (!write_trylock_irqsave(&tasklist_lock, flags)) { task_unlock(current); do { cpu_relax(); } while (!write_can_lock(&tasklist_lock)); goto repeat; } ret = security_ptrace_traceme(current->parent); /* * Set the ptrace bit in the process ptrace flags. * Then link us on our parent's ptraced list. */ if (!ret) { current->ptrace |= PT_PTRACED; __ptrace_link(current, current->real_parent); } write_unlock_irqrestore(&tasklist_lock, flags); } task_unlock(current); return ret; }