Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
0002 #ifndef _LINUX_NSPROXY_H
0003 #define _LINUX_NSPROXY_H
0004 
0005 #include <linux/spinlock.h>
0006 #include <linux/sched.h>
0007 
0008 struct mnt_namespace;
0009 struct uts_namespace;
0010 struct ipc_namespace;
0011 struct pid_namespace;
0012 struct cgroup_namespace;
0013 struct fs_struct;
0014 
0015 /*
0016  * A structure to contain pointers to all per-process
0017  * namespaces - fs (mount), uts, network, sysvipc, etc.
0018  *
0019  * The pid namespace is an exception -- it's accessed using
0020  * task_active_pid_ns.  The pid namespace here is the
0021  * namespace that children will use.
0022  *
0023  * 'count' is the number of tasks holding a reference.
0024  * The count for each namespace, then, will be the number
0025  * of nsproxies pointing to it, not the number of tasks.
0026  *
0027  * The nsproxy is shared by tasks which share all namespaces.
0028  * As soon as a single namespace is cloned or unshared, the
0029  * nsproxy is copied.
0030  */
0031 struct nsproxy {
0032     atomic_t count;
0033     struct uts_namespace *uts_ns;
0034     struct ipc_namespace *ipc_ns;
0035     struct mnt_namespace *mnt_ns;
0036     struct pid_namespace *pid_ns_for_children;
0037     struct net       *net_ns;
0038     struct time_namespace *time_ns;
0039     struct time_namespace *time_ns_for_children;
0040     struct cgroup_namespace *cgroup_ns;
0041 };
0042 extern struct nsproxy init_nsproxy;
0043 
0044 /*
0045  * A structure to encompass all bits needed to install
0046  * a partial or complete new set of namespaces.
0047  *
0048  * If a new user namespace is requested cred will
0049  * point to a modifiable set of credentials. If a pointer
0050  * to a modifiable set is needed nsset_cred() must be
0051  * used and tested.
0052  */
0053 struct nsset {
0054     unsigned flags;
0055     struct nsproxy *nsproxy;
0056     struct fs_struct *fs;
0057     const struct cred *cred;
0058 };
0059 
0060 static inline struct cred *nsset_cred(struct nsset *set)
0061 {
0062     if (set->flags & CLONE_NEWUSER)
0063         return (struct cred *)set->cred;
0064 
0065     return NULL;
0066 }
0067 
0068 /*
0069  * the namespaces access rules are:
0070  *
0071  *  1. only current task is allowed to change tsk->nsproxy pointer or
0072  *     any pointer on the nsproxy itself.  Current must hold the task_lock
0073  *     when changing tsk->nsproxy.
0074  *
0075  *  2. when accessing (i.e. reading) current task's namespaces - no
0076  *     precautions should be taken - just dereference the pointers
0077  *
0078  *  3. the access to other task namespaces is performed like this
0079  *     task_lock(task);
0080  *     nsproxy = task->nsproxy;
0081  *     if (nsproxy != NULL) {
0082  *             / *
0083  *               * work with the namespaces here
0084  *               * e.g. get the reference on one of them
0085  *               * /
0086  *     } / *
0087  *         * NULL task->nsproxy means that this task is
0088  *         * almost dead (zombie)
0089  *         * /
0090  *     task_unlock(task);
0091  *
0092  */
0093 
0094 int copy_namespaces(unsigned long flags, struct task_struct *tsk);
0095 void exit_task_namespaces(struct task_struct *tsk);
0096 void switch_task_namespaces(struct task_struct *tsk, struct nsproxy *new);
0097 void free_nsproxy(struct nsproxy *ns);
0098 int unshare_nsproxy_namespaces(unsigned long, struct nsproxy **,
0099     struct cred *, struct fs_struct *);
0100 int __init nsproxy_cache_init(void);
0101 
0102 static inline void put_nsproxy(struct nsproxy *ns)
0103 {
0104     if (atomic_dec_and_test(&ns->count)) {
0105         free_nsproxy(ns);
0106     }
0107 }
0108 
0109 static inline void get_nsproxy(struct nsproxy *ns)
0110 {
0111     atomic_inc(&ns->count);
0112 }
0113 
0114 #endif