mirror of
https://github.com/torvalds/linux.git
synced 2024-11-26 14:12:06 +00:00
Merge branch 'next' into for-linus
This commit is contained in:
commit
cbacc2c7f0
582
Documentation/credentials.txt
Normal file
582
Documentation/credentials.txt
Normal file
@ -0,0 +1,582 @@
|
||||
====================
|
||||
CREDENTIALS IN LINUX
|
||||
====================
|
||||
|
||||
By: David Howells <dhowells@redhat.com>
|
||||
|
||||
Contents:
|
||||
|
||||
(*) Overview.
|
||||
|
||||
(*) Types of credentials.
|
||||
|
||||
(*) File markings.
|
||||
|
||||
(*) Task credentials.
|
||||
|
||||
- Immutable credentials.
|
||||
- Accessing task credentials.
|
||||
- Accessing another task's credentials.
|
||||
- Altering credentials.
|
||||
- Managing credentials.
|
||||
|
||||
(*) Open file credentials.
|
||||
|
||||
(*) Overriding the VFS's use of credentials.
|
||||
|
||||
|
||||
========
|
||||
OVERVIEW
|
||||
========
|
||||
|
||||
There are several parts to the security check performed by Linux when one
|
||||
object acts upon another:
|
||||
|
||||
(1) Objects.
|
||||
|
||||
Objects are things in the system that may be acted upon directly by
|
||||
userspace programs. Linux has a variety of actionable objects, including:
|
||||
|
||||
- Tasks
|
||||
- Files/inodes
|
||||
- Sockets
|
||||
- Message queues
|
||||
- Shared memory segments
|
||||
- Semaphores
|
||||
- Keys
|
||||
|
||||
As a part of the description of all these objects there is a set of
|
||||
credentials. What's in the set depends on the type of object.
|
||||
|
||||
(2) Object ownership.
|
||||
|
||||
Amongst the credentials of most objects, there will be a subset that
|
||||
indicates the ownership of that object. This is used for resource
|
||||
accounting and limitation (disk quotas and task rlimits for example).
|
||||
|
||||
In a standard UNIX filesystem, for instance, this will be defined by the
|
||||
UID marked on the inode.
|
||||
|
||||
(3) The objective context.
|
||||
|
||||
Also amongst the credentials of those objects, there will be a subset that
|
||||
indicates the 'objective context' of that object. This may or may not be
|
||||
the same set as in (2) - in standard UNIX files, for instance, this is the
|
||||
defined by the UID and the GID marked on the inode.
|
||||
|
||||
The objective context is used as part of the security calculation that is
|
||||
carried out when an object is acted upon.
|
||||
|
||||
(4) Subjects.
|
||||
|
||||
A subject is an object that is acting upon another object.
|
||||
|
||||
Most of the objects in the system are inactive: they don't act on other
|
||||
objects within the system. Processes/tasks are the obvious exception:
|
||||
they do stuff; they access and manipulate things.
|
||||
|
||||
Objects other than tasks may under some circumstances also be subjects.
|
||||
For instance an open file may send SIGIO to a task using the UID and EUID
|
||||
given to it by a task that called fcntl(F_SETOWN) upon it. In this case,
|
||||
the file struct will have a subjective context too.
|
||||
|
||||
(5) The subjective context.
|
||||
|
||||
A subject has an additional interpretation of its credentials. A subset
|
||||
of its credentials forms the 'subjective context'. The subjective context
|
||||
is used as part of the security calculation that is carried out when a
|
||||
subject acts.
|
||||
|
||||
A Linux task, for example, has the FSUID, FSGID and the supplementary
|
||||
group list for when it is acting upon a file - which are quite separate
|
||||
from the real UID and GID that normally form the objective context of the
|
||||
task.
|
||||
|
||||
(6) Actions.
|
||||
|
||||
Linux has a number of actions available that a subject may perform upon an
|
||||
object. The set of actions available depends on the nature of the subject
|
||||
and the object.
|
||||
|
||||
Actions include reading, writing, creating and deleting files; forking or
|
||||
signalling and tracing tasks.
|
||||
|
||||
(7) Rules, access control lists and security calculations.
|
||||
|
||||
When a subject acts upon an object, a security calculation is made. This
|
||||
involves taking the subjective context, the objective context and the
|
||||
action, and searching one or more sets of rules to see whether the subject
|
||||
is granted or denied permission to act in the desired manner on the
|
||||
object, given those contexts.
|
||||
|
||||
There are two main sources of rules:
|
||||
|
||||
(a) Discretionary access control (DAC):
|
||||
|
||||
Sometimes the object will include sets of rules as part of its
|
||||
description. This is an 'Access Control List' or 'ACL'. A Linux
|
||||
file may supply more than one ACL.
|
||||
|
||||
A traditional UNIX file, for example, includes a permissions mask that
|
||||
is an abbreviated ACL with three fixed classes of subject ('user',
|
||||
'group' and 'other'), each of which may be granted certain privileges
|
||||
('read', 'write' and 'execute' - whatever those map to for the object
|
||||
in question). UNIX file permissions do not allow the arbitrary
|
||||
specification of subjects, however, and so are of limited use.
|
||||
|
||||
A Linux file might also sport a POSIX ACL. This is a list of rules
|
||||
that grants various permissions to arbitrary subjects.
|
||||
|
||||
(b) Mandatory access control (MAC):
|
||||
|
||||
The system as a whole may have one or more sets of rules that get
|
||||
applied to all subjects and objects, regardless of their source.
|
||||
SELinux and Smack are examples of this.
|
||||
|
||||
In the case of SELinux and Smack, each object is given a label as part
|
||||
of its credentials. When an action is requested, they take the
|
||||
subject label, the object label and the action and look for a rule
|
||||
that says that this action is either granted or denied.
|
||||
|
||||
|
||||
====================
|
||||
TYPES OF CREDENTIALS
|
||||
====================
|
||||
|
||||
The Linux kernel supports the following types of credentials:
|
||||
|
||||
(1) Traditional UNIX credentials.
|
||||
|
||||
Real User ID
|
||||
Real Group ID
|
||||
|
||||
The UID and GID are carried by most, if not all, Linux objects, even if in
|
||||
some cases it has to be invented (FAT or CIFS files for example, which are
|
||||
derived from Windows). These (mostly) define the objective context of
|
||||
that object, with tasks being slightly different in some cases.
|
||||
|
||||
Effective, Saved and FS User ID
|
||||
Effective, Saved and FS Group ID
|
||||
Supplementary groups
|
||||
|
||||
These are additional credentials used by tasks only. Usually, an
|
||||
EUID/EGID/GROUPS will be used as the subjective context, and real UID/GID
|
||||
will be used as the objective. For tasks, it should be noted that this is
|
||||
not always true.
|
||||
|
||||
(2) Capabilities.
|
||||
|
||||
Set of permitted capabilities
|
||||
Set of inheritable capabilities
|
||||
Set of effective capabilities
|
||||
Capability bounding set
|
||||
|
||||
These are only carried by tasks. They indicate superior capabilities
|
||||
granted piecemeal to a task that an ordinary task wouldn't otherwise have.
|
||||
These are manipulated implicitly by changes to the traditional UNIX
|
||||
credentials, but can also be manipulated directly by the capset() system
|
||||
call.
|
||||
|
||||
The permitted capabilities are those caps that the process might grant
|
||||
itself to its effective or permitted sets through capset(). This
|
||||
inheritable set might also be so constrained.
|
||||
|
||||
The effective capabilities are the ones that a task is actually allowed to
|
||||
make use of itself.
|
||||
|
||||
The inheritable capabilities are the ones that may get passed across
|
||||
execve().
|
||||
|
||||
The bounding set limits the capabilities that may be inherited across
|
||||
execve(), especially when a binary is executed that will execute as UID 0.
|
||||
|
||||
(3) Secure management flags (securebits).
|
||||
|
||||
These are only carried by tasks. These govern the way the above
|
||||
credentials are manipulated and inherited over certain operations such as
|
||||
execve(). They aren't used directly as objective or subjective
|
||||
credentials.
|
||||
|
||||
(4) Keys and keyrings.
|
||||
|
||||
These are only carried by tasks. They carry and cache security tokens
|
||||
that don't fit into the other standard UNIX credentials. They are for
|
||||
making such things as network filesystem keys available to the file
|
||||
accesses performed by processes, without the necessity of ordinary
|
||||
programs having to know about security details involved.
|
||||
|
||||
Keyrings are a special type of key. They carry sets of other keys and can
|
||||
be searched for the desired key. Each process may subscribe to a number
|
||||
of keyrings:
|
||||
|
||||
Per-thread keying
|
||||
Per-process keyring
|
||||
Per-session keyring
|
||||
|
||||
When a process accesses a key, if not already present, it will normally be
|
||||
cached on one of these keyrings for future accesses to find.
|
||||
|
||||
For more information on using keys, see Documentation/keys.txt.
|
||||
|
||||
(5) LSM
|
||||
|
||||
The Linux Security Module allows extra controls to be placed over the
|
||||
operations that a task may do. Currently Linux supports two main
|
||||
alternate LSM options: SELinux and Smack.
|
||||
|
||||
Both work by labelling the objects in a system and then applying sets of
|
||||
rules (policies) that say what operations a task with one label may do to
|
||||
an object with another label.
|
||||
|
||||
(6) AF_KEY
|
||||
|
||||
This is a socket-based approach to credential management for networking
|
||||
stacks [RFC 2367]. It isn't discussed by this document as it doesn't
|
||||
interact directly with task and file credentials; rather it keeps system
|
||||
level credentials.
|
||||
|
||||
|
||||
When a file is opened, part of the opening task's subjective context is
|
||||
recorded in the file struct created. This allows operations using that file
|
||||
struct to use those credentials instead of the subjective context of the task
|
||||
that issued the operation. An example of this would be a file opened on a
|
||||
network filesystem where the credentials of the opened file should be presented
|
||||
to the server, regardless of who is actually doing a read or a write upon it.
|
||||
|
||||
|
||||
=============
|
||||
FILE MARKINGS
|
||||
=============
|
||||
|
||||
Files on disk or obtained over the network may have annotations that form the
|
||||
objective security context of that file. Depending on the type of filesystem,
|
||||
this may include one or more of the following:
|
||||
|
||||
(*) UNIX UID, GID, mode;
|
||||
|
||||
(*) Windows user ID;
|
||||
|
||||
(*) Access control list;
|
||||
|
||||
(*) LSM security label;
|
||||
|
||||
(*) UNIX exec privilege escalation bits (SUID/SGID);
|
||||
|
||||
(*) File capabilities exec privilege escalation bits.
|
||||
|
||||
These are compared to the task's subjective security context, and certain
|
||||
operations allowed or disallowed as a result. In the case of execve(), the
|
||||
privilege escalation bits come into play, and may allow the resulting process
|
||||
extra privileges, based on the annotations on the executable file.
|
||||
|
||||
|
||||
================
|
||||
TASK CREDENTIALS
|
||||
================
|
||||
|
||||
In Linux, all of a task's credentials are held in (uid, gid) or through
|
||||
(groups, keys, LSM security) a refcounted structure of type 'struct cred'.
|
||||
Each task points to its credentials by a pointer called 'cred' in its
|
||||
task_struct.
|
||||
|
||||
Once a set of credentials has been prepared and committed, it may not be
|
||||
changed, barring the following exceptions:
|
||||
|
||||
(1) its reference count may be changed;
|
||||
|
||||
(2) the reference count on the group_info struct it points to may be changed;
|
||||
|
||||
(3) the reference count on the security data it points to may be changed;
|
||||
|
||||
(4) the reference count on any keyrings it points to may be changed;
|
||||
|
||||
(5) any keyrings it points to may be revoked, expired or have their security
|
||||
attributes changed; and
|
||||
|
||||
(6) the contents of any keyrings to which it points may be changed (the whole
|
||||
point of keyrings being a shared set of credentials, modifiable by anyone
|
||||
with appropriate access).
|
||||
|
||||
To alter anything in the cred struct, the copy-and-replace principle must be
|
||||
adhered to. First take a copy, then alter the copy and then use RCU to change
|
||||
the task pointer to make it point to the new copy. There are wrappers to aid
|
||||
with this (see below).
|
||||
|
||||
A task may only alter its _own_ credentials; it is no longer permitted for a
|
||||
task to alter another's credentials. This means the capset() system call is no
|
||||
longer permitted to take any PID other than the one of the current process.
|
||||
Also keyctl_instantiate() and keyctl_negate() functions no longer permit
|
||||
attachment to process-specific keyrings in the requesting process as the
|
||||
instantiating process may need to create them.
|
||||
|
||||
|
||||
IMMUTABLE CREDENTIALS
|
||||
---------------------
|
||||
|
||||
Once a set of credentials has been made public (by calling commit_creds() for
|
||||
example), it must be considered immutable, barring two exceptions:
|
||||
|
||||
(1) The reference count may be altered.
|
||||
|
||||
(2) Whilst the keyring subscriptions of a set of credentials may not be
|
||||
changed, the keyrings subscribed to may have their contents altered.
|
||||
|
||||
To catch accidental credential alteration at compile time, struct task_struct
|
||||
has _const_ pointers to its credential sets, as does struct file. Furthermore,
|
||||
certain functions such as get_cred() and put_cred() operate on const pointers,
|
||||
thus rendering casts unnecessary, but require to temporarily ditch the const
|
||||
qualification to be able to alter the reference count.
|
||||
|
||||
|
||||
ACCESSING TASK CREDENTIALS
|
||||
--------------------------
|
||||
|
||||
A task being able to alter only its own credentials permits the current process
|
||||
to read or replace its own credentials without the need for any form of locking
|
||||
- which simplifies things greatly. It can just call:
|
||||
|
||||
const struct cred *current_cred()
|
||||
|
||||
to get a pointer to its credentials structure, and it doesn't have to release
|
||||
it afterwards.
|
||||
|
||||
There are convenience wrappers for retrieving specific aspects of a task's
|
||||
credentials (the value is simply returned in each case):
|
||||
|
||||
uid_t current_uid(void) Current's real UID
|
||||
gid_t current_gid(void) Current's real GID
|
||||
uid_t current_euid(void) Current's effective UID
|
||||
gid_t current_egid(void) Current's effective GID
|
||||
uid_t current_fsuid(void) Current's file access UID
|
||||
gid_t current_fsgid(void) Current's file access GID
|
||||
kernel_cap_t current_cap(void) Current's effective capabilities
|
||||
void *current_security(void) Current's LSM security pointer
|
||||
struct user_struct *current_user(void) Current's user account
|
||||
|
||||
There are also convenience wrappers for retrieving specific associated pairs of
|
||||
a task's credentials:
|
||||
|
||||
void current_uid_gid(uid_t *, gid_t *);
|
||||
void current_euid_egid(uid_t *, gid_t *);
|
||||
void current_fsuid_fsgid(uid_t *, gid_t *);
|
||||
|
||||
which return these pairs of values through their arguments after retrieving
|
||||
them from the current task's credentials.
|
||||
|
||||
|
||||
In addition, there is a function for obtaining a reference on the current
|
||||
process's current set of credentials:
|
||||
|
||||
const struct cred *get_current_cred(void);
|
||||
|
||||
and functions for getting references to one of the credentials that don't
|
||||
actually live in struct cred:
|
||||
|
||||
struct user_struct *get_current_user(void);
|
||||
struct group_info *get_current_groups(void);
|
||||
|
||||
which get references to the current process's user accounting structure and
|
||||
supplementary groups list respectively.
|
||||
|
||||
Once a reference has been obtained, it must be released with put_cred(),
|
||||
free_uid() or put_group_info() as appropriate.
|
||||
|
||||
|
||||
ACCESSING ANOTHER TASK'S CREDENTIALS
|
||||
------------------------------------
|
||||
|
||||
Whilst a task may access its own credentials without the need for locking, the
|
||||
same is not true of a task wanting to access another task's credentials. It
|
||||
must use the RCU read lock and rcu_dereference().
|
||||
|
||||
The rcu_dereference() is wrapped by:
|
||||
|
||||
const struct cred *__task_cred(struct task_struct *task);
|
||||
|
||||
This should be used inside the RCU read lock, as in the following example:
|
||||
|
||||
void foo(struct task_struct *t, struct foo_data *f)
|
||||
{
|
||||
const struct cred *tcred;
|
||||
...
|
||||
rcu_read_lock();
|
||||
tcred = __task_cred(t);
|
||||
f->uid = tcred->uid;
|
||||
f->gid = tcred->gid;
|
||||
f->groups = get_group_info(tcred->groups);
|
||||
rcu_read_unlock();
|
||||
...
|
||||
}
|
||||
|
||||
A function need not get RCU read lock to use __task_cred() if it is holding a
|
||||
spinlock at the time as this implicitly holds the RCU read lock.
|
||||
|
||||
Should it be necessary to hold another task's credentials for a long period of
|
||||
time, and possibly to sleep whilst doing so, then the caller should get a
|
||||
reference on them using:
|
||||
|
||||
const struct cred *get_task_cred(struct task_struct *task);
|
||||
|
||||
This does all the RCU magic inside of it. The caller must call put_cred() on
|
||||
the credentials so obtained when they're finished with.
|
||||
|
||||
There are a couple of convenience functions to access bits of another task's
|
||||
credentials, hiding the RCU magic from the caller:
|
||||
|
||||
uid_t task_uid(task) Task's real UID
|
||||
uid_t task_euid(task) Task's effective UID
|
||||
|
||||
If the caller is holding a spinlock or the RCU read lock at the time anyway,
|
||||
then:
|
||||
|
||||
__task_cred(task)->uid
|
||||
__task_cred(task)->euid
|
||||
|
||||
should be used instead. Similarly, if multiple aspects of a task's credentials
|
||||
need to be accessed, RCU read lock or a spinlock should be used, __task_cred()
|
||||
called, the result stored in a temporary pointer and then the credential
|
||||
aspects called from that before dropping the lock. This prevents the
|
||||
potentially expensive RCU magic from being invoked multiple times.
|
||||
|
||||
Should some other single aspect of another task's credentials need to be
|
||||
accessed, then this can be used:
|
||||
|
||||
task_cred_xxx(task, member)
|
||||
|
||||
where 'member' is a non-pointer member of the cred struct. For instance:
|
||||
|
||||
uid_t task_cred_xxx(task, suid);
|
||||
|
||||
will retrieve 'struct cred::suid' from the task, doing the appropriate RCU
|
||||
magic. This may not be used for pointer members as what they point to may
|
||||
disappear the moment the RCU read lock is dropped.
|
||||
|
||||
|
||||
ALTERING CREDENTIALS
|
||||
--------------------
|
||||
|
||||
As previously mentioned, a task may only alter its own credentials, and may not
|
||||
alter those of another task. This means that it doesn't need to use any
|
||||
locking to alter its own credentials.
|
||||
|
||||
To alter the current process's credentials, a function should first prepare a
|
||||
new set of credentials by calling:
|
||||
|
||||
struct cred *prepare_creds(void);
|
||||
|
||||
this locks current->cred_replace_mutex and then allocates and constructs a
|
||||
duplicate of the current process's credentials, returning with the mutex still
|
||||
held if successful. It returns NULL if not successful (out of memory).
|
||||
|
||||
The mutex prevents ptrace() from altering the ptrace state of a process whilst
|
||||
security checks on credentials construction and changing is taking place as
|
||||
the ptrace state may alter the outcome, particularly in the case of execve().
|
||||
|
||||
The new credentials set should be altered appropriately, and any security
|
||||
checks and hooks done. Both the current and the proposed sets of credentials
|
||||
are available for this purpose as current_cred() will return the current set
|
||||
still at this point.
|
||||
|
||||
|
||||
When the credential set is ready, it should be committed to the current process
|
||||
by calling:
|
||||
|
||||
int commit_creds(struct cred *new);
|
||||
|
||||
This will alter various aspects of the credentials and the process, giving the
|
||||
LSM a chance to do likewise, then it will use rcu_assign_pointer() to actually
|
||||
commit the new credentials to current->cred, it will release
|
||||
current->cred_replace_mutex to allow ptrace() to take place, and it will notify
|
||||
the scheduler and others of the changes.
|
||||
|
||||
This function is guaranteed to return 0, so that it can be tail-called at the
|
||||
end of such functions as sys_setresuid().
|
||||
|
||||
Note that this function consumes the caller's reference to the new credentials.
|
||||
The caller should _not_ call put_cred() on the new credentials afterwards.
|
||||
|
||||
Furthermore, once this function has been called on a new set of credentials,
|
||||
those credentials may _not_ be changed further.
|
||||
|
||||
|
||||
Should the security checks fail or some other error occur after prepare_creds()
|
||||
has been called, then the following function should be invoked:
|
||||
|
||||
void abort_creds(struct cred *new);
|
||||
|
||||
This releases the lock on current->cred_replace_mutex that prepare_creds() got
|
||||
and then releases the new credentials.
|
||||
|
||||
|
||||
A typical credentials alteration function would look something like this:
|
||||
|
||||
int alter_suid(uid_t suid)
|
||||
{
|
||||
struct cred *new;
|
||||
int ret;
|
||||
|
||||
new = prepare_creds();
|
||||
if (!new)
|
||||
return -ENOMEM;
|
||||
|
||||
new->suid = suid;
|
||||
ret = security_alter_suid(new);
|
||||
if (ret < 0) {
|
||||
abort_creds(new);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return commit_creds(new);
|
||||
}
|
||||
|
||||
|
||||
MANAGING CREDENTIALS
|
||||
--------------------
|
||||
|
||||
There are some functions to help manage credentials:
|
||||
|
||||
(*) void put_cred(const struct cred *cred);
|
||||
|
||||
This releases a reference to the given set of credentials. If the
|
||||
reference count reaches zero, the credentials will be scheduled for
|
||||
destruction by the RCU system.
|
||||
|
||||
(*) const struct cred *get_cred(const struct cred *cred);
|
||||
|
||||
This gets a reference on a live set of credentials, returning a pointer to
|
||||
that set of credentials.
|
||||
|
||||
(*) struct cred *get_new_cred(struct cred *cred);
|
||||
|
||||
This gets a reference on a set of credentials that is under construction
|
||||
and is thus still mutable, returning a pointer to that set of credentials.
|
||||
|
||||
|
||||
=====================
|
||||
OPEN FILE CREDENTIALS
|
||||
=====================
|
||||
|
||||
When a new file is opened, a reference is obtained on the opening task's
|
||||
credentials and this is attached to the file struct as 'f_cred' in place of
|
||||
'f_uid' and 'f_gid'. Code that used to access file->f_uid and file->f_gid
|
||||
should now access file->f_cred->fsuid and file->f_cred->fsgid.
|
||||
|
||||
It is safe to access f_cred without the use of RCU or locking because the
|
||||
pointer will not change over the lifetime of the file struct, and nor will the
|
||||
contents of the cred struct pointed to, barring the exceptions listed above
|
||||
(see the Task Credentials section).
|
||||
|
||||
|
||||
=======================================
|
||||
OVERRIDING THE VFS'S USE OF CREDENTIALS
|
||||
=======================================
|
||||
|
||||
Under some circumstances it is desirable to override the credentials used by
|
||||
the VFS, and that can be done by calling into such as vfs_mkdir() with a
|
||||
different set of credentials. This is done in the following places:
|
||||
|
||||
(*) sys_faccessat().
|
||||
|
||||
(*) do_coredump().
|
||||
|
||||
(*) nfs4recover.c.
|
@ -1452,6 +1452,10 @@ and is between 256 and 4096 characters. It is defined in the file
|
||||
instruction doesn't work correctly and not to
|
||||
use it.
|
||||
|
||||
no_file_caps Tells the kernel not to honor file capabilities. The
|
||||
only way then for a file to be executed with privilege
|
||||
is to be setuid root or executed by root.
|
||||
|
||||
nohalt [IA-64] Tells the kernel not to use the power saving
|
||||
function PAL_HALT_LIGHT when idle. This increases
|
||||
power-consumption. On the positive side, it reduces
|
||||
|
@ -273,3 +273,24 @@ task groups and modify their CPU share using the "cgroups" pseudo filesystem.
|
||||
|
||||
# #Launch gmplayer (or your favourite movie player)
|
||||
# echo <movie_player_pid> > multimedia/tasks
|
||||
|
||||
8. Implementation note: user namespaces
|
||||
|
||||
User namespaces are intended to be hierarchical. But they are currently
|
||||
only partially implemented. Each of those has ramifications for CFS.
|
||||
|
||||
First, since user namespaces are hierarchical, the /sys/kernel/uids
|
||||
presentation is inadequate. Eventually we will likely want to use sysfs
|
||||
tagging to provide private views of /sys/kernel/uids within each user
|
||||
namespace.
|
||||
|
||||
Second, the hierarchical nature is intended to support completely
|
||||
unprivileged use of user namespaces. So if using user groups, then
|
||||
we want the users in a user namespace to be children of the user
|
||||
who created it.
|
||||
|
||||
That is currently unimplemented. So instead, every user in a new
|
||||
user namespace will receive 1024 shares just like any user in the
|
||||
initial user namespace. Note that at the moment creation of a new
|
||||
user namespace requires each of CAP_SYS_ADMIN, CAP_SETUID, and
|
||||
CAP_SETGID.
|
||||
|
@ -19,15 +19,18 @@ void foo(void)
|
||||
BLANK();
|
||||
|
||||
DEFINE(TASK_BLOCKED, offsetof(struct task_struct, blocked));
|
||||
DEFINE(TASK_UID, offsetof(struct task_struct, uid));
|
||||
DEFINE(TASK_EUID, offsetof(struct task_struct, euid));
|
||||
DEFINE(TASK_GID, offsetof(struct task_struct, gid));
|
||||
DEFINE(TASK_EGID, offsetof(struct task_struct, egid));
|
||||
DEFINE(TASK_CRED, offsetof(struct task_struct, cred));
|
||||
DEFINE(TASK_REAL_PARENT, offsetof(struct task_struct, real_parent));
|
||||
DEFINE(TASK_GROUP_LEADER, offsetof(struct task_struct, group_leader));
|
||||
DEFINE(TASK_TGID, offsetof(struct task_struct, tgid));
|
||||
BLANK();
|
||||
|
||||
DEFINE(CRED_UID, offsetof(struct cred, uid));
|
||||
DEFINE(CRED_EUID, offsetof(struct cred, euid));
|
||||
DEFINE(CRED_GID, offsetof(struct cred, gid));
|
||||
DEFINE(CRED_EGID, offsetof(struct cred, egid));
|
||||
BLANK();
|
||||
|
||||
DEFINE(SIZEOF_PT_REGS, sizeof(struct pt_regs));
|
||||
DEFINE(PT_PTRACED, PT_PTRACED);
|
||||
DEFINE(CLONE_VM, CLONE_VM);
|
||||
|
@ -850,8 +850,9 @@ osf_getpriority:
|
||||
sys_getxuid:
|
||||
.prologue 0
|
||||
ldq $2, TI_TASK($8)
|
||||
ldl $0, TASK_UID($2)
|
||||
ldl $1, TASK_EUID($2)
|
||||
ldq $3, TASK_CRED($2)
|
||||
ldl $0, CRED_UID($3)
|
||||
ldl $1, CRED_EUID($3)
|
||||
stq $1, 80($sp)
|
||||
ret
|
||||
.end sys_getxuid
|
||||
@ -862,8 +863,9 @@ sys_getxuid:
|
||||
sys_getxgid:
|
||||
.prologue 0
|
||||
ldq $2, TI_TASK($8)
|
||||
ldl $0, TASK_GID($2)
|
||||
ldl $1, TASK_EGID($2)
|
||||
ldq $3, TASK_CRED($2)
|
||||
ldl $0, CRED_GID($3)
|
||||
ldl $1, CRED_EGID($3)
|
||||
stq $1, 80($sp)
|
||||
ret
|
||||
.end sys_getxgid
|
||||
|
@ -1767,25 +1767,24 @@ groups16_from_user(struct group_info *group_info, short __user *grouplist)
|
||||
asmlinkage long
|
||||
sys32_getgroups16 (int gidsetsize, short __user *grouplist)
|
||||
{
|
||||
const struct cred *cred = current_cred();
|
||||
int i;
|
||||
|
||||
if (gidsetsize < 0)
|
||||
return -EINVAL;
|
||||
|
||||
get_group_info(current->group_info);
|
||||
i = current->group_info->ngroups;
|
||||
i = cred->group_info->ngroups;
|
||||
if (gidsetsize) {
|
||||
if (i > gidsetsize) {
|
||||
i = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
if (groups16_to_user(grouplist, current->group_info)) {
|
||||
if (groups16_to_user(grouplist, cred->group_info)) {
|
||||
i = -EFAULT;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
out:
|
||||
put_group_info(current->group_info);
|
||||
return i;
|
||||
}
|
||||
|
||||
|
@ -158,7 +158,7 @@ mca_handler_bh(unsigned long paddr, void *iip, unsigned long ipsr)
|
||||
ia64_mlogbuf_dump();
|
||||
printk(KERN_ERR "OS_MCA: process [cpu %d, pid: %d, uid: %d, "
|
||||
"iip: %p, psr: 0x%lx,paddr: 0x%lx](%s) encounters MCA.\n",
|
||||
raw_smp_processor_id(), current->pid, current->uid,
|
||||
raw_smp_processor_id(), current->pid, current_uid(),
|
||||
iip, ipsr, paddr, current->comm);
|
||||
|
||||
spin_lock(&mca_bh_lock);
|
||||
|
@ -2220,8 +2220,8 @@ pfm_alloc_file(pfm_context_t *ctx)
|
||||
DPRINT(("new inode ino=%ld @%p\n", inode->i_ino, inode));
|
||||
|
||||
inode->i_mode = S_IFCHR|S_IRUGO;
|
||||
inode->i_uid = current->fsuid;
|
||||
inode->i_gid = current->fsgid;
|
||||
inode->i_uid = current_fsuid();
|
||||
inode->i_gid = current_fsgid();
|
||||
|
||||
sprintf(name, "[%lu]", inode->i_ino);
|
||||
this.name = name;
|
||||
@ -2399,22 +2399,33 @@ error_kmem:
|
||||
static int
|
||||
pfm_bad_permissions(struct task_struct *task)
|
||||
{
|
||||
const struct cred *tcred;
|
||||
uid_t uid = current_uid();
|
||||
gid_t gid = current_gid();
|
||||
int ret;
|
||||
|
||||
rcu_read_lock();
|
||||
tcred = __task_cred(task);
|
||||
|
||||
/* inspired by ptrace_attach() */
|
||||
DPRINT(("cur: uid=%d gid=%d task: euid=%d suid=%d uid=%d egid=%d sgid=%d\n",
|
||||
current->uid,
|
||||
current->gid,
|
||||
task->euid,
|
||||
task->suid,
|
||||
task->uid,
|
||||
task->egid,
|
||||
task->sgid));
|
||||
uid,
|
||||
gid,
|
||||
tcred->euid,
|
||||
tcred->suid,
|
||||
tcred->uid,
|
||||
tcred->egid,
|
||||
tcred->sgid));
|
||||
|
||||
return ((current->uid != task->euid)
|
||||
|| (current->uid != task->suid)
|
||||
|| (current->uid != task->uid)
|
||||
|| (current->gid != task->egid)
|
||||
|| (current->gid != task->sgid)
|
||||
|| (current->gid != task->gid)) && !capable(CAP_SYS_PTRACE);
|
||||
ret = ((uid != tcred->euid)
|
||||
|| (uid != tcred->suid)
|
||||
|| (uid != tcred->uid)
|
||||
|| (gid != tcred->egid)
|
||||
|| (gid != tcred->sgid)
|
||||
|| (gid != tcred->gid)) && !capable(CAP_SYS_PTRACE);
|
||||
|
||||
rcu_read_unlock();
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -229,7 +229,7 @@ ia64_rt_sigreturn (struct sigscratch *scr)
|
||||
si.si_errno = 0;
|
||||
si.si_code = SI_KERNEL;
|
||||
si.si_pid = task_pid_vnr(current);
|
||||
si.si_uid = current->uid;
|
||||
si.si_uid = current_uid();
|
||||
si.si_addr = sc;
|
||||
force_sig_info(SIGSEGV, &si, current);
|
||||
return retval;
|
||||
@ -326,7 +326,7 @@ force_sigsegv_info (int sig, void __user *addr)
|
||||
si.si_errno = 0;
|
||||
si.si_code = SI_KERNEL;
|
||||
si.si_pid = task_pid_vnr(current);
|
||||
si.si_uid = current->uid;
|
||||
si.si_uid = current_uid();
|
||||
si.si_addr = addr;
|
||||
force_sig_info(SIGSEGV, &si, current);
|
||||
return 0;
|
||||
|
@ -174,8 +174,8 @@ static unsigned int translate_open_flags(int flags)
|
||||
|
||||
static void sp_setfsuidgid( uid_t uid, gid_t gid)
|
||||
{
|
||||
current->fsuid = uid;
|
||||
current->fsgid = gid;
|
||||
current->cred->fsuid = uid;
|
||||
current->cred->fsgid = gid;
|
||||
|
||||
key_fsuid_changed(current);
|
||||
key_fsgid_changed(current);
|
||||
|
@ -51,6 +51,7 @@ asmlinkage long mipsmt_sys_sched_setaffinity(pid_t pid, unsigned int len,
|
||||
int retval;
|
||||
struct task_struct *p;
|
||||
struct thread_info *ti;
|
||||
uid_t euid;
|
||||
|
||||
if (len < sizeof(new_mask))
|
||||
return -EINVAL;
|
||||
@ -76,9 +77,9 @@ asmlinkage long mipsmt_sys_sched_setaffinity(pid_t pid, unsigned int len,
|
||||
*/
|
||||
get_task_struct(p);
|
||||
|
||||
euid = current_euid();
|
||||
retval = -EPERM;
|
||||
if ((current->euid != p->euid) && (current->euid != p->uid) &&
|
||||
!capable(CAP_SYS_NICE)) {
|
||||
if (euid != p->euid && euid != p->uid && !capable(CAP_SYS_NICE)) {
|
||||
read_unlock(&tasklist_lock);
|
||||
goto out_unlock;
|
||||
}
|
||||
|
@ -1085,8 +1085,8 @@ static int vpe_open(struct inode *inode, struct file *filp)
|
||||
v->load_addr = NULL;
|
||||
v->len = 0;
|
||||
|
||||
v->uid = filp->f_uid;
|
||||
v->gid = filp->f_gid;
|
||||
v->uid = filp->f_cred->fsuid;
|
||||
v->gid = filp->f_cred->fsgid;
|
||||
|
||||
#ifdef CONFIG_MIPS_APSP_KSPD
|
||||
/* get kspd to tell us when a syscall_exit happens */
|
||||
|
@ -182,7 +182,7 @@ give_sigsegv:
|
||||
si.si_errno = 0;
|
||||
si.si_code = SI_KERNEL;
|
||||
si.si_pid = task_pid_vnr(current);
|
||||
si.si_uid = current->uid;
|
||||
si.si_uid = current_uid();
|
||||
si.si_addr = &frame->uc;
|
||||
force_sig_info(SIGSEGV, &si, current);
|
||||
return;
|
||||
|
@ -339,7 +339,7 @@ bad_area_nosemaphore:
|
||||
&& printk_ratelimit())
|
||||
printk(KERN_CRIT "kernel tried to execute NX-protected"
|
||||
" page (%lx) - exploit attempt? (uid: %d)\n",
|
||||
address, current->uid);
|
||||
address, current_uid());
|
||||
|
||||
return SIGSEGV;
|
||||
|
||||
|
@ -95,8 +95,8 @@ spufs_new_inode(struct super_block *sb, int mode)
|
||||
goto out;
|
||||
|
||||
inode->i_mode = mode;
|
||||
inode->i_uid = current->fsuid;
|
||||
inode->i_gid = current->fsgid;
|
||||
inode->i_uid = current_fsuid();
|
||||
inode->i_gid = current_fsgid();
|
||||
inode->i_blocks = 0;
|
||||
inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
|
||||
out:
|
||||
@ -323,7 +323,7 @@ static int spufs_context_open(struct dentry *dentry, struct vfsmount *mnt)
|
||||
goto out;
|
||||
}
|
||||
|
||||
filp = dentry_open(dentry, mnt, O_RDONLY);
|
||||
filp = dentry_open(dentry, mnt, O_RDONLY, current_cred());
|
||||
if (IS_ERR(filp)) {
|
||||
put_unused_fd(ret);
|
||||
ret = PTR_ERR(filp);
|
||||
@ -562,7 +562,7 @@ static int spufs_gang_open(struct dentry *dentry, struct vfsmount *mnt)
|
||||
goto out;
|
||||
}
|
||||
|
||||
filp = dentry_open(dentry, mnt, O_RDONLY);
|
||||
filp = dentry_open(dentry, mnt, O_RDONLY, current_cred());
|
||||
if (IS_ERR(filp)) {
|
||||
put_unused_fd(ret);
|
||||
ret = PTR_ERR(filp);
|
||||
|
@ -280,8 +280,8 @@ static int hypfs_fill_super(struct super_block *sb, void *data, int silent)
|
||||
if (!sbi)
|
||||
return -ENOMEM;
|
||||
mutex_init(&sbi->lock);
|
||||
sbi->uid = current->uid;
|
||||
sbi->gid = current->gid;
|
||||
sbi->uid = current_uid();
|
||||
sbi->gid = current_gid();
|
||||
sb->s_fs_info = sbi;
|
||||
sb->s_blocksize = PAGE_CACHE_SIZE;
|
||||
sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
|
||||
|
@ -148,9 +148,9 @@ asmlinkage long sys32_getresuid16(u16 __user *ruid, u16 __user *euid, u16 __user
|
||||
{
|
||||
int retval;
|
||||
|
||||
if (!(retval = put_user(high2lowuid(current->uid), ruid)) &&
|
||||
!(retval = put_user(high2lowuid(current->euid), euid)))
|
||||
retval = put_user(high2lowuid(current->suid), suid);
|
||||
if (!(retval = put_user(high2lowuid(current->cred->uid), ruid)) &&
|
||||
!(retval = put_user(high2lowuid(current->cred->euid), euid)))
|
||||
retval = put_user(high2lowuid(current->cred->suid), suid);
|
||||
|
||||
return retval;
|
||||
}
|
||||
@ -165,9 +165,9 @@ asmlinkage long sys32_getresgid16(u16 __user *rgid, u16 __user *egid, u16 __user
|
||||
{
|
||||
int retval;
|
||||
|
||||
if (!(retval = put_user(high2lowgid(current->gid), rgid)) &&
|
||||
!(retval = put_user(high2lowgid(current->egid), egid)))
|
||||
retval = put_user(high2lowgid(current->sgid), sgid);
|
||||
if (!(retval = put_user(high2lowgid(current->cred->gid), rgid)) &&
|
||||
!(retval = put_user(high2lowgid(current->cred->egid), egid)))
|
||||
retval = put_user(high2lowgid(current->cred->sgid), sgid);
|
||||
|
||||
return retval;
|
||||
}
|
||||
@ -217,20 +217,20 @@ asmlinkage long sys32_getgroups16(int gidsetsize, u16 __user *grouplist)
|
||||
if (gidsetsize < 0)
|
||||
return -EINVAL;
|
||||
|
||||
get_group_info(current->group_info);
|
||||
i = current->group_info->ngroups;
|
||||
get_group_info(current->cred->group_info);
|
||||
i = current->cred->group_info->ngroups;
|
||||
if (gidsetsize) {
|
||||
if (i > gidsetsize) {
|
||||
i = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
if (groups16_to_user(grouplist, current->group_info)) {
|
||||
if (groups16_to_user(grouplist, current->cred->group_info)) {
|
||||
i = -EFAULT;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
out:
|
||||
put_group_info(current->group_info);
|
||||
put_group_info(current->cred->group_info);
|
||||
return i;
|
||||
}
|
||||
|
||||
@ -261,22 +261,22 @@ asmlinkage long sys32_setgroups16(int gidsetsize, u16 __user *grouplist)
|
||||
|
||||
asmlinkage long sys32_getuid16(void)
|
||||
{
|
||||
return high2lowuid(current->uid);
|
||||
return high2lowuid(current->cred->uid);
|
||||
}
|
||||
|
||||
asmlinkage long sys32_geteuid16(void)
|
||||
{
|
||||
return high2lowuid(current->euid);
|
||||
return high2lowuid(current->cred->euid);
|
||||
}
|
||||
|
||||
asmlinkage long sys32_getgid16(void)
|
||||
{
|
||||
return high2lowgid(current->gid);
|
||||
return high2lowgid(current->cred->gid);
|
||||
}
|
||||
|
||||
asmlinkage long sys32_getegid16(void)
|
||||
{
|
||||
return high2lowgid(current->egid);
|
||||
return high2lowgid(current->cred->egid);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -161,7 +161,8 @@ void mconsole_proc(struct mc_request *req)
|
||||
goto out_kill;
|
||||
}
|
||||
|
||||
file = dentry_open(nd.path.dentry, nd.path.mnt, O_RDONLY);
|
||||
file = dentry_open(nd.path.dentry, nd.path.mnt, O_RDONLY,
|
||||
current_cred());
|
||||
if (IS_ERR(file)) {
|
||||
mconsole_reply(req, "Failed to open file", 1, 0);
|
||||
goto out_kill;
|
||||
|
@ -327,7 +327,7 @@ static int load_aout_binary(struct linux_binprm *bprm, struct pt_regs *regs)
|
||||
current->mm->cached_hole_size = 0;
|
||||
|
||||
current->mm->mmap = NULL;
|
||||
compute_creds(bprm);
|
||||
install_exec_creds(bprm);
|
||||
current->flags &= ~PF_FORKNOEXEC;
|
||||
|
||||
if (N_MAGIC(ex) == OMAGIC) {
|
||||
|
@ -393,7 +393,7 @@ static void show_fault_oops(struct pt_regs *regs, unsigned long error_code,
|
||||
if (pte && pte_present(*pte) && !pte_exec(*pte))
|
||||
printk(KERN_CRIT "kernel tried to execute "
|
||||
"NX-protected page - exploit attempt? "
|
||||
"(uid: %d)\n", current->uid);
|
||||
"(uid: %d)\n", current_uid());
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -936,8 +936,10 @@ loop_set_status(struct loop_device *lo, const struct loop_info64 *info)
|
||||
{
|
||||
int err;
|
||||
struct loop_func_table *xfer;
|
||||
uid_t uid = current_uid();
|
||||
|
||||
if (lo->lo_encrypt_key_size && lo->lo_key_owner != current->uid &&
|
||||
if (lo->lo_encrypt_key_size &&
|
||||
lo->lo_key_owner != uid &&
|
||||
!capable(CAP_SYS_ADMIN))
|
||||
return -EPERM;
|
||||
if (lo->lo_state != Lo_bound)
|
||||
@ -992,7 +994,7 @@ loop_set_status(struct loop_device *lo, const struct loop_info64 *info)
|
||||
if (info->lo_encrypt_key_size) {
|
||||
memcpy(lo->lo_encrypt_key, info->lo_encrypt_key,
|
||||
info->lo_encrypt_key_size);
|
||||
lo->lo_key_owner = current->uid;
|
||||
lo->lo_key_owner = uid;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -67,6 +67,29 @@ static void tty_audit_buf_put(struct tty_audit_buf *buf)
|
||||
tty_audit_buf_free(buf);
|
||||
}
|
||||
|
||||
static void tty_audit_log(const char *description, struct task_struct *tsk,
|
||||
uid_t loginuid, unsigned sessionid, int major,
|
||||
int minor, unsigned char *data, size_t size)
|
||||
{
|
||||
struct audit_buffer *ab;
|
||||
|
||||
ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_TTY);
|
||||
if (ab) {
|
||||
char name[sizeof(tsk->comm)];
|
||||
uid_t uid = task_uid(tsk);
|
||||
|
||||
audit_log_format(ab, "%s pid=%u uid=%u auid=%u ses=%u "
|
||||
"major=%d minor=%d comm=", description,
|
||||
tsk->pid, uid, loginuid, sessionid,
|
||||
major, minor);
|
||||
get_task_comm(name, tsk);
|
||||
audit_log_untrustedstring(ab, name);
|
||||
audit_log_format(ab, " data=");
|
||||
audit_log_n_hex(ab, data, size);
|
||||
audit_log_end(ab);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* tty_audit_buf_push - Push buffered data out
|
||||
*
|
||||
@ -77,25 +100,12 @@ static void tty_audit_buf_push(struct task_struct *tsk, uid_t loginuid,
|
||||
unsigned int sessionid,
|
||||
struct tty_audit_buf *buf)
|
||||
{
|
||||
struct audit_buffer *ab;
|
||||
|
||||
if (buf->valid == 0)
|
||||
return;
|
||||
if (audit_enabled == 0)
|
||||
return;
|
||||
ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_TTY);
|
||||
if (ab) {
|
||||
char name[sizeof(tsk->comm)];
|
||||
|
||||
audit_log_format(ab, "tty pid=%u uid=%u auid=%u ses=%u "
|
||||
"major=%d minor=%d comm=", tsk->pid, tsk->uid,
|
||||
loginuid, sessionid, buf->major, buf->minor);
|
||||
get_task_comm(name, tsk);
|
||||
audit_log_untrustedstring(ab, name);
|
||||
audit_log_format(ab, " data=");
|
||||
audit_log_n_hex(ab, buf->data, buf->valid);
|
||||
audit_log_end(ab);
|
||||
}
|
||||
tty_audit_log("tty", tsk, loginuid, sessionid, buf->major, buf->minor,
|
||||
buf->data, buf->valid);
|
||||
buf->valid = 0;
|
||||
}
|
||||
|
||||
@ -149,6 +159,42 @@ void tty_audit_fork(struct signal_struct *sig)
|
||||
sig->tty_audit_buf = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* tty_audit_tiocsti - Log TIOCSTI
|
||||
*/
|
||||
void tty_audit_tiocsti(struct tty_struct *tty, char ch)
|
||||
{
|
||||
struct tty_audit_buf *buf;
|
||||
int major, minor, should_audit;
|
||||
|
||||
spin_lock_irq(¤t->sighand->siglock);
|
||||
should_audit = current->signal->audit_tty;
|
||||
buf = current->signal->tty_audit_buf;
|
||||
if (buf)
|
||||
atomic_inc(&buf->count);
|
||||
spin_unlock_irq(¤t->sighand->siglock);
|
||||
|
||||
major = tty->driver->major;
|
||||
minor = tty->driver->minor_start + tty->index;
|
||||
if (buf) {
|
||||
mutex_lock(&buf->mutex);
|
||||
if (buf->major == major && buf->minor == minor)
|
||||
tty_audit_buf_push_current(buf);
|
||||
mutex_unlock(&buf->mutex);
|
||||
tty_audit_buf_put(buf);
|
||||
}
|
||||
|
||||
if (should_audit && audit_enabled) {
|
||||
uid_t auid;
|
||||
unsigned int sessionid;
|
||||
|
||||
auid = audit_get_loginuid(current);
|
||||
sessionid = audit_get_sessionid(current);
|
||||
tty_audit_log("ioctl=TIOCSTI", current, auid, sessionid, major,
|
||||
minor, &ch, 1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* tty_audit_push_task - Flush task's pending audit data
|
||||
*/
|
||||
|
@ -2018,6 +2018,7 @@ static int tiocsti(struct tty_struct *tty, char __user *p)
|
||||
return -EPERM;
|
||||
if (get_user(ch, p))
|
||||
return -EFAULT;
|
||||
tty_audit_tiocsti(tty, ch);
|
||||
ld = tty_ldisc_ref_wait(tty);
|
||||
ld->ops->receive_buf(tty, &ch, &mbz, 1);
|
||||
tty_ldisc_deref(ld);
|
||||
|
@ -106,6 +106,7 @@ void proc_id_connector(struct task_struct *task, int which_id)
|
||||
struct proc_event *ev;
|
||||
__u8 buffer[CN_PROC_MSG_SIZE];
|
||||
struct timespec ts;
|
||||
const struct cred *cred;
|
||||
|
||||
if (atomic_read(&proc_event_num_listeners) < 1)
|
||||
return;
|
||||
@ -115,14 +116,19 @@ void proc_id_connector(struct task_struct *task, int which_id)
|
||||
ev->what = which_id;
|
||||
ev->event_data.id.process_pid = task->pid;
|
||||
ev->event_data.id.process_tgid = task->tgid;
|
||||
rcu_read_lock();
|
||||
cred = __task_cred(task);
|
||||
if (which_id == PROC_EVENT_UID) {
|
||||
ev->event_data.id.r.ruid = task->uid;
|
||||
ev->event_data.id.e.euid = task->euid;
|
||||
ev->event_data.id.r.ruid = cred->uid;
|
||||
ev->event_data.id.e.euid = cred->euid;
|
||||
} else if (which_id == PROC_EVENT_GID) {
|
||||
ev->event_data.id.r.rgid = task->gid;
|
||||
ev->event_data.id.e.egid = task->egid;
|
||||
} else
|
||||
ev->event_data.id.r.rgid = cred->gid;
|
||||
ev->event_data.id.e.egid = cred->egid;
|
||||
} else {
|
||||
rcu_read_unlock();
|
||||
return;
|
||||
}
|
||||
rcu_read_unlock();
|
||||
get_seq(&msg->seq, &ev->cpu);
|
||||
ktime_get_ts(&ts); /* get high res monotonic timestamp */
|
||||
put_unaligned(timespec_to_ns(&ts), (__u64 *)&ev->timestamp_ns);
|
||||
|
@ -156,8 +156,8 @@ void capifs_new_ncci(unsigned int number, dev_t device)
|
||||
if (!inode)
|
||||
return;
|
||||
inode->i_ino = number+2;
|
||||
inode->i_uid = config.setuid ? config.uid : current->fsuid;
|
||||
inode->i_gid = config.setgid ? config.gid : current->fsgid;
|
||||
inode->i_uid = config.setuid ? config.uid : current_fsuid();
|
||||
inode->i_gid = config.setgid ? config.gid : current_fsgid();
|
||||
inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
|
||||
init_special_inode(inode, S_IFCHR|config.mode, device);
|
||||
//inode->i_op = &capifs_file_inode_operations;
|
||||
|
@ -246,7 +246,8 @@ hysdn_conf_open(struct inode *ino, struct file *filep)
|
||||
}
|
||||
if (card->debug_flags & (LOG_PROC_OPEN | LOG_PROC_ALL))
|
||||
hysdn_addlog(card, "config open for uid=%d gid=%d mode=0x%x",
|
||||
filep->f_uid, filep->f_gid, filep->f_mode);
|
||||
filep->f_cred->fsuid, filep->f_cred->fsgid,
|
||||
filep->f_mode);
|
||||
|
||||
if ((filep->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_WRITE) {
|
||||
/* write only access -> write boot file or conf line */
|
||||
@ -331,7 +332,8 @@ hysdn_conf_close(struct inode *ino, struct file *filep)
|
||||
}
|
||||
if (card->debug_flags & (LOG_PROC_OPEN | LOG_PROC_ALL))
|
||||
hysdn_addlog(card, "config close for uid=%d gid=%d mode=0x%x",
|
||||
filep->f_uid, filep->f_gid, filep->f_mode);
|
||||
filep->f_cred->fsuid, filep->f_cred->fsgid,
|
||||
filep->f_mode);
|
||||
|
||||
if ((filep->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_WRITE) {
|
||||
/* write only access -> write boot file or conf line */
|
||||
|
@ -702,6 +702,7 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
|
||||
struct tun_net *tn;
|
||||
struct tun_struct *tun;
|
||||
struct net_device *dev;
|
||||
const struct cred *cred = current_cred();
|
||||
int err;
|
||||
|
||||
tn = net_generic(net, tun_net_id);
|
||||
@ -712,11 +713,12 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
|
||||
|
||||
/* Check permissions */
|
||||
if (((tun->owner != -1 &&
|
||||
current->euid != tun->owner) ||
|
||||
cred->euid != tun->owner) ||
|
||||
(tun->group != -1 &&
|
||||
current->egid != tun->group)) &&
|
||||
!capable(CAP_NET_ADMIN))
|
||||
cred->egid != tun->group)) &&
|
||||
!capable(CAP_NET_ADMIN)) {
|
||||
return -EPERM;
|
||||
}
|
||||
}
|
||||
else if (__dev_get_by_name(net, ifr->ifr_name))
|
||||
return -EINVAL;
|
||||
|
@ -574,6 +574,7 @@ static int usbdev_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
struct usb_device *dev = NULL;
|
||||
struct dev_state *ps;
|
||||
const struct cred *cred = current_cred();
|
||||
int ret;
|
||||
|
||||
lock_kernel();
|
||||
@ -617,8 +618,8 @@ static int usbdev_open(struct inode *inode, struct file *file)
|
||||
init_waitqueue_head(&ps->wait);
|
||||
ps->discsignr = 0;
|
||||
ps->disc_pid = get_pid(task_pid(current));
|
||||
ps->disc_uid = current->uid;
|
||||
ps->disc_euid = current->euid;
|
||||
ps->disc_uid = cred->uid;
|
||||
ps->disc_euid = cred->euid;
|
||||
ps->disccontext = NULL;
|
||||
ps->ifclaimed = 0;
|
||||
security_task_getsecid(current, &ps->secid);
|
||||
@ -967,6 +968,7 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb,
|
||||
struct usb_host_endpoint *ep;
|
||||
struct async *as;
|
||||
struct usb_ctrlrequest *dr = NULL;
|
||||
const struct cred *cred = current_cred();
|
||||
unsigned int u, totlen, isofrmlen;
|
||||
int ret, ifnum = -1;
|
||||
int is_in;
|
||||
@ -1174,8 +1176,8 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb,
|
||||
as->signr = uurb->signr;
|
||||
as->ifnum = ifnum;
|
||||
as->pid = get_pid(task_pid(current));
|
||||
as->uid = current->uid;
|
||||
as->euid = current->euid;
|
||||
as->uid = cred->uid;
|
||||
as->euid = cred->euid;
|
||||
security_task_getsecid(current, &as->secid);
|
||||
if (!is_in) {
|
||||
if (copy_from_user(as->urb->transfer_buffer, uurb->buffer,
|
||||
|
@ -277,8 +277,8 @@ static struct inode *usbfs_get_inode (struct super_block *sb, int mode, dev_t de
|
||||
|
||||
if (inode) {
|
||||
inode->i_mode = mode;
|
||||
inode->i_uid = current->fsuid;
|
||||
inode->i_gid = current->fsgid;
|
||||
inode->i_uid = current_fsuid();
|
||||
inode->i_gid = current_fsgid();
|
||||
inode->i_blocks = 0;
|
||||
inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
|
||||
switch (mode & S_IFMT) {
|
||||
|
@ -120,7 +120,7 @@ struct p9_fid *v9fs_fid_lookup(struct dentry *dentry)
|
||||
switch (access) {
|
||||
case V9FS_ACCESS_SINGLE:
|
||||
case V9FS_ACCESS_USER:
|
||||
uid = current->fsuid;
|
||||
uid = current_fsuid();
|
||||
any = 0;
|
||||
break;
|
||||
|
||||
|
@ -215,8 +215,8 @@ struct inode *v9fs_get_inode(struct super_block *sb, int mode)
|
||||
inode = new_inode(sb);
|
||||
if (inode) {
|
||||
inode->i_mode = mode;
|
||||
inode->i_uid = current->fsuid;
|
||||
inode->i_gid = current->fsgid;
|
||||
inode->i_uid = current_fsuid();
|
||||
inode->i_gid = current_fsgid();
|
||||
inode->i_blocks = 0;
|
||||
inode->i_rdev = 0;
|
||||
inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
|
||||
|
@ -113,8 +113,8 @@ static int v9fs_get_sb(struct file_system_type *fs_type, int flags,
|
||||
struct v9fs_session_info *v9ses = NULL;
|
||||
struct p9_wstat *st = NULL;
|
||||
int mode = S_IRWXUGO | S_ISVTX;
|
||||
uid_t uid = current->fsuid;
|
||||
gid_t gid = current->fsgid;
|
||||
uid_t uid = current_fsuid();
|
||||
gid_t gid = current_fsgid();
|
||||
struct p9_fid *fid;
|
||||
int retval = 0;
|
||||
|
||||
|
@ -293,8 +293,8 @@ affs_new_inode(struct inode *dir)
|
||||
mark_buffer_dirty_inode(bh, inode);
|
||||
affs_brelse(bh);
|
||||
|
||||
inode->i_uid = current->fsuid;
|
||||
inode->i_gid = current->fsgid;
|
||||
inode->i_uid = current_fsuid();
|
||||
inode->i_gid = current_fsgid();
|
||||
inode->i_ino = block;
|
||||
inode->i_nlink = 1;
|
||||
inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME_SEC;
|
||||
|
@ -163,8 +163,8 @@ parse_options(char *options, uid_t *uid, gid_t *gid, int *mode, int *reserved, s
|
||||
|
||||
/* Fill in defaults */
|
||||
|
||||
*uid = current->uid;
|
||||
*gid = current->gid;
|
||||
*uid = current_uid();
|
||||
*gid = current_gid();
|
||||
*reserved = 2;
|
||||
*root = -1;
|
||||
*blocksize = -1;
|
||||
|
@ -154,8 +154,8 @@ static struct inode *anon_inode_mkinode(void)
|
||||
*/
|
||||
inode->i_state = I_DIRTY;
|
||||
inode->i_mode = S_IRUSR | S_IWUSR;
|
||||
inode->i_uid = current->fsuid;
|
||||
inode->i_gid = current->fsgid;
|
||||
inode->i_uid = current_fsuid();
|
||||
inode->i_gid = current_fsgid();
|
||||
inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
|
||||
return inode;
|
||||
}
|
||||
|
@ -29,13 +29,13 @@ int inode_change_ok(struct inode *inode, struct iattr *attr)
|
||||
|
||||
/* Make sure a caller can chown. */
|
||||
if ((ia_valid & ATTR_UID) &&
|
||||
(current->fsuid != inode->i_uid ||
|
||||
(current_fsuid() != inode->i_uid ||
|
||||
attr->ia_uid != inode->i_uid) && !capable(CAP_CHOWN))
|
||||
goto error;
|
||||
|
||||
/* Make sure caller can chgrp. */
|
||||
if ((ia_valid & ATTR_GID) &&
|
||||
(current->fsuid != inode->i_uid ||
|
||||
(current_fsuid() != inode->i_uid ||
|
||||
(!in_group_p(attr->ia_gid) && attr->ia_gid != inode->i_gid)) &&
|
||||
!capable(CAP_CHOWN))
|
||||
goto error;
|
||||
|
@ -76,8 +76,8 @@ static int parse_options(char *options, int *pipefd, uid_t *uid, gid_t *gid,
|
||||
substring_t args[MAX_OPT_ARGS];
|
||||
int option;
|
||||
|
||||
*uid = current->uid;
|
||||
*gid = current->gid;
|
||||
*uid = current_uid();
|
||||
*gid = current_gid();
|
||||
*pgrp = task_pgrp_nr(current);
|
||||
|
||||
*minproto = *maxproto = AUTOFS_PROTO_VERSION;
|
||||
|
@ -308,7 +308,8 @@ static int autofs_dev_ioctl_open_mountpoint(const char *path, dev_t devid)
|
||||
goto out;
|
||||
}
|
||||
|
||||
filp = dentry_open(nd.path.dentry, nd.path.mnt, O_RDONLY);
|
||||
filp = dentry_open(nd.path.dentry, nd.path.mnt, O_RDONLY,
|
||||
current_cred());
|
||||
if (IS_ERR(filp)) {
|
||||
err = PTR_ERR(filp);
|
||||
goto out;
|
||||
|
@ -235,8 +235,8 @@ static int parse_options(char *options, int *pipefd, uid_t *uid, gid_t *gid,
|
||||
substring_t args[MAX_OPT_ARGS];
|
||||
int option;
|
||||
|
||||
*uid = current->uid;
|
||||
*gid = current->gid;
|
||||
*uid = current_uid();
|
||||
*gid = current_gid();
|
||||
*pgrp = task_pgrp_nr(current);
|
||||
|
||||
*minproto = AUTOFS_MIN_PROTO_VERSION;
|
||||
|
@ -391,8 +391,8 @@ int autofs4_wait(struct autofs_sb_info *sbi, struct dentry *dentry,
|
||||
memcpy(&wq->name, &qstr, sizeof(struct qstr));
|
||||
wq->dev = autofs4_get_dev(sbi);
|
||||
wq->ino = autofs4_get_ino(sbi);
|
||||
wq->uid = current->uid;
|
||||
wq->gid = current->gid;
|
||||
wq->uid = current_uid();
|
||||
wq->gid = current_gid();
|
||||
wq->pid = current->pid;
|
||||
wq->tgid = current->tgid;
|
||||
wq->status = -EINTR; /* Status return if interrupted */
|
||||
|
@ -106,8 +106,8 @@ static int bfs_create(struct inode *dir, struct dentry *dentry, int mode,
|
||||
}
|
||||
set_bit(ino, info->si_imap);
|
||||
info->si_freei--;
|
||||
inode->i_uid = current->fsuid;
|
||||
inode->i_gid = (dir->i_mode & S_ISGID) ? dir->i_gid : current->fsgid;
|
||||
inode->i_uid = current_fsuid();
|
||||
inode->i_gid = (dir->i_mode & S_ISGID) ? dir->i_gid : current_fsgid();
|
||||
inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME_SEC;
|
||||
inode->i_blocks = 0;
|
||||
inode->i_op = &bfs_file_inops;
|
||||
|
@ -320,7 +320,7 @@ static int load_aout_binary(struct linux_binprm * bprm, struct pt_regs * regs)
|
||||
current->mm->free_area_cache = current->mm->mmap_base;
|
||||
current->mm->cached_hole_size = 0;
|
||||
|
||||
compute_creds(bprm);
|
||||
install_exec_creds(bprm);
|
||||
current->flags &= ~PF_FORKNOEXEC;
|
||||
#ifdef __sparc__
|
||||
if (N_MAGIC(ex) == NMAGIC) {
|
||||
|
@ -157,7 +157,7 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec,
|
||||
int items;
|
||||
elf_addr_t *elf_info;
|
||||
int ei_index = 0;
|
||||
struct task_struct *tsk = current;
|
||||
const struct cred *cred = current_cred();
|
||||
struct vm_area_struct *vma;
|
||||
|
||||
/*
|
||||
@ -223,10 +223,10 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec,
|
||||
NEW_AUX_ENT(AT_BASE, interp_load_addr);
|
||||
NEW_AUX_ENT(AT_FLAGS, 0);
|
||||
NEW_AUX_ENT(AT_ENTRY, exec->e_entry);
|
||||
NEW_AUX_ENT(AT_UID, tsk->uid);
|
||||
NEW_AUX_ENT(AT_EUID, tsk->euid);
|
||||
NEW_AUX_ENT(AT_GID, tsk->gid);
|
||||
NEW_AUX_ENT(AT_EGID, tsk->egid);
|
||||
NEW_AUX_ENT(AT_UID, cred->uid);
|
||||
NEW_AUX_ENT(AT_EUID, cred->euid);
|
||||
NEW_AUX_ENT(AT_GID, cred->gid);
|
||||
NEW_AUX_ENT(AT_EGID, cred->egid);
|
||||
NEW_AUX_ENT(AT_SECURE, security_bprm_secureexec(bprm));
|
||||
NEW_AUX_ENT(AT_EXECFN, bprm->exec);
|
||||
if (k_platform) {
|
||||
@ -956,7 +956,7 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
|
||||
}
|
||||
#endif /* ARCH_HAS_SETUP_ADDITIONAL_PAGES */
|
||||
|
||||
compute_creds(bprm);
|
||||
install_exec_creds(bprm);
|
||||
current->flags &= ~PF_FORKNOEXEC;
|
||||
retval = create_elf_tables(bprm, &loc->elf_ex,
|
||||
load_addr, interp_load_addr);
|
||||
@ -1361,6 +1361,7 @@ static void fill_prstatus(struct elf_prstatus *prstatus,
|
||||
static int fill_psinfo(struct elf_prpsinfo *psinfo, struct task_struct *p,
|
||||
struct mm_struct *mm)
|
||||
{
|
||||
const struct cred *cred;
|
||||
unsigned int i, len;
|
||||
|
||||
/* first copy the parameters from user space */
|
||||
@ -1388,8 +1389,11 @@ static int fill_psinfo(struct elf_prpsinfo *psinfo, struct task_struct *p,
|
||||
psinfo->pr_zomb = psinfo->pr_sname == 'Z';
|
||||
psinfo->pr_nice = task_nice(p);
|
||||
psinfo->pr_flag = p->flags;
|
||||
SET_UID(psinfo->pr_uid, p->uid);
|
||||
SET_GID(psinfo->pr_gid, p->gid);
|
||||
rcu_read_lock();
|
||||
cred = __task_cred(p);
|
||||
SET_UID(psinfo->pr_uid, cred->uid);
|
||||
SET_GID(psinfo->pr_gid, cred->gid);
|
||||
rcu_read_unlock();
|
||||
strncpy(psinfo->pr_fname, p->comm, sizeof(psinfo->pr_fname));
|
||||
|
||||
return 0;
|
||||
|
@ -404,7 +404,7 @@ static int load_elf_fdpic_binary(struct linux_binprm *bprm,
|
||||
current->mm->start_stack = current->mm->start_brk + stack_size;
|
||||
#endif
|
||||
|
||||
compute_creds(bprm);
|
||||
install_exec_creds(bprm);
|
||||
current->flags &= ~PF_FORKNOEXEC;
|
||||
if (create_elf_fdpic_tables(bprm, current->mm,
|
||||
&exec_params, &interp_params) < 0)
|
||||
@ -475,6 +475,7 @@ static int create_elf_fdpic_tables(struct linux_binprm *bprm,
|
||||
struct elf_fdpic_params *exec_params,
|
||||
struct elf_fdpic_params *interp_params)
|
||||
{
|
||||
const struct cred *cred = current_cred();
|
||||
unsigned long sp, csp, nitems;
|
||||
elf_caddr_t __user *argv, *envp;
|
||||
size_t platform_len = 0, len;
|
||||
@ -623,10 +624,10 @@ static int create_elf_fdpic_tables(struct linux_binprm *bprm,
|
||||
NEW_AUX_ENT(AT_BASE, interp_params->elfhdr_addr);
|
||||
NEW_AUX_ENT(AT_FLAGS, 0);
|
||||
NEW_AUX_ENT(AT_ENTRY, exec_params->entry_addr);
|
||||
NEW_AUX_ENT(AT_UID, (elf_addr_t) current->uid);
|
||||
NEW_AUX_ENT(AT_EUID, (elf_addr_t) current->euid);
|
||||
NEW_AUX_ENT(AT_GID, (elf_addr_t) current->gid);
|
||||
NEW_AUX_ENT(AT_EGID, (elf_addr_t) current->egid);
|
||||
NEW_AUX_ENT(AT_UID, (elf_addr_t) cred->uid);
|
||||
NEW_AUX_ENT(AT_EUID, (elf_addr_t) cred->euid);
|
||||
NEW_AUX_ENT(AT_GID, (elf_addr_t) cred->gid);
|
||||
NEW_AUX_ENT(AT_EGID, (elf_addr_t) cred->egid);
|
||||
NEW_AUX_ENT(AT_SECURE, security_bprm_secureexec(bprm));
|
||||
NEW_AUX_ENT(AT_EXECFN, bprm->exec);
|
||||
|
||||
@ -1413,6 +1414,7 @@ static void fill_prstatus(struct elf_prstatus *prstatus,
|
||||
static int fill_psinfo(struct elf_prpsinfo *psinfo, struct task_struct *p,
|
||||
struct mm_struct *mm)
|
||||
{
|
||||
const struct cred *cred;
|
||||
unsigned int i, len;
|
||||
|
||||
/* first copy the parameters from user space */
|
||||
@ -1440,8 +1442,11 @@ static int fill_psinfo(struct elf_prpsinfo *psinfo, struct task_struct *p,
|
||||
psinfo->pr_zomb = psinfo->pr_sname == 'Z';
|
||||
psinfo->pr_nice = task_nice(p);
|
||||
psinfo->pr_flag = p->flags;
|
||||
SET_UID(psinfo->pr_uid, p->uid);
|
||||
SET_GID(psinfo->pr_gid, p->gid);
|
||||
rcu_read_lock();
|
||||
cred = __task_cred(p);
|
||||
SET_UID(psinfo->pr_uid, cred->uid);
|
||||
SET_GID(psinfo->pr_gid, cred->gid);
|
||||
rcu_read_unlock();
|
||||
strncpy(psinfo->pr_fname, p->comm, sizeof(psinfo->pr_fname));
|
||||
|
||||
return 0;
|
||||
|
@ -880,7 +880,7 @@ static int load_flat_binary(struct linux_binprm * bprm, struct pt_regs * regs)
|
||||
(libinfo.lib_list[j].loaded)?
|
||||
libinfo.lib_list[j].start_data:UNLOADED_LIB;
|
||||
|
||||
compute_creds(bprm);
|
||||
install_exec_creds(bprm);
|
||||
current->flags &= ~PF_FORKNOEXEC;
|
||||
|
||||
set_binfmt(&flat_format);
|
||||
|
@ -255,7 +255,7 @@ load_som_binary(struct linux_binprm * bprm, struct pt_regs * regs)
|
||||
kfree(hpuxhdr);
|
||||
|
||||
set_binfmt(&som_format);
|
||||
compute_creds(bprm);
|
||||
install_exec_creds(bprm);
|
||||
setup_arg_pages(bprm, STACK_TOP, EXSTACK_DEFAULT);
|
||||
|
||||
create_som_tables(bprm);
|
||||
|
@ -19,7 +19,7 @@
|
||||
#define _CIFS_FS_SB_H
|
||||
|
||||
#define CIFS_MOUNT_NO_PERM 1 /* do not do client vfs_perm check */
|
||||
#define CIFS_MOUNT_SET_UID 2 /* set current->euid in create etc. */
|
||||
#define CIFS_MOUNT_SET_UID 2 /* set current's euid in create etc. */
|
||||
#define CIFS_MOUNT_SERVER_INUM 4 /* inode numbers from uniqueid from server */
|
||||
#define CIFS_MOUNT_DIRECT_IO 8 /* do not write nor read through page cache */
|
||||
#define CIFS_MOUNT_NO_XATTR 0x10 /* if set - disable xattr support */
|
||||
|
@ -39,7 +39,7 @@ extern int smb_send(struct socket *, struct smb_hdr *,
|
||||
unsigned int /* length */ , struct sockaddr *, bool);
|
||||
extern unsigned int _GetXid(void);
|
||||
extern void _FreeXid(unsigned int);
|
||||
#define GetXid() (int)_GetXid(); cFYI(1,("CIFS VFS: in %s as Xid: %d with uid: %d",__func__, xid,current->fsuid));
|
||||
#define GetXid() (int)_GetXid(); cFYI(1,("CIFS VFS: in %s as Xid: %d with uid: %d",__func__, xid,current_fsuid()));
|
||||
#define FreeXid(curr_xid) {_FreeXid(curr_xid); cFYI(1,("CIFS VFS: leaving %s (xid = %d) rc = %d",__func__,curr_xid,(int)rc));}
|
||||
extern char *build_path_from_dentry(struct dentry *);
|
||||
extern char *build_wildcard_path_from_dentry(struct dentry *direntry);
|
||||
|
@ -836,8 +836,8 @@ cifs_parse_mount_options(char *options, const char *devname,
|
||||
/* null target name indicates to use *SMBSERVR default called name
|
||||
if we end up sending RFC1001 session initialize */
|
||||
vol->target_rfc1001_name[0] = 0;
|
||||
vol->linux_uid = current->uid; /* current->euid instead? */
|
||||
vol->linux_gid = current->gid;
|
||||
vol->linux_uid = current_uid(); /* use current_euid() instead? */
|
||||
vol->linux_gid = current_gid();
|
||||
vol->dir_mode = S_IRWXUGO;
|
||||
/* 2767 perms indicate mandatory locking support */
|
||||
vol->file_mode = (S_IRWXUGO | S_ISGID) & (~S_IXGRP);
|
||||
|
@ -235,11 +235,11 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
|
||||
};
|
||||
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) {
|
||||
args.uid = (__u64) current->fsuid;
|
||||
args.uid = (__u64) current_fsuid();
|
||||
if (inode->i_mode & S_ISGID)
|
||||
args.gid = (__u64) inode->i_gid;
|
||||
else
|
||||
args.gid = (__u64) current->fsgid;
|
||||
args.gid = (__u64) current_fsgid();
|
||||
} else {
|
||||
args.uid = NO_CHANGE_64;
|
||||
args.gid = NO_CHANGE_64;
|
||||
@ -271,13 +271,13 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
|
||||
if ((oplock & CIFS_CREATE_ACTION) &&
|
||||
(cifs_sb->mnt_cifs_flags &
|
||||
CIFS_MOUNT_SET_UID)) {
|
||||
newinode->i_uid = current->fsuid;
|
||||
newinode->i_uid = current_fsuid();
|
||||
if (inode->i_mode & S_ISGID)
|
||||
newinode->i_gid =
|
||||
inode->i_gid;
|
||||
else
|
||||
newinode->i_gid =
|
||||
current->fsgid;
|
||||
current_fsgid();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -375,8 +375,8 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode,
|
||||
.device = device_number,
|
||||
};
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) {
|
||||
args.uid = (__u64) current->fsuid;
|
||||
args.gid = (__u64) current->fsgid;
|
||||
args.uid = (__u64) current_fsuid();
|
||||
args.gid = (__u64) current_fsgid();
|
||||
} else {
|
||||
args.uid = NO_CHANGE_64;
|
||||
args.gid = NO_CHANGE_64;
|
||||
|
@ -1143,11 +1143,11 @@ mkdir_get_info:
|
||||
.device = 0,
|
||||
};
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) {
|
||||
args.uid = (__u64)current->fsuid;
|
||||
args.uid = (__u64)current_fsuid();
|
||||
if (inode->i_mode & S_ISGID)
|
||||
args.gid = (__u64)inode->i_gid;
|
||||
else
|
||||
args.gid = (__u64)current->fsgid;
|
||||
args.gid = (__u64)current_fsgid();
|
||||
} else {
|
||||
args.uid = NO_CHANGE_64;
|
||||
args.gid = NO_CHANGE_64;
|
||||
@ -1184,13 +1184,13 @@ mkdir_get_info:
|
||||
if (cifs_sb->mnt_cifs_flags &
|
||||
CIFS_MOUNT_SET_UID) {
|
||||
direntry->d_inode->i_uid =
|
||||
current->fsuid;
|
||||
current_fsuid();
|
||||
if (inode->i_mode & S_ISGID)
|
||||
direntry->d_inode->i_gid =
|
||||
inode->i_gid;
|
||||
else
|
||||
direntry->d_inode->i_gid =
|
||||
current->fsgid;
|
||||
current_fsgid();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -65,7 +65,7 @@ long cifs_ioctl(struct file *filep, unsigned int command, unsigned long arg)
|
||||
switch (command) {
|
||||
case CIFS_IOC_CHECKUMOUNT:
|
||||
cFYI(1, ("User unmount attempted"));
|
||||
if (cifs_sb->mnt_uid == current->uid)
|
||||
if (cifs_sb->mnt_uid == current_uid())
|
||||
rc = 0;
|
||||
else {
|
||||
rc = -EACCES;
|
||||
|
@ -338,13 +338,13 @@ header_assemble(struct smb_hdr *buffer, char smb_command /* command */ ,
|
||||
/* BB Add support for establishing new tCon and SMB Session */
|
||||
/* with userid/password pairs found on the smb session */
|
||||
/* for other target tcp/ip addresses BB */
|
||||
if (current->fsuid != treeCon->ses->linux_uid) {
|
||||
if (current_fsuid() != treeCon->ses->linux_uid) {
|
||||
cFYI(1, ("Multiuser mode and UID "
|
||||
"did not match tcon uid"));
|
||||
read_lock(&cifs_tcp_ses_lock);
|
||||
list_for_each(temp_item, &treeCon->ses->server->smb_ses_list) {
|
||||
ses = list_entry(temp_item, struct cifsSesInfo, smb_ses_list);
|
||||
if (ses->linux_uid == current->fsuid) {
|
||||
if (ses->linux_uid == current_fsuid()) {
|
||||
if (ses->server == treeCon->ses->server) {
|
||||
cFYI(1, ("found matching uid substitute right smb_uid"));
|
||||
buffer->Uid = ses->Suid;
|
||||
|
@ -32,8 +32,8 @@ void coda_cache_enter(struct inode *inode, int mask)
|
||||
struct coda_inode_info *cii = ITOC(inode);
|
||||
|
||||
cii->c_cached_epoch = atomic_read(&permission_epoch);
|
||||
if (cii->c_uid != current->fsuid) {
|
||||
cii->c_uid = current->fsuid;
|
||||
if (cii->c_uid != current_fsuid()) {
|
||||
cii->c_uid = current_fsuid();
|
||||
cii->c_cached_perm = mask;
|
||||
} else
|
||||
cii->c_cached_perm |= mask;
|
||||
@ -60,7 +60,7 @@ int coda_cache_check(struct inode *inode, int mask)
|
||||
int hit;
|
||||
|
||||
hit = (mask & cii->c_cached_perm) == mask &&
|
||||
cii->c_uid == current->fsuid &&
|
||||
cii->c_uid == current_fsuid() &&
|
||||
cii->c_cached_epoch == atomic_read(&permission_epoch);
|
||||
|
||||
return hit;
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include <linux/file.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/stat.h>
|
||||
#include <linux/cred.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/smp_lock.h>
|
||||
#include <linux/string.h>
|
||||
@ -174,7 +175,7 @@ int coda_release(struct inode *coda_inode, struct file *coda_file)
|
||||
BUG_ON(!cfi || cfi->cfi_magic != CODA_MAGIC);
|
||||
|
||||
err = venus_close(coda_inode->i_sb, coda_i2f(coda_inode),
|
||||
coda_flags, coda_file->f_uid);
|
||||
coda_flags, coda_file->f_cred->fsuid);
|
||||
|
||||
host_inode = cfi->cfi_container->f_path.dentry->d_inode;
|
||||
cii = ITOC(coda_inode);
|
||||
|
@ -52,7 +52,7 @@ static void *alloc_upcall(int opcode, int size)
|
||||
inp->ih.opcode = opcode;
|
||||
inp->ih.pid = current->pid;
|
||||
inp->ih.pgid = task_pgrp_nr(current);
|
||||
inp->ih.uid = current->fsuid;
|
||||
inp->ih.uid = current_fsuid();
|
||||
|
||||
return (void*)inp;
|
||||
}
|
||||
|
42
fs/compat.c
42
fs/compat.c
@ -1393,10 +1393,20 @@ int compat_do_execve(char * filename,
|
||||
if (!bprm)
|
||||
goto out_ret;
|
||||
|
||||
retval = mutex_lock_interruptible(¤t->cred_exec_mutex);
|
||||
if (retval < 0)
|
||||
goto out_free;
|
||||
|
||||
retval = -ENOMEM;
|
||||
bprm->cred = prepare_exec_creds();
|
||||
if (!bprm->cred)
|
||||
goto out_unlock;
|
||||
check_unsafe_exec(bprm);
|
||||
|
||||
file = open_exec(filename);
|
||||
retval = PTR_ERR(file);
|
||||
if (IS_ERR(file))
|
||||
goto out_kfree;
|
||||
goto out_unlock;
|
||||
|
||||
sched_exec();
|
||||
|
||||
@ -1410,14 +1420,10 @@ int compat_do_execve(char * filename,
|
||||
|
||||
bprm->argc = compat_count(argv, MAX_ARG_STRINGS);
|
||||
if ((retval = bprm->argc) < 0)
|
||||
goto out_mm;
|
||||
goto out;
|
||||
|
||||
bprm->envc = compat_count(envp, MAX_ARG_STRINGS);
|
||||
if ((retval = bprm->envc) < 0)
|
||||
goto out_mm;
|
||||
|
||||
retval = security_bprm_alloc(bprm);
|
||||
if (retval)
|
||||
goto out;
|
||||
|
||||
retval = prepare_binprm(bprm);
|
||||
@ -1438,19 +1444,16 @@ int compat_do_execve(char * filename,
|
||||
goto out;
|
||||
|
||||
retval = search_binary_handler(bprm, regs);
|
||||
if (retval >= 0) {
|
||||
/* execve success */
|
||||
security_bprm_free(bprm);
|
||||
acct_update_integrals(current);
|
||||
free_bprm(bprm);
|
||||
return retval;
|
||||
}
|
||||
if (retval < 0)
|
||||
goto out;
|
||||
|
||||
/* execve succeeded */
|
||||
mutex_unlock(¤t->cred_exec_mutex);
|
||||
acct_update_integrals(current);
|
||||
free_bprm(bprm);
|
||||
return retval;
|
||||
|
||||
out:
|
||||
if (bprm->security)
|
||||
security_bprm_free(bprm);
|
||||
|
||||
out_mm:
|
||||
if (bprm->mm)
|
||||
mmput(bprm->mm);
|
||||
|
||||
@ -1460,7 +1463,10 @@ out_file:
|
||||
fput(bprm->file);
|
||||
}
|
||||
|
||||
out_kfree:
|
||||
out_unlock:
|
||||
mutex_unlock(¤t->cred_exec_mutex);
|
||||
|
||||
out_free:
|
||||
free_bprm(bprm);
|
||||
|
||||
out_ret:
|
||||
|
@ -222,8 +222,8 @@ int devpts_pty_new(struct inode *ptmx_inode, struct tty_struct *tty)
|
||||
return -ENOMEM;
|
||||
|
||||
inode->i_ino = number+2;
|
||||
inode->i_uid = config.setuid ? config.uid : current->fsuid;
|
||||
inode->i_gid = config.setgid ? config.gid : current->fsgid;
|
||||
inode->i_uid = config.setuid ? config.uid : current_fsuid();
|
||||
inode->i_gid = config.setgid ? config.gid : current_fsgid();
|
||||
inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
|
||||
init_special_inode(inode, S_IFCHR|config.mode, device);
|
||||
inode->i_private = tty;
|
||||
|
@ -874,7 +874,7 @@ static inline int need_print_warning(struct dquot *dquot)
|
||||
|
||||
switch (dquot->dq_type) {
|
||||
case USRQUOTA:
|
||||
return current->fsuid == dquot->dq_id;
|
||||
return current_fsuid() == dquot->dq_id;
|
||||
case GRPQUOTA:
|
||||
return in_group_p(dquot->dq_id);
|
||||
}
|
||||
@ -981,7 +981,7 @@ static void send_warning(const struct dquot *dquot, const char warntype)
|
||||
MINOR(dquot->dq_sb->s_dev));
|
||||
if (ret)
|
||||
goto attr_err_out;
|
||||
ret = nla_put_u64(skb, QUOTA_NL_A_CAUSED_ID, current->user->uid);
|
||||
ret = nla_put_u64(skb, QUOTA_NL_A_CAUSED_ID, current_uid());
|
||||
if (ret)
|
||||
goto attr_err_out;
|
||||
genlmsg_end(skb, msg_head);
|
||||
|
@ -691,7 +691,8 @@ int ecryptfs_init_kthread(void);
|
||||
void ecryptfs_destroy_kthread(void);
|
||||
int ecryptfs_privileged_open(struct file **lower_file,
|
||||
struct dentry *lower_dentry,
|
||||
struct vfsmount *lower_mnt);
|
||||
struct vfsmount *lower_mnt,
|
||||
const struct cred *cred);
|
||||
int ecryptfs_init_persistent_file(struct dentry *ecryptfs_dentry);
|
||||
|
||||
#endif /* #ifndef ECRYPTFS_KERNEL_H */
|
||||
|
@ -73,7 +73,7 @@ static int ecryptfs_threadfn(void *ignored)
|
||||
mntget(req->lower_mnt);
|
||||
(*req->lower_file) = dentry_open(
|
||||
req->lower_dentry, req->lower_mnt,
|
||||
(O_RDWR | O_LARGEFILE));
|
||||
(O_RDWR | O_LARGEFILE), current_cred());
|
||||
req->flags |= ECRYPTFS_REQ_PROCESSED;
|
||||
}
|
||||
wake_up(&req->wait);
|
||||
@ -132,7 +132,8 @@ void ecryptfs_destroy_kthread(void)
|
||||
*/
|
||||
int ecryptfs_privileged_open(struct file **lower_file,
|
||||
struct dentry *lower_dentry,
|
||||
struct vfsmount *lower_mnt)
|
||||
struct vfsmount *lower_mnt,
|
||||
const struct cred *cred)
|
||||
{
|
||||
struct ecryptfs_open_req *req;
|
||||
int rc = 0;
|
||||
@ -143,7 +144,7 @@ int ecryptfs_privileged_open(struct file **lower_file,
|
||||
dget(lower_dentry);
|
||||
mntget(lower_mnt);
|
||||
(*lower_file) = dentry_open(lower_dentry, lower_mnt,
|
||||
(O_RDWR | O_LARGEFILE));
|
||||
(O_RDWR | O_LARGEFILE), cred);
|
||||
if (!IS_ERR(*lower_file))
|
||||
goto out;
|
||||
req = kmem_cache_alloc(ecryptfs_open_req_cache, GFP_KERNEL);
|
||||
@ -184,7 +185,7 @@ int ecryptfs_privileged_open(struct file **lower_file,
|
||||
dget(lower_dentry);
|
||||
mntget(lower_mnt);
|
||||
(*lower_file) = dentry_open(lower_dentry, lower_mnt,
|
||||
(O_RDONLY | O_LARGEFILE));
|
||||
(O_RDONLY | O_LARGEFILE), cred);
|
||||
if (IS_ERR(*lower_file)) {
|
||||
rc = PTR_ERR(*req->lower_file);
|
||||
(*lower_file) = NULL;
|
||||
|
@ -115,6 +115,7 @@ void __ecryptfs_printk(const char *fmt, ...)
|
||||
*/
|
||||
int ecryptfs_init_persistent_file(struct dentry *ecryptfs_dentry)
|
||||
{
|
||||
const struct cred *cred = current_cred();
|
||||
struct ecryptfs_inode_info *inode_info =
|
||||
ecryptfs_inode_to_private(ecryptfs_dentry->d_inode);
|
||||
int rc = 0;
|
||||
@ -127,7 +128,7 @@ int ecryptfs_init_persistent_file(struct dentry *ecryptfs_dentry)
|
||||
|
||||
lower_dentry = ecryptfs_dentry_to_lower(ecryptfs_dentry);
|
||||
rc = ecryptfs_privileged_open(&inode_info->lower_file,
|
||||
lower_dentry, lower_mnt);
|
||||
lower_dentry, lower_mnt, cred);
|
||||
if (rc || IS_ERR(inode_info->lower_file)) {
|
||||
printk(KERN_ERR "Error opening lower persistent file "
|
||||
"for lower_dentry [0x%p] and lower_mnt [0x%p]; "
|
||||
|
@ -360,7 +360,8 @@ int ecryptfs_process_response(struct ecryptfs_message *msg, uid_t euid,
|
||||
struct ecryptfs_msg_ctx *msg_ctx;
|
||||
size_t msg_size;
|
||||
struct nsproxy *nsproxy;
|
||||
struct user_namespace *current_user_ns;
|
||||
struct user_namespace *tsk_user_ns;
|
||||
uid_t ctx_euid;
|
||||
int rc;
|
||||
|
||||
if (msg->index >= ecryptfs_message_buf_len) {
|
||||
@ -384,9 +385,9 @@ int ecryptfs_process_response(struct ecryptfs_message *msg, uid_t euid,
|
||||
mutex_unlock(&ecryptfs_daemon_hash_mux);
|
||||
goto wake_up;
|
||||
}
|
||||
current_user_ns = nsproxy->user_ns;
|
||||
rc = ecryptfs_find_daemon_by_euid(&daemon, msg_ctx->task->euid,
|
||||
current_user_ns);
|
||||
tsk_user_ns = __task_cred(msg_ctx->task)->user->user_ns;
|
||||
ctx_euid = task_euid(msg_ctx->task);
|
||||
rc = ecryptfs_find_daemon_by_euid(&daemon, ctx_euid, tsk_user_ns);
|
||||
rcu_read_unlock();
|
||||
mutex_unlock(&ecryptfs_daemon_hash_mux);
|
||||
if (rc) {
|
||||
@ -394,28 +395,28 @@ int ecryptfs_process_response(struct ecryptfs_message *msg, uid_t euid,
|
||||
printk(KERN_WARNING "%s: User [%d] received a "
|
||||
"message response from process [0x%p] but does "
|
||||
"not have a registered daemon\n", __func__,
|
||||
msg_ctx->task->euid, pid);
|
||||
ctx_euid, pid);
|
||||
goto wake_up;
|
||||
}
|
||||
if (msg_ctx->task->euid != euid) {
|
||||
if (ctx_euid != euid) {
|
||||
rc = -EBADMSG;
|
||||
printk(KERN_WARNING "%s: Received message from user "
|
||||
"[%d]; expected message from user [%d]\n", __func__,
|
||||
euid, msg_ctx->task->euid);
|
||||
euid, ctx_euid);
|
||||
goto unlock;
|
||||
}
|
||||
if (current_user_ns != user_ns) {
|
||||
if (tsk_user_ns != user_ns) {
|
||||
rc = -EBADMSG;
|
||||
printk(KERN_WARNING "%s: Received message from user_ns "
|
||||
"[0x%p]; expected message from user_ns [0x%p]\n",
|
||||
__func__, user_ns, nsproxy->user_ns);
|
||||
__func__, user_ns, tsk_user_ns);
|
||||
goto unlock;
|
||||
}
|
||||
if (daemon->pid != pid) {
|
||||
rc = -EBADMSG;
|
||||
printk(KERN_ERR "%s: User [%d] sent a message response "
|
||||
"from an unrecognized process [0x%p]\n",
|
||||
__func__, msg_ctx->task->euid, pid);
|
||||
__func__, ctx_euid, pid);
|
||||
goto unlock;
|
||||
}
|
||||
if (msg_ctx->state != ECRYPTFS_MSG_CTX_STATE_PENDING) {
|
||||
@ -464,14 +465,14 @@ ecryptfs_send_message_locked(char *data, int data_len, u8 msg_type,
|
||||
struct ecryptfs_msg_ctx **msg_ctx)
|
||||
{
|
||||
struct ecryptfs_daemon *daemon;
|
||||
uid_t euid = current_euid();
|
||||
int rc;
|
||||
|
||||
rc = ecryptfs_find_daemon_by_euid(&daemon, current->euid,
|
||||
current->nsproxy->user_ns);
|
||||
rc = ecryptfs_find_daemon_by_euid(&daemon, euid, current_user_ns());
|
||||
if (rc || !daemon) {
|
||||
rc = -ENOTCONN;
|
||||
printk(KERN_ERR "%s: User [%d] does not have a daemon "
|
||||
"registered\n", __func__, current->euid);
|
||||
"registered\n", __func__, euid);
|
||||
goto out;
|
||||
}
|
||||
mutex_lock(&ecryptfs_msg_ctx_lists_mux);
|
||||
|
@ -42,12 +42,12 @@ ecryptfs_miscdev_poll(struct file *file, poll_table *pt)
|
||||
{
|
||||
struct ecryptfs_daemon *daemon;
|
||||
unsigned int mask = 0;
|
||||
uid_t euid = current_euid();
|
||||
int rc;
|
||||
|
||||
mutex_lock(&ecryptfs_daemon_hash_mux);
|
||||
/* TODO: Just use file->private_data? */
|
||||
rc = ecryptfs_find_daemon_by_euid(&daemon, current->euid,
|
||||
current->nsproxy->user_ns);
|
||||
rc = ecryptfs_find_daemon_by_euid(&daemon, euid, current_user_ns());
|
||||
BUG_ON(rc || !daemon);
|
||||
mutex_lock(&daemon->mux);
|
||||
mutex_unlock(&ecryptfs_daemon_hash_mux);
|
||||
@ -83,6 +83,7 @@ static int
|
||||
ecryptfs_miscdev_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
struct ecryptfs_daemon *daemon = NULL;
|
||||
uid_t euid = current_euid();
|
||||
int rc;
|
||||
|
||||
mutex_lock(&ecryptfs_daemon_hash_mux);
|
||||
@ -93,11 +94,9 @@ ecryptfs_miscdev_open(struct inode *inode, struct file *file)
|
||||
"count; rc = [%d]\n", __func__, rc);
|
||||
goto out_unlock_daemon_list;
|
||||
}
|
||||
rc = ecryptfs_find_daemon_by_euid(&daemon, current->euid,
|
||||
current->nsproxy->user_ns);
|
||||
rc = ecryptfs_find_daemon_by_euid(&daemon, euid, current_user_ns());
|
||||
if (rc || !daemon) {
|
||||
rc = ecryptfs_spawn_daemon(&daemon, current->euid,
|
||||
current->nsproxy->user_ns,
|
||||
rc = ecryptfs_spawn_daemon(&daemon, euid, current_user_ns(),
|
||||
task_pid(current));
|
||||
if (rc) {
|
||||
printk(KERN_ERR "%s: Error attempting to spawn daemon; "
|
||||
@ -147,11 +146,11 @@ static int
|
||||
ecryptfs_miscdev_release(struct inode *inode, struct file *file)
|
||||
{
|
||||
struct ecryptfs_daemon *daemon = NULL;
|
||||
uid_t euid = current_euid();
|
||||
int rc;
|
||||
|
||||
mutex_lock(&ecryptfs_daemon_hash_mux);
|
||||
rc = ecryptfs_find_daemon_by_euid(&daemon, current->euid,
|
||||
current->nsproxy->user_ns);
|
||||
rc = ecryptfs_find_daemon_by_euid(&daemon, euid, current_user_ns());
|
||||
BUG_ON(rc || !daemon);
|
||||
mutex_lock(&daemon->mux);
|
||||
BUG_ON(daemon->pid != task_pid(current));
|
||||
@ -246,12 +245,12 @@ ecryptfs_miscdev_read(struct file *file, char __user *buf, size_t count,
|
||||
char packet_length[3];
|
||||
size_t i;
|
||||
size_t total_length;
|
||||
uid_t euid = current_euid();
|
||||
int rc;
|
||||
|
||||
mutex_lock(&ecryptfs_daemon_hash_mux);
|
||||
/* TODO: Just use file->private_data? */
|
||||
rc = ecryptfs_find_daemon_by_euid(&daemon, current->euid,
|
||||
current->nsproxy->user_ns);
|
||||
rc = ecryptfs_find_daemon_by_euid(&daemon, euid, current_user_ns());
|
||||
BUG_ON(rc || !daemon);
|
||||
mutex_lock(&daemon->mux);
|
||||
if (daemon->flags & ECRYPTFS_DAEMON_ZOMBIE) {
|
||||
@ -290,8 +289,8 @@ check_list:
|
||||
* message from the queue; try again */
|
||||
goto check_list;
|
||||
}
|
||||
BUG_ON(current->euid != daemon->euid);
|
||||
BUG_ON(current->nsproxy->user_ns != daemon->user_ns);
|
||||
BUG_ON(euid != daemon->euid);
|
||||
BUG_ON(current_user_ns() != daemon->user_ns);
|
||||
BUG_ON(task_pid(current) != daemon->pid);
|
||||
msg_ctx = list_first_entry(&daemon->msg_ctx_out_queue,
|
||||
struct ecryptfs_msg_ctx, daemon_out_list);
|
||||
@ -414,6 +413,7 @@ ecryptfs_miscdev_write(struct file *file, const char __user *buf,
|
||||
size_t packet_size, packet_size_length, i;
|
||||
ssize_t sz = 0;
|
||||
char *data;
|
||||
uid_t euid = current_euid();
|
||||
int rc;
|
||||
|
||||
if (count == 0)
|
||||
@ -463,8 +463,7 @@ ecryptfs_miscdev_write(struct file *file, const char __user *buf,
|
||||
goto out_free;
|
||||
}
|
||||
rc = ecryptfs_miscdev_response(&data[i], packet_size,
|
||||
current->euid,
|
||||
current->nsproxy->user_ns,
|
||||
euid, current_user_ns(),
|
||||
task_pid(current), seq);
|
||||
if (rc)
|
||||
printk(KERN_WARNING "%s: Failed to deliver miscdev "
|
||||
|
183
fs/exec.c
183
fs/exec.c
@ -55,6 +55,7 @@
|
||||
#include <asm/uaccess.h>
|
||||
#include <asm/mmu_context.h>
|
||||
#include <asm/tlb.h>
|
||||
#include "internal.h"
|
||||
|
||||
#ifdef __alpha__
|
||||
/* for /sbin/loader handling in search_binary_handler() */
|
||||
@ -980,7 +981,7 @@ int flush_old_exec(struct linux_binprm * bprm)
|
||||
/* This is the point of no return */
|
||||
current->sas_ss_sp = current->sas_ss_size = 0;
|
||||
|
||||
if (current->euid == current->uid && current->egid == current->gid)
|
||||
if (current_euid() == current_uid() && current_egid() == current_gid())
|
||||
set_dumpable(current->mm, 1);
|
||||
else
|
||||
set_dumpable(current->mm, suid_dumpable);
|
||||
@ -1007,16 +1008,17 @@ int flush_old_exec(struct linux_binprm * bprm)
|
||||
*/
|
||||
current->mm->task_size = TASK_SIZE;
|
||||
|
||||
if (bprm->e_uid != current->euid || bprm->e_gid != current->egid) {
|
||||
suid_keys(current);
|
||||
set_dumpable(current->mm, suid_dumpable);
|
||||
/* install the new credentials */
|
||||
if (bprm->cred->uid != current_euid() ||
|
||||
bprm->cred->gid != current_egid()) {
|
||||
current->pdeath_signal = 0;
|
||||
} else if (file_permission(bprm->file, MAY_READ) ||
|
||||
(bprm->interp_flags & BINPRM_FLAGS_ENFORCE_NONDUMP)) {
|
||||
suid_keys(current);
|
||||
bprm->interp_flags & BINPRM_FLAGS_ENFORCE_NONDUMP) {
|
||||
set_dumpable(current->mm, suid_dumpable);
|
||||
}
|
||||
|
||||
current->personality &= ~bprm->per_clear;
|
||||
|
||||
/* An exec changes our domain. We are no longer part of the thread
|
||||
group */
|
||||
|
||||
@ -1033,13 +1035,50 @@ out:
|
||||
|
||||
EXPORT_SYMBOL(flush_old_exec);
|
||||
|
||||
/*
|
||||
* install the new credentials for this executable
|
||||
*/
|
||||
void install_exec_creds(struct linux_binprm *bprm)
|
||||
{
|
||||
security_bprm_committing_creds(bprm);
|
||||
|
||||
commit_creds(bprm->cred);
|
||||
bprm->cred = NULL;
|
||||
|
||||
/* cred_exec_mutex must be held at least to this point to prevent
|
||||
* ptrace_attach() from altering our determination of the task's
|
||||
* credentials; any time after this it may be unlocked */
|
||||
|
||||
security_bprm_committed_creds(bprm);
|
||||
}
|
||||
EXPORT_SYMBOL(install_exec_creds);
|
||||
|
||||
/*
|
||||
* determine how safe it is to execute the proposed program
|
||||
* - the caller must hold current->cred_exec_mutex to protect against
|
||||
* PTRACE_ATTACH
|
||||
*/
|
||||
void check_unsafe_exec(struct linux_binprm *bprm)
|
||||
{
|
||||
struct task_struct *p = current;
|
||||
|
||||
bprm->unsafe = tracehook_unsafe_exec(p);
|
||||
|
||||
if (atomic_read(&p->fs->count) > 1 ||
|
||||
atomic_read(&p->files->count) > 1 ||
|
||||
atomic_read(&p->sighand->count) > 1)
|
||||
bprm->unsafe |= LSM_UNSAFE_SHARE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Fill the binprm structure from the inode.
|
||||
* Check permissions, then read the first 128 (BINPRM_BUF_SIZE) bytes
|
||||
*
|
||||
* This may be called multiple times for binary chains (scripts for example).
|
||||
*/
|
||||
int prepare_binprm(struct linux_binprm *bprm)
|
||||
{
|
||||
int mode;
|
||||
umode_t mode;
|
||||
struct inode * inode = bprm->file->f_path.dentry->d_inode;
|
||||
int retval;
|
||||
|
||||
@ -1047,14 +1086,15 @@ int prepare_binprm(struct linux_binprm *bprm)
|
||||
if (bprm->file->f_op == NULL)
|
||||
return -EACCES;
|
||||
|
||||
bprm->e_uid = current->euid;
|
||||
bprm->e_gid = current->egid;
|
||||
/* clear any previous set[ug]id data from a previous binary */
|
||||
bprm->cred->euid = current_euid();
|
||||
bprm->cred->egid = current_egid();
|
||||
|
||||
if(!(bprm->file->f_path.mnt->mnt_flags & MNT_NOSUID)) {
|
||||
if (!(bprm->file->f_path.mnt->mnt_flags & MNT_NOSUID)) {
|
||||
/* Set-uid? */
|
||||
if (mode & S_ISUID) {
|
||||
current->personality &= ~PER_CLEAR_ON_SETID;
|
||||
bprm->e_uid = inode->i_uid;
|
||||
bprm->per_clear |= PER_CLEAR_ON_SETID;
|
||||
bprm->cred->euid = inode->i_uid;
|
||||
}
|
||||
|
||||
/* Set-gid? */
|
||||
@ -1064,52 +1104,23 @@ int prepare_binprm(struct linux_binprm *bprm)
|
||||
* executable.
|
||||
*/
|
||||
if ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) {
|
||||
current->personality &= ~PER_CLEAR_ON_SETID;
|
||||
bprm->e_gid = inode->i_gid;
|
||||
bprm->per_clear |= PER_CLEAR_ON_SETID;
|
||||
bprm->cred->egid = inode->i_gid;
|
||||
}
|
||||
}
|
||||
|
||||
/* fill in binprm security blob */
|
||||
retval = security_bprm_set(bprm);
|
||||
retval = security_bprm_set_creds(bprm);
|
||||
if (retval)
|
||||
return retval;
|
||||
bprm->cred_prepared = 1;
|
||||
|
||||
memset(bprm->buf,0,BINPRM_BUF_SIZE);
|
||||
return kernel_read(bprm->file,0,bprm->buf,BINPRM_BUF_SIZE);
|
||||
memset(bprm->buf, 0, BINPRM_BUF_SIZE);
|
||||
return kernel_read(bprm->file, 0, bprm->buf, BINPRM_BUF_SIZE);
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(prepare_binprm);
|
||||
|
||||
static int unsafe_exec(struct task_struct *p)
|
||||
{
|
||||
int unsafe = tracehook_unsafe_exec(p);
|
||||
|
||||
if (atomic_read(&p->fs->count) > 1 ||
|
||||
atomic_read(&p->files->count) > 1 ||
|
||||
atomic_read(&p->sighand->count) > 1)
|
||||
unsafe |= LSM_UNSAFE_SHARE;
|
||||
|
||||
return unsafe;
|
||||
}
|
||||
|
||||
void compute_creds(struct linux_binprm *bprm)
|
||||
{
|
||||
int unsafe;
|
||||
|
||||
if (bprm->e_uid != current->uid) {
|
||||
suid_keys(current);
|
||||
current->pdeath_signal = 0;
|
||||
}
|
||||
exec_keys(current);
|
||||
|
||||
task_lock(current);
|
||||
unsafe = unsafe_exec(current);
|
||||
security_bprm_apply_creds(bprm, unsafe);
|
||||
task_unlock(current);
|
||||
security_bprm_post_apply_creds(bprm);
|
||||
}
|
||||
EXPORT_SYMBOL(compute_creds);
|
||||
|
||||
/*
|
||||
* Arguments are '\0' separated strings found at the location bprm->p
|
||||
* points to; chop off the first by relocating brpm->p to right after
|
||||
@ -1270,6 +1281,8 @@ EXPORT_SYMBOL(search_binary_handler);
|
||||
void free_bprm(struct linux_binprm *bprm)
|
||||
{
|
||||
free_arg_pages(bprm);
|
||||
if (bprm->cred)
|
||||
abort_creds(bprm->cred);
|
||||
kfree(bprm);
|
||||
}
|
||||
|
||||
@ -1295,10 +1308,20 @@ int do_execve(char * filename,
|
||||
if (!bprm)
|
||||
goto out_files;
|
||||
|
||||
retval = mutex_lock_interruptible(¤t->cred_exec_mutex);
|
||||
if (retval < 0)
|
||||
goto out_free;
|
||||
|
||||
retval = -ENOMEM;
|
||||
bprm->cred = prepare_exec_creds();
|
||||
if (!bprm->cred)
|
||||
goto out_unlock;
|
||||
check_unsafe_exec(bprm);
|
||||
|
||||
file = open_exec(filename);
|
||||
retval = PTR_ERR(file);
|
||||
if (IS_ERR(file))
|
||||
goto out_kfree;
|
||||
goto out_unlock;
|
||||
|
||||
sched_exec();
|
||||
|
||||
@ -1312,14 +1335,10 @@ int do_execve(char * filename,
|
||||
|
||||
bprm->argc = count(argv, MAX_ARG_STRINGS);
|
||||
if ((retval = bprm->argc) < 0)
|
||||
goto out_mm;
|
||||
goto out;
|
||||
|
||||
bprm->envc = count(envp, MAX_ARG_STRINGS);
|
||||
if ((retval = bprm->envc) < 0)
|
||||
goto out_mm;
|
||||
|
||||
retval = security_bprm_alloc(bprm);
|
||||
if (retval)
|
||||
goto out;
|
||||
|
||||
retval = prepare_binprm(bprm);
|
||||
@ -1341,21 +1360,18 @@ int do_execve(char * filename,
|
||||
|
||||
current->flags &= ~PF_KTHREAD;
|
||||
retval = search_binary_handler(bprm,regs);
|
||||
if (retval >= 0) {
|
||||
/* execve success */
|
||||
security_bprm_free(bprm);
|
||||
acct_update_integrals(current);
|
||||
free_bprm(bprm);
|
||||
if (displaced)
|
||||
put_files_struct(displaced);
|
||||
return retval;
|
||||
}
|
||||
if (retval < 0)
|
||||
goto out;
|
||||
|
||||
/* execve succeeded */
|
||||
mutex_unlock(¤t->cred_exec_mutex);
|
||||
acct_update_integrals(current);
|
||||
free_bprm(bprm);
|
||||
if (displaced)
|
||||
put_files_struct(displaced);
|
||||
return retval;
|
||||
|
||||
out:
|
||||
if (bprm->security)
|
||||
security_bprm_free(bprm);
|
||||
|
||||
out_mm:
|
||||
if (bprm->mm)
|
||||
mmput (bprm->mm);
|
||||
|
||||
@ -1364,7 +1380,11 @@ out_file:
|
||||
allow_write_access(bprm->file);
|
||||
fput(bprm->file);
|
||||
}
|
||||
out_kfree:
|
||||
|
||||
out_unlock:
|
||||
mutex_unlock(¤t->cred_exec_mutex);
|
||||
|
||||
out_free:
|
||||
free_bprm(bprm);
|
||||
|
||||
out_files:
|
||||
@ -1396,6 +1416,7 @@ EXPORT_SYMBOL(set_binfmt);
|
||||
*/
|
||||
static int format_corename(char *corename, long signr)
|
||||
{
|
||||
const struct cred *cred = current_cred();
|
||||
const char *pat_ptr = core_pattern;
|
||||
int ispipe = (*pat_ptr == '|');
|
||||
char *out_ptr = corename;
|
||||
@ -1432,7 +1453,7 @@ static int format_corename(char *corename, long signr)
|
||||
/* uid */
|
||||
case 'u':
|
||||
rc = snprintf(out_ptr, out_end - out_ptr,
|
||||
"%d", current->uid);
|
||||
"%d", cred->uid);
|
||||
if (rc > out_end - out_ptr)
|
||||
goto out;
|
||||
out_ptr += rc;
|
||||
@ -1440,7 +1461,7 @@ static int format_corename(char *corename, long signr)
|
||||
/* gid */
|
||||
case 'g':
|
||||
rc = snprintf(out_ptr, out_end - out_ptr,
|
||||
"%d", current->gid);
|
||||
"%d", cred->gid);
|
||||
if (rc > out_end - out_ptr)
|
||||
goto out;
|
||||
out_ptr += rc;
|
||||
@ -1716,8 +1737,9 @@ int do_coredump(long signr, int exit_code, struct pt_regs * regs)
|
||||
struct linux_binfmt * binfmt;
|
||||
struct inode * inode;
|
||||
struct file * file;
|
||||
const struct cred *old_cred;
|
||||
struct cred *cred;
|
||||
int retval = 0;
|
||||
int fsuid = current->fsuid;
|
||||
int flag = 0;
|
||||
int ispipe = 0;
|
||||
unsigned long core_limit = current->signal->rlim[RLIMIT_CORE].rlim_cur;
|
||||
@ -1730,12 +1752,20 @@ int do_coredump(long signr, int exit_code, struct pt_regs * regs)
|
||||
binfmt = current->binfmt;
|
||||
if (!binfmt || !binfmt->core_dump)
|
||||
goto fail;
|
||||
|
||||
cred = prepare_creds();
|
||||
if (!cred) {
|
||||
retval = -ENOMEM;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
down_write(&mm->mmap_sem);
|
||||
/*
|
||||
* If another thread got here first, or we are not dumpable, bail out.
|
||||
*/
|
||||
if (mm->core_state || !get_dumpable(mm)) {
|
||||
up_write(&mm->mmap_sem);
|
||||
put_cred(cred);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
@ -1746,12 +1776,16 @@ int do_coredump(long signr, int exit_code, struct pt_regs * regs)
|
||||
*/
|
||||
if (get_dumpable(mm) == 2) { /* Setuid core dump mode */
|
||||
flag = O_EXCL; /* Stop rewrite attacks */
|
||||
current->fsuid = 0; /* Dump root private */
|
||||
cred->fsuid = 0; /* Dump root private */
|
||||
}
|
||||
|
||||
retval = coredump_wait(exit_code, &core_state);
|
||||
if (retval < 0)
|
||||
if (retval < 0) {
|
||||
put_cred(cred);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
old_cred = override_creds(cred);
|
||||
|
||||
/*
|
||||
* Clear any false indication of pending signals that might
|
||||
@ -1823,7 +1857,7 @@ int do_coredump(long signr, int exit_code, struct pt_regs * regs)
|
||||
* Dont allow local users get cute and trick others to coredump
|
||||
* into their pre-created files:
|
||||
*/
|
||||
if (inode->i_uid != current->fsuid)
|
||||
if (inode->i_uid != current_fsuid())
|
||||
goto close_fail;
|
||||
if (!file->f_op)
|
||||
goto close_fail;
|
||||
@ -1842,7 +1876,8 @@ fail_unlock:
|
||||
if (helper_argv)
|
||||
argv_free(helper_argv);
|
||||
|
||||
current->fsuid = fsuid;
|
||||
revert_creds(old_cred);
|
||||
put_cred(cred);
|
||||
coredump_finish(mm);
|
||||
fail:
|
||||
return retval;
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/mount.h>
|
||||
#include <linux/namei.h>
|
||||
#include <linux/sched.h>
|
||||
|
||||
#define dprintk(fmt, args...) do{}while(0)
|
||||
|
||||
@ -249,6 +250,7 @@ static int filldir_one(void * __buf, const char * name, int len,
|
||||
static int get_name(struct vfsmount *mnt, struct dentry *dentry,
|
||||
char *name, struct dentry *child)
|
||||
{
|
||||
const struct cred *cred = current_cred();
|
||||
struct inode *dir = dentry->d_inode;
|
||||
int error;
|
||||
struct file *file;
|
||||
@ -263,7 +265,7 @@ static int get_name(struct vfsmount *mnt, struct dentry *dentry,
|
||||
/*
|
||||
* Open the directory ...
|
||||
*/
|
||||
file = dentry_open(dget(dentry), mntget(mnt), O_RDONLY);
|
||||
file = dentry_open(dget(dentry), mntget(mnt), O_RDONLY, cred);
|
||||
error = PTR_ERR(file);
|
||||
if (IS_ERR(file))
|
||||
goto out;
|
||||
|
@ -1193,7 +1193,7 @@ static int ext2_has_free_blocks(struct ext2_sb_info *sbi)
|
||||
free_blocks = percpu_counter_read_positive(&sbi->s_freeblocks_counter);
|
||||
root_blocks = le32_to_cpu(sbi->s_es->s_r_blocks_count);
|
||||
if (free_blocks < root_blocks + 1 && !capable(CAP_SYS_RESOURCE) &&
|
||||
sbi->s_resuid != current->fsuid &&
|
||||
sbi->s_resuid != current_fsuid() &&
|
||||
(sbi->s_resgid == 0 || !in_group_p (sbi->s_resgid))) {
|
||||
return 0;
|
||||
}
|
||||
|
@ -550,7 +550,7 @@ got:
|
||||
|
||||
sb->s_dirt = 1;
|
||||
mark_buffer_dirty(bh2);
|
||||
inode->i_uid = current->fsuid;
|
||||
inode->i_uid = current_fsuid();
|
||||
if (test_opt (sb, GRPID))
|
||||
inode->i_gid = dir->i_gid;
|
||||
else if (dir->i_mode & S_ISGID) {
|
||||
@ -558,7 +558,7 @@ got:
|
||||
if (S_ISDIR(mode))
|
||||
mode |= S_ISGID;
|
||||
} else
|
||||
inode->i_gid = current->fsgid;
|
||||
inode->i_gid = current_fsgid();
|
||||
inode->i_mode = mode;
|
||||
|
||||
inode->i_ino = ino;
|
||||
|
@ -1422,7 +1422,7 @@ static int ext3_has_free_blocks(struct ext3_sb_info *sbi)
|
||||
free_blocks = percpu_counter_read_positive(&sbi->s_freeblocks_counter);
|
||||
root_blocks = le32_to_cpu(sbi->s_es->s_r_blocks_count);
|
||||
if (free_blocks < root_blocks + 1 && !capable(CAP_SYS_RESOURCE) &&
|
||||
sbi->s_resuid != current->fsuid &&
|
||||
sbi->s_resuid != current_fsuid() &&
|
||||
(sbi->s_resgid == 0 || !in_group_p (sbi->s_resgid))) {
|
||||
return 0;
|
||||
}
|
||||
|
@ -539,7 +539,7 @@ got:
|
||||
percpu_counter_inc(&sbi->s_dirs_counter);
|
||||
sb->s_dirt = 1;
|
||||
|
||||
inode->i_uid = current->fsuid;
|
||||
inode->i_uid = current_fsuid();
|
||||
if (test_opt (sb, GRPID))
|
||||
inode->i_gid = dir->i_gid;
|
||||
else if (dir->i_mode & S_ISGID) {
|
||||
@ -547,7 +547,7 @@ got:
|
||||
if (S_ISDIR(mode))
|
||||
mode |= S_ISGID;
|
||||
} else
|
||||
inode->i_gid = current->fsgid;
|
||||
inode->i_gid = current_fsgid();
|
||||
inode->i_mode = mode;
|
||||
|
||||
inode->i_ino = ino;
|
||||
|
@ -624,7 +624,7 @@ int ext4_has_free_blocks(struct ext4_sb_info *sbi, s64 nblocks)
|
||||
return 1;
|
||||
|
||||
/* Hm, nope. Are (enough) root reserved blocks available? */
|
||||
if (sbi->s_resuid == current->fsuid ||
|
||||
if (sbi->s_resuid == current_fsuid() ||
|
||||
((sbi->s_resgid != 0) && in_group_p(sbi->s_resgid)) ||
|
||||
capable(CAP_SYS_RESOURCE)) {
|
||||
if (free_blocks >= (nblocks + dirty_blocks))
|
||||
|
@ -787,7 +787,7 @@ got:
|
||||
spin_unlock(sb_bgl_lock(sbi, flex_group));
|
||||
}
|
||||
|
||||
inode->i_uid = current->fsuid;
|
||||
inode->i_uid = current_fsuid();
|
||||
if (test_opt(sb, GRPID))
|
||||
inode->i_gid = dir->i_gid;
|
||||
else if (dir->i_mode & S_ISGID) {
|
||||
@ -795,7 +795,7 @@ got:
|
||||
if (S_ISDIR(mode))
|
||||
mode |= S_ISGID;
|
||||
} else
|
||||
inode->i_gid = current->fsgid;
|
||||
inode->i_gid = current_fsgid();
|
||||
inode->i_mode = mode;
|
||||
|
||||
inode->i_ino = ino + group * EXT4_INODES_PER_GROUP(sb);
|
||||
|
@ -304,7 +304,7 @@ static int fat_allow_set_time(struct msdos_sb_info *sbi, struct inode *inode)
|
||||
{
|
||||
mode_t allow_utime = sbi->options.allow_utime;
|
||||
|
||||
if (current->fsuid != inode->i_uid) {
|
||||
if (current_fsuid() != inode->i_uid) {
|
||||
if (in_group_p(inode->i_gid))
|
||||
allow_utime >>= 3;
|
||||
if (allow_utime & MAY_WRITE)
|
||||
|
@ -926,8 +926,8 @@ static int parse_options(char *options, int is_vfat, int silent, int *debug,
|
||||
|
||||
opts->isvfat = is_vfat;
|
||||
|
||||
opts->fs_uid = current->uid;
|
||||
opts->fs_gid = current->gid;
|
||||
opts->fs_uid = current_uid();
|
||||
opts->fs_gid = current_gid();
|
||||
opts->fs_fmask = opts->fs_dmask = current->fs->umask;
|
||||
opts->allow_utime = -1;
|
||||
opts->codepage = fat_default_codepage;
|
||||
|
18
fs/fcntl.c
18
fs/fcntl.c
@ -212,13 +212,14 @@ static void f_modown(struct file *filp, struct pid *pid, enum pid_type type,
|
||||
int __f_setown(struct file *filp, struct pid *pid, enum pid_type type,
|
||||
int force)
|
||||
{
|
||||
const struct cred *cred = current_cred();
|
||||
int err;
|
||||
|
||||
err = security_file_set_fowner(filp);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
f_modown(filp, pid, type, current->uid, current->euid, force);
|
||||
f_modown(filp, pid, type, cred->uid, cred->euid, force);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(__f_setown);
|
||||
@ -407,10 +408,17 @@ static const long band_table[NSIGPOLL] = {
|
||||
static inline int sigio_perm(struct task_struct *p,
|
||||
struct fown_struct *fown, int sig)
|
||||
{
|
||||
return (((fown->euid == 0) ||
|
||||
(fown->euid == p->suid) || (fown->euid == p->uid) ||
|
||||
(fown->uid == p->suid) || (fown->uid == p->uid)) &&
|
||||
!security_file_send_sigiotask(p, fown, sig));
|
||||
const struct cred *cred;
|
||||
int ret;
|
||||
|
||||
rcu_read_lock();
|
||||
cred = __task_cred(p);
|
||||
ret = ((fown->euid == 0 ||
|
||||
fown->euid == cred->suid || fown->euid == cred->uid ||
|
||||
fown->uid == cred->suid || fown->uid == cred->uid) &&
|
||||
!security_file_send_sigiotask(p, fown, sig));
|
||||
rcu_read_unlock();
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void send_sigio_to_task(struct task_struct *p,
|
||||
|
@ -36,7 +36,9 @@ static struct percpu_counter nr_files __cacheline_aligned_in_smp;
|
||||
|
||||
static inline void file_free_rcu(struct rcu_head *head)
|
||||
{
|
||||
struct file *f = container_of(head, struct file, f_u.fu_rcuhead);
|
||||
struct file *f = container_of(head, struct file, f_u.fu_rcuhead);
|
||||
|
||||
put_cred(f->f_cred);
|
||||
kmem_cache_free(filp_cachep, f);
|
||||
}
|
||||
|
||||
@ -94,7 +96,7 @@ int proc_nr_files(ctl_table *table, int write, struct file *filp,
|
||||
*/
|
||||
struct file *get_empty_filp(void)
|
||||
{
|
||||
struct task_struct *tsk;
|
||||
const struct cred *cred = current_cred();
|
||||
static int old_max;
|
||||
struct file * f;
|
||||
|
||||
@ -118,12 +120,10 @@ struct file *get_empty_filp(void)
|
||||
if (security_file_alloc(f))
|
||||
goto fail_sec;
|
||||
|
||||
tsk = current;
|
||||
INIT_LIST_HEAD(&f->f_u.fu_list);
|
||||
atomic_long_set(&f->f_count, 1);
|
||||
rwlock_init(&f->f_owner.lock);
|
||||
f->f_uid = tsk->fsuid;
|
||||
f->f_gid = tsk->fsgid;
|
||||
f->f_cred = get_cred(cred);
|
||||
eventpoll_init_file(f);
|
||||
/* f->f_version: 0 */
|
||||
return f;
|
||||
|
@ -87,8 +87,8 @@ static void __fuse_put_request(struct fuse_req *req)
|
||||
|
||||
static void fuse_req_init_context(struct fuse_req *req)
|
||||
{
|
||||
req->in.h.uid = current->fsuid;
|
||||
req->in.h.gid = current->fsgid;
|
||||
req->in.h.uid = current_fsuid();
|
||||
req->in.h.gid = current_fsgid();
|
||||
req->in.h.pid = current->pid;
|
||||
}
|
||||
|
||||
|
@ -869,18 +869,25 @@ int fuse_update_attributes(struct inode *inode, struct kstat *stat,
|
||||
*/
|
||||
int fuse_allow_task(struct fuse_conn *fc, struct task_struct *task)
|
||||
{
|
||||
const struct cred *cred;
|
||||
int ret;
|
||||
|
||||
if (fc->flags & FUSE_ALLOW_OTHER)
|
||||
return 1;
|
||||
|
||||
if (task->euid == fc->user_id &&
|
||||
task->suid == fc->user_id &&
|
||||
task->uid == fc->user_id &&
|
||||
task->egid == fc->group_id &&
|
||||
task->sgid == fc->group_id &&
|
||||
task->gid == fc->group_id)
|
||||
return 1;
|
||||
rcu_read_lock();
|
||||
ret = 0;
|
||||
cred = __task_cred(task);
|
||||
if (cred->euid == fc->user_id &&
|
||||
cred->suid == fc->user_id &&
|
||||
cred->uid == fc->user_id &&
|
||||
cred->egid == fc->group_id &&
|
||||
cred->sgid == fc->group_id &&
|
||||
cred->gid == fc->group_id)
|
||||
ret = 1;
|
||||
rcu_read_unlock();
|
||||
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int fuse_access(struct inode *inode, int mask)
|
||||
|
@ -705,18 +705,18 @@ static void munge_mode_uid_gid(struct gfs2_inode *dip, unsigned int *mode,
|
||||
(dip->i_inode.i_mode & S_ISUID) && dip->i_inode.i_uid) {
|
||||
if (S_ISDIR(*mode))
|
||||
*mode |= S_ISUID;
|
||||
else if (dip->i_inode.i_uid != current->fsuid)
|
||||
else if (dip->i_inode.i_uid != current_fsuid())
|
||||
*mode &= ~07111;
|
||||
*uid = dip->i_inode.i_uid;
|
||||
} else
|
||||
*uid = current->fsuid;
|
||||
*uid = current_fsuid();
|
||||
|
||||
if (dip->i_inode.i_mode & S_ISGID) {
|
||||
if (S_ISDIR(*mode))
|
||||
*mode |= S_ISGID;
|
||||
*gid = dip->i_inode.i_gid;
|
||||
} else
|
||||
*gid = current->fsgid;
|
||||
*gid = current_fsgid();
|
||||
}
|
||||
|
||||
static int alloc_dinode(struct gfs2_inode *dip, u64 *no_addr, u64 *generation)
|
||||
@ -1124,8 +1124,8 @@ int gfs2_unlink_ok(struct gfs2_inode *dip, const struct qstr *name,
|
||||
return -EPERM;
|
||||
|
||||
if ((dip->i_inode.i_mode & S_ISVTX) &&
|
||||
dip->i_inode.i_uid != current->fsuid &&
|
||||
ip->i_inode.i_uid != current->fsuid && !capable(CAP_FOWNER))
|
||||
dip->i_inode.i_uid != current_fsuid() &&
|
||||
ip->i_inode.i_uid != current_fsuid() && !capable(CAP_FOWNER))
|
||||
return -EPERM;
|
||||
|
||||
if (IS_APPEND(&dip->i_inode))
|
||||
|
@ -155,8 +155,8 @@ struct inode *hfs_new_inode(struct inode *dir, struct qstr *name, int mode)
|
||||
hfs_cat_build_key(sb, (btree_key *)&HFS_I(inode)->cat_key, dir->i_ino, name);
|
||||
inode->i_ino = HFS_SB(sb)->next_id++;
|
||||
inode->i_mode = mode;
|
||||
inode->i_uid = current->fsuid;
|
||||
inode->i_gid = current->fsgid;
|
||||
inode->i_uid = current_fsuid();
|
||||
inode->i_gid = current_fsgid();
|
||||
inode->i_nlink = 1;
|
||||
inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME_SEC;
|
||||
HFS_I(inode)->flags = 0;
|
||||
|
@ -210,8 +210,8 @@ static int parse_options(char *options, struct hfs_sb_info *hsb)
|
||||
int tmp, token;
|
||||
|
||||
/* initialize the sb with defaults */
|
||||
hsb->s_uid = current->uid;
|
||||
hsb->s_gid = current->gid;
|
||||
hsb->s_uid = current_uid();
|
||||
hsb->s_gid = current_gid();
|
||||
hsb->s_file_umask = 0133;
|
||||
hsb->s_dir_umask = 0022;
|
||||
hsb->s_type = hsb->s_creator = cpu_to_be32(0x3f3f3f3f); /* == '????' */
|
||||
|
@ -296,8 +296,8 @@ struct inode *hfsplus_new_inode(struct super_block *sb, int mode)
|
||||
|
||||
inode->i_ino = HFSPLUS_SB(sb).next_cnid++;
|
||||
inode->i_mode = mode;
|
||||
inode->i_uid = current->fsuid;
|
||||
inode->i_gid = current->fsgid;
|
||||
inode->i_uid = current_fsuid();
|
||||
inode->i_gid = current_fsgid();
|
||||
inode->i_nlink = 1;
|
||||
inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME_SEC;
|
||||
INIT_LIST_HEAD(&HFSPLUS_I(inode).open_dir_list);
|
||||
|
@ -49,8 +49,8 @@ void hfsplus_fill_defaults(struct hfsplus_sb_info *opts)
|
||||
opts->creator = HFSPLUS_DEF_CR_TYPE;
|
||||
opts->type = HFSPLUS_DEF_CR_TYPE;
|
||||
opts->umask = current->fs->umask;
|
||||
opts->uid = current->uid;
|
||||
opts->gid = current->gid;
|
||||
opts->uid = current_uid();
|
||||
opts->gid = current_gid();
|
||||
opts->part = -1;
|
||||
opts->session = -1;
|
||||
}
|
||||
|
@ -92,11 +92,11 @@ static int hpfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
|
||||
inc_nlink(dir);
|
||||
insert_inode_hash(result);
|
||||
|
||||
if (result->i_uid != current->fsuid ||
|
||||
result->i_gid != current->fsgid ||
|
||||
if (result->i_uid != current_fsuid() ||
|
||||
result->i_gid != current_fsgid() ||
|
||||
result->i_mode != (mode | S_IFDIR)) {
|
||||
result->i_uid = current->fsuid;
|
||||
result->i_gid = current->fsgid;
|
||||
result->i_uid = current_fsuid();
|
||||
result->i_gid = current_fsgid();
|
||||
result->i_mode = mode | S_IFDIR;
|
||||
hpfs_write_inode_nolock(result);
|
||||
}
|
||||
@ -184,11 +184,11 @@ static int hpfs_create(struct inode *dir, struct dentry *dentry, int mode, struc
|
||||
|
||||
insert_inode_hash(result);
|
||||
|
||||
if (result->i_uid != current->fsuid ||
|
||||
result->i_gid != current->fsgid ||
|
||||
if (result->i_uid != current_fsuid() ||
|
||||
result->i_gid != current_fsgid() ||
|
||||
result->i_mode != (mode | S_IFREG)) {
|
||||
result->i_uid = current->fsuid;
|
||||
result->i_gid = current->fsgid;
|
||||
result->i_uid = current_fsuid();
|
||||
result->i_gid = current_fsgid();
|
||||
result->i_mode = mode | S_IFREG;
|
||||
hpfs_write_inode_nolock(result);
|
||||
}
|
||||
@ -247,8 +247,8 @@ static int hpfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t
|
||||
result->i_mtime.tv_nsec = 0;
|
||||
result->i_atime.tv_nsec = 0;
|
||||
hpfs_i(result)->i_ea_size = 0;
|
||||
result->i_uid = current->fsuid;
|
||||
result->i_gid = current->fsgid;
|
||||
result->i_uid = current_fsuid();
|
||||
result->i_gid = current_fsgid();
|
||||
result->i_nlink = 1;
|
||||
result->i_size = 0;
|
||||
result->i_blocks = 1;
|
||||
@ -325,8 +325,8 @@ static int hpfs_symlink(struct inode *dir, struct dentry *dentry, const char *sy
|
||||
result->i_atime.tv_nsec = 0;
|
||||
hpfs_i(result)->i_ea_size = 0;
|
||||
result->i_mode = S_IFLNK | 0777;
|
||||
result->i_uid = current->fsuid;
|
||||
result->i_gid = current->fsgid;
|
||||
result->i_uid = current_fsuid();
|
||||
result->i_gid = current_fsgid();
|
||||
result->i_blocks = 1;
|
||||
result->i_nlink = 1;
|
||||
result->i_size = strlen(symlink);
|
||||
|
@ -475,8 +475,8 @@ static int hpfs_fill_super(struct super_block *s, void *options, int silent)
|
||||
|
||||
init_MUTEX(&sbi->hpfs_creation_de);
|
||||
|
||||
uid = current->uid;
|
||||
gid = current->gid;
|
||||
uid = current_uid();
|
||||
gid = current_gid();
|
||||
umask = current->fs->umask;
|
||||
lowercase = 0;
|
||||
conv = CONV_BINARY;
|
||||
|
@ -426,6 +426,7 @@ static int file_mode(int fmode)
|
||||
|
||||
static int hppfs_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
const struct cred *cred = file->f_cred;
|
||||
struct hppfs_private *data;
|
||||
struct vfsmount *proc_mnt;
|
||||
struct dentry *proc_dentry;
|
||||
@ -446,7 +447,7 @@ static int hppfs_open(struct inode *inode, struct file *file)
|
||||
|
||||
/* XXX This isn't closed anywhere */
|
||||
data->proc_file = dentry_open(dget(proc_dentry), mntget(proc_mnt),
|
||||
file_mode(file->f_mode));
|
||||
file_mode(file->f_mode), cred);
|
||||
err = PTR_ERR(data->proc_file);
|
||||
if (IS_ERR(data->proc_file))
|
||||
goto out_free1;
|
||||
@ -489,6 +490,7 @@ static int hppfs_open(struct inode *inode, struct file *file)
|
||||
|
||||
static int hppfs_dir_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
const struct cred *cred = file->f_cred;
|
||||
struct hppfs_private *data;
|
||||
struct vfsmount *proc_mnt;
|
||||
struct dentry *proc_dentry;
|
||||
@ -502,7 +504,7 @@ static int hppfs_dir_open(struct inode *inode, struct file *file)
|
||||
proc_dentry = HPPFS_I(inode)->proc_dentry;
|
||||
proc_mnt = inode->i_sb->s_fs_info;
|
||||
data->proc_file = dentry_open(dget(proc_dentry), mntget(proc_mnt),
|
||||
file_mode(file->f_mode));
|
||||
file_mode(file->f_mode), cred);
|
||||
err = PTR_ERR(data->proc_file);
|
||||
if (IS_ERR(data->proc_file))
|
||||
goto out_free;
|
||||
|
@ -551,9 +551,9 @@ static int hugetlbfs_mknod(struct inode *dir,
|
||||
if (S_ISDIR(mode))
|
||||
mode |= S_ISGID;
|
||||
} else {
|
||||
gid = current->fsgid;
|
||||
gid = current_fsgid();
|
||||
}
|
||||
inode = hugetlbfs_get_inode(dir->i_sb, current->fsuid, gid, mode, dev);
|
||||
inode = hugetlbfs_get_inode(dir->i_sb, current_fsuid(), gid, mode, dev);
|
||||
if (inode) {
|
||||
dir->i_ctime = dir->i_mtime = CURRENT_TIME;
|
||||
d_instantiate(dentry, inode);
|
||||
@ -586,9 +586,9 @@ static int hugetlbfs_symlink(struct inode *dir,
|
||||
if (dir->i_mode & S_ISGID)
|
||||
gid = dir->i_gid;
|
||||
else
|
||||
gid = current->fsgid;
|
||||
gid = current_fsgid();
|
||||
|
||||
inode = hugetlbfs_get_inode(dir->i_sb, current->fsuid,
|
||||
inode = hugetlbfs_get_inode(dir->i_sb, current_fsuid(),
|
||||
gid, S_IFLNK|S_IRWXUGO, 0);
|
||||
if (inode) {
|
||||
int l = strlen(symname)+1;
|
||||
@ -854,8 +854,8 @@ hugetlbfs_fill_super(struct super_block *sb, void *data, int silent)
|
||||
|
||||
config.nr_blocks = -1; /* No limit on size by default */
|
||||
config.nr_inodes = -1; /* No limit on number of inodes by default */
|
||||
config.uid = current->fsuid;
|
||||
config.gid = current->fsgid;
|
||||
config.uid = current_fsuid();
|
||||
config.gid = current_fsgid();
|
||||
config.mode = 0755;
|
||||
config.hstate = &default_hstate;
|
||||
ret = hugetlbfs_parse_options(data, &config);
|
||||
@ -951,6 +951,7 @@ struct file *hugetlb_file_setup(const char *name, size_t size)
|
||||
struct inode *inode;
|
||||
struct dentry *dentry, *root;
|
||||
struct qstr quick_string;
|
||||
struct user_struct *user = current_user();
|
||||
|
||||
if (!hugetlbfs_vfsmount)
|
||||
return ERR_PTR(-ENOENT);
|
||||
@ -958,7 +959,7 @@ struct file *hugetlb_file_setup(const char *name, size_t size)
|
||||
if (!can_do_hugetlb_shm())
|
||||
return ERR_PTR(-EPERM);
|
||||
|
||||
if (!user_shm_lock(size, current->user))
|
||||
if (!user_shm_lock(size, user))
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
root = hugetlbfs_vfsmount->mnt_root;
|
||||
@ -970,8 +971,8 @@ struct file *hugetlb_file_setup(const char *name, size_t size)
|
||||
goto out_shm_unlock;
|
||||
|
||||
error = -ENOSPC;
|
||||
inode = hugetlbfs_get_inode(root->d_sb, current->fsuid,
|
||||
current->fsgid, S_IFREG | S_IRWXUGO, 0);
|
||||
inode = hugetlbfs_get_inode(root->d_sb, current_fsuid(),
|
||||
current_fsgid(), S_IFREG | S_IRWXUGO, 0);
|
||||
if (!inode)
|
||||
goto out_dentry;
|
||||
|
||||
@ -998,7 +999,7 @@ out_inode:
|
||||
out_dentry:
|
||||
dput(dentry);
|
||||
out_shm_unlock:
|
||||
user_shm_unlock(size, current->user);
|
||||
user_shm_unlock(size, user);
|
||||
return ERR_PTR(error);
|
||||
}
|
||||
|
||||
|
@ -601,7 +601,7 @@ asmlinkage long sys_inotify_init1(int flags)
|
||||
goto out_put_fd;
|
||||
}
|
||||
|
||||
user = get_uid(current->user);
|
||||
user = get_current_user();
|
||||
if (unlikely(atomic_read(&user->inotify_devs) >=
|
||||
inotify_max_user_instances)) {
|
||||
ret = -EMFILE;
|
||||
|
@ -10,6 +10,7 @@
|
||||
*/
|
||||
|
||||
struct super_block;
|
||||
struct linux_binprm;
|
||||
|
||||
/*
|
||||
* block_dev.c
|
||||
@ -39,6 +40,11 @@ static inline int sb_is_blkdev_sb(struct super_block *sb)
|
||||
*/
|
||||
extern void __init chrdev_init(void);
|
||||
|
||||
/*
|
||||
* exec.c
|
||||
*/
|
||||
extern void check_unsafe_exec(struct linux_binprm *);
|
||||
|
||||
/*
|
||||
* namespace.c
|
||||
*/
|
||||
|
18
fs/ioprio.c
18
fs/ioprio.c
@ -31,10 +31,16 @@ static int set_task_ioprio(struct task_struct *task, int ioprio)
|
||||
{
|
||||
int err;
|
||||
struct io_context *ioc;
|
||||
const struct cred *cred = current_cred(), *tcred;
|
||||
|
||||
if (task->uid != current->euid &&
|
||||
task->uid != current->uid && !capable(CAP_SYS_NICE))
|
||||
rcu_read_lock();
|
||||
tcred = __task_cred(task);
|
||||
if (tcred->uid != cred->euid &&
|
||||
tcred->uid != cred->uid && !capable(CAP_SYS_NICE)) {
|
||||
rcu_read_unlock();
|
||||
return -EPERM;
|
||||
}
|
||||
rcu_read_unlock();
|
||||
|
||||
err = security_task_setioprio(task, ioprio);
|
||||
if (err)
|
||||
@ -123,7 +129,7 @@ asmlinkage long sys_ioprio_set(int which, int who, int ioprio)
|
||||
break;
|
||||
case IOPRIO_WHO_USER:
|
||||
if (!who)
|
||||
user = current->user;
|
||||
user = current_user();
|
||||
else
|
||||
user = find_user(who);
|
||||
|
||||
@ -131,7 +137,7 @@ asmlinkage long sys_ioprio_set(int which, int who, int ioprio)
|
||||
break;
|
||||
|
||||
do_each_thread(g, p) {
|
||||
if (p->uid != who)
|
||||
if (__task_cred(p)->uid != who)
|
||||
continue;
|
||||
ret = set_task_ioprio(p, ioprio);
|
||||
if (ret)
|
||||
@ -216,7 +222,7 @@ asmlinkage long sys_ioprio_get(int which, int who)
|
||||
break;
|
||||
case IOPRIO_WHO_USER:
|
||||
if (!who)
|
||||
user = current->user;
|
||||
user = current_user();
|
||||
else
|
||||
user = find_user(who);
|
||||
|
||||
@ -224,7 +230,7 @@ asmlinkage long sys_ioprio_get(int which, int who)
|
||||
break;
|
||||
|
||||
do_each_thread(g, p) {
|
||||
if (p->uid != user->uid)
|
||||
if (__task_cred(p)->uid != user->uid)
|
||||
continue;
|
||||
tmpio = get_task_ioprio(p);
|
||||
if (tmpio < 0)
|
||||
|
@ -93,13 +93,13 @@ struct inode *ialloc(struct inode *parent, umode_t mode)
|
||||
return ERR_PTR(rc);
|
||||
}
|
||||
|
||||
inode->i_uid = current->fsuid;
|
||||
inode->i_uid = current_fsuid();
|
||||
if (parent->i_mode & S_ISGID) {
|
||||
inode->i_gid = parent->i_gid;
|
||||
if (S_ISDIR(mode))
|
||||
mode |= S_ISGID;
|
||||
} else
|
||||
inode->i_gid = current->fsgid;
|
||||
inode->i_gid = current_fsgid();
|
||||
|
||||
/*
|
||||
* New inodes need to save sane values on disk when
|
||||
|
@ -1349,7 +1349,7 @@ int generic_setlease(struct file *filp, long arg, struct file_lock **flp)
|
||||
struct inode *inode = dentry->d_inode;
|
||||
int error, rdlease_count = 0, wrlease_count = 0;
|
||||
|
||||
if ((current->fsuid != inode->i_uid) && !capable(CAP_LEASE))
|
||||
if ((current_fsuid() != inode->i_uid) && !capable(CAP_LEASE))
|
||||
return -EACCES;
|
||||
if (!S_ISREG(inode->i_mode))
|
||||
return -EINVAL;
|
||||
|
@ -262,8 +262,8 @@ struct inode * minix_new_inode(const struct inode * dir, int * error)
|
||||
iput(inode);
|
||||
return NULL;
|
||||
}
|
||||
inode->i_uid = current->fsuid;
|
||||
inode->i_gid = (dir->i_mode & S_ISGID) ? dir->i_gid : current->fsgid;
|
||||
inode->i_uid = current_fsuid();
|
||||
inode->i_gid = (dir->i_mode & S_ISGID) ? dir->i_gid : current_fsgid();
|
||||
inode->i_ino = j;
|
||||
inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME_SEC;
|
||||
inode->i_blocks = 0;
|
||||
|
10
fs/namei.c
10
fs/namei.c
@ -186,7 +186,7 @@ int generic_permission(struct inode *inode, int mask,
|
||||
|
||||
mask &= MAY_READ | MAY_WRITE | MAY_EXEC;
|
||||
|
||||
if (current->fsuid == inode->i_uid)
|
||||
if (current_fsuid() == inode->i_uid)
|
||||
mode >>= 6;
|
||||
else {
|
||||
if (IS_POSIXACL(inode) && (mode & S_IRWXG) && check_acl) {
|
||||
@ -441,7 +441,7 @@ static int exec_permission_lite(struct inode *inode)
|
||||
if (inode->i_op && inode->i_op->permission)
|
||||
return -EAGAIN;
|
||||
|
||||
if (current->fsuid == inode->i_uid)
|
||||
if (current_fsuid() == inode->i_uid)
|
||||
mode >>= 6;
|
||||
else if (in_group_p(inode->i_gid))
|
||||
mode >>= 3;
|
||||
@ -1334,11 +1334,13 @@ static int user_path_parent(int dfd, const char __user *path,
|
||||
*/
|
||||
static inline int check_sticky(struct inode *dir, struct inode *inode)
|
||||
{
|
||||
uid_t fsuid = current_fsuid();
|
||||
|
||||
if (!(dir->i_mode & S_ISVTX))
|
||||
return 0;
|
||||
if (inode->i_uid == current->fsuid)
|
||||
if (inode->i_uid == fsuid)
|
||||
return 0;
|
||||
if (dir->i_uid == current->fsuid)
|
||||
if (dir->i_uid == fsuid)
|
||||
return 0;
|
||||
return !capable(CAP_FOWNER);
|
||||
}
|
||||
|
@ -1176,7 +1176,7 @@ static int mount_is_safe(struct path *path)
|
||||
if (S_ISLNK(path->dentry->d_inode->i_mode))
|
||||
return -EPERM;
|
||||
if (path->dentry->d_inode->i_mode & S_ISVTX) {
|
||||
if (current->uid != path->dentry->d_inode->i_uid)
|
||||
if (current_uid() != path->dentry->d_inode->i_uid)
|
||||
return -EPERM;
|
||||
}
|
||||
if (inode_permission(path->dentry->d_inode, MAY_WRITE))
|
||||
|
@ -40,10 +40,10 @@ ncp_get_fs_info(struct ncp_server * server, struct file *file,
|
||||
struct inode *inode = file->f_path.dentry->d_inode;
|
||||
struct ncp_fs_info info;
|
||||
|
||||
if ((file_permission(file, MAY_WRITE) != 0)
|
||||
&& (current->uid != server->m.mounted_uid)) {
|
||||
if (file_permission(file, MAY_WRITE) != 0
|
||||
&& current_uid() != server->m.mounted_uid)
|
||||
return -EACCES;
|
||||
}
|
||||
|
||||
if (copy_from_user(&info, arg, sizeof(info)))
|
||||
return -EFAULT;
|
||||
|
||||
@ -70,10 +70,10 @@ ncp_get_fs_info_v2(struct ncp_server * server, struct file *file,
|
||||
struct inode *inode = file->f_path.dentry->d_inode;
|
||||
struct ncp_fs_info_v2 info2;
|
||||
|
||||
if ((file_permission(file, MAY_WRITE) != 0)
|
||||
&& (current->uid != server->m.mounted_uid)) {
|
||||
if (file_permission(file, MAY_WRITE) != 0
|
||||
&& current_uid() != server->m.mounted_uid)
|
||||
return -EACCES;
|
||||
}
|
||||
|
||||
if (copy_from_user(&info2, arg, sizeof(info2)))
|
||||
return -EFAULT;
|
||||
|
||||
@ -141,10 +141,10 @@ ncp_get_compat_fs_info_v2(struct ncp_server * server, struct file *file,
|
||||
struct inode *inode = file->f_path.dentry->d_inode;
|
||||
struct compat_ncp_fs_info_v2 info2;
|
||||
|
||||
if ((file_permission(file, MAY_WRITE) != 0)
|
||||
&& (current->uid != server->m.mounted_uid)) {
|
||||
if (file_permission(file, MAY_WRITE) != 0
|
||||
&& current_uid() != server->m.mounted_uid)
|
||||
return -EACCES;
|
||||
}
|
||||
|
||||
if (copy_from_user(&info2, arg, sizeof(info2)))
|
||||
return -EFAULT;
|
||||
|
||||
@ -270,16 +270,17 @@ static int __ncp_ioctl(struct inode *inode, struct file *filp,
|
||||
struct ncp_ioctl_request request;
|
||||
char* bouncebuffer;
|
||||
void __user *argp = (void __user *)arg;
|
||||
uid_t uid = current_uid();
|
||||
|
||||
switch (cmd) {
|
||||
#ifdef CONFIG_COMPAT
|
||||
case NCP_IOC_NCPREQUEST_32:
|
||||
#endif
|
||||
case NCP_IOC_NCPREQUEST:
|
||||
if ((file_permission(filp, MAY_WRITE) != 0)
|
||||
&& (current->uid != server->m.mounted_uid)) {
|
||||
if (file_permission(filp, MAY_WRITE) != 0
|
||||
&& uid != server->m.mounted_uid)
|
||||
return -EACCES;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_COMPAT
|
||||
if (cmd == NCP_IOC_NCPREQUEST_32) {
|
||||
struct compat_ncp_ioctl_request request32;
|
||||
@ -356,10 +357,10 @@ static int __ncp_ioctl(struct inode *inode, struct file *filp,
|
||||
case NCP_IOC_GETMOUNTUID16:
|
||||
case NCP_IOC_GETMOUNTUID32:
|
||||
case NCP_IOC_GETMOUNTUID64:
|
||||
if ((file_permission(filp, MAY_READ) != 0)
|
||||
&& (current->uid != server->m.mounted_uid)) {
|
||||
if (file_permission(filp, MAY_READ) != 0
|
||||
&& uid != server->m.mounted_uid)
|
||||
return -EACCES;
|
||||
}
|
||||
|
||||
if (cmd == NCP_IOC_GETMOUNTUID16) {
|
||||
u16 uid;
|
||||
SET_UID(uid, server->m.mounted_uid);
|
||||
@ -380,11 +381,10 @@ static int __ncp_ioctl(struct inode *inode, struct file *filp,
|
||||
{
|
||||
struct ncp_setroot_ioctl sr;
|
||||
|
||||
if ((file_permission(filp, MAY_READ) != 0)
|
||||
&& (current->uid != server->m.mounted_uid))
|
||||
{
|
||||
if (file_permission(filp, MAY_READ) != 0
|
||||
&& uid != server->m.mounted_uid)
|
||||
return -EACCES;
|
||||
}
|
||||
|
||||
if (server->m.mounted_vol[0]) {
|
||||
struct dentry* dentry = inode->i_sb->s_root;
|
||||
|
||||
@ -408,6 +408,7 @@ static int __ncp_ioctl(struct inode *inode, struct file *filp,
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
}
|
||||
|
||||
case NCP_IOC_SETROOT:
|
||||
{
|
||||
struct ncp_setroot_ioctl sr;
|
||||
@ -455,11 +456,10 @@ static int __ncp_ioctl(struct inode *inode, struct file *filp,
|
||||
|
||||
#ifdef CONFIG_NCPFS_PACKET_SIGNING
|
||||
case NCP_IOC_SIGN_INIT:
|
||||
if ((file_permission(filp, MAY_WRITE) != 0)
|
||||
&& (current->uid != server->m.mounted_uid))
|
||||
{
|
||||
if (file_permission(filp, MAY_WRITE) != 0
|
||||
&& uid != server->m.mounted_uid)
|
||||
return -EACCES;
|
||||
}
|
||||
|
||||
if (argp) {
|
||||
if (server->sign_wanted)
|
||||
{
|
||||
@ -478,24 +478,22 @@ static int __ncp_ioctl(struct inode *inode, struct file *filp,
|
||||
return 0;
|
||||
|
||||
case NCP_IOC_SIGN_WANTED:
|
||||
if ((file_permission(filp, MAY_READ) != 0)
|
||||
&& (current->uid != server->m.mounted_uid))
|
||||
{
|
||||
if (file_permission(filp, MAY_READ) != 0
|
||||
&& uid != server->m.mounted_uid)
|
||||
return -EACCES;
|
||||
}
|
||||
|
||||
if (put_user(server->sign_wanted, (int __user *)argp))
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
|
||||
case NCP_IOC_SET_SIGN_WANTED:
|
||||
{
|
||||
int newstate;
|
||||
|
||||
if ((file_permission(filp, MAY_WRITE) != 0)
|
||||
&& (current->uid != server->m.mounted_uid))
|
||||
{
|
||||
if (file_permission(filp, MAY_WRITE) != 0
|
||||
&& uid != server->m.mounted_uid)
|
||||
return -EACCES;
|
||||
}
|
||||
|
||||
/* get only low 8 bits... */
|
||||
if (get_user(newstate, (unsigned char __user *)argp))
|
||||
return -EFAULT;
|
||||
@ -512,11 +510,10 @@ static int __ncp_ioctl(struct inode *inode, struct file *filp,
|
||||
|
||||
#ifdef CONFIG_NCPFS_IOCTL_LOCKING
|
||||
case NCP_IOC_LOCKUNLOCK:
|
||||
if ((file_permission(filp, MAY_WRITE) != 0)
|
||||
&& (current->uid != server->m.mounted_uid))
|
||||
{
|
||||
if (file_permission(filp, MAY_WRITE) != 0
|
||||
&& uid != server->m.mounted_uid)
|
||||
return -EACCES;
|
||||
}
|
||||
|
||||
{
|
||||
struct ncp_lock_ioctl rqdata;
|
||||
|
||||
@ -585,9 +582,8 @@ outrel:
|
||||
|
||||
#ifdef CONFIG_COMPAT
|
||||
case NCP_IOC_GETOBJECTNAME_32:
|
||||
if (current->uid != server->m.mounted_uid) {
|
||||
if (uid != server->m.mounted_uid)
|
||||
return -EACCES;
|
||||
}
|
||||
{
|
||||
struct compat_ncp_objectname_ioctl user;
|
||||
size_t outl;
|
||||
@ -609,10 +605,10 @@ outrel:
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
case NCP_IOC_GETOBJECTNAME:
|
||||
if (current->uid != server->m.mounted_uid) {
|
||||
if (uid != server->m.mounted_uid)
|
||||
return -EACCES;
|
||||
}
|
||||
{
|
||||
struct ncp_objectname_ioctl user;
|
||||
size_t outl;
|
||||
@ -633,13 +629,13 @@ outrel:
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_COMPAT
|
||||
case NCP_IOC_SETOBJECTNAME_32:
|
||||
#endif
|
||||
case NCP_IOC_SETOBJECTNAME:
|
||||
if (current->uid != server->m.mounted_uid) {
|
||||
if (uid != server->m.mounted_uid)
|
||||
return -EACCES;
|
||||
}
|
||||
{
|
||||
struct ncp_objectname_ioctl user;
|
||||
void* newname;
|
||||
@ -691,13 +687,13 @@ outrel:
|
||||
kfree(oldname);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_COMPAT
|
||||
case NCP_IOC_GETPRIVATEDATA_32:
|
||||
#endif
|
||||
case NCP_IOC_GETPRIVATEDATA:
|
||||
if (current->uid != server->m.mounted_uid) {
|
||||
if (uid != server->m.mounted_uid)
|
||||
return -EACCES;
|
||||
}
|
||||
{
|
||||
struct ncp_privatedata_ioctl user;
|
||||
size_t outl;
|
||||
@ -736,13 +732,13 @@ outrel:
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_COMPAT
|
||||
case NCP_IOC_SETPRIVATEDATA_32:
|
||||
#endif
|
||||
case NCP_IOC_SETPRIVATEDATA:
|
||||
if (current->uid != server->m.mounted_uid) {
|
||||
if (uid != server->m.mounted_uid)
|
||||
return -EACCES;
|
||||
}
|
||||
{
|
||||
struct ncp_privatedata_ioctl user;
|
||||
void* new;
|
||||
@ -794,9 +790,10 @@ outrel:
|
||||
#endif /* CONFIG_NCPFS_NLS */
|
||||
|
||||
case NCP_IOC_SETDENTRYTTL:
|
||||
if ((file_permission(filp, MAY_WRITE) != 0) &&
|
||||
(current->uid != server->m.mounted_uid))
|
||||
if (file_permission(filp, MAY_WRITE) != 0 &&
|
||||
uid != server->m.mounted_uid)
|
||||
return -EACCES;
|
||||
|
||||
{
|
||||
u_int32_t user;
|
||||
|
||||
|
@ -10,6 +10,8 @@
|
||||
#include <linux/sunrpc/svc.h>
|
||||
#include <linux/nfsd/nfsd.h>
|
||||
#include <linux/nfsd/syscall.h>
|
||||
#include <linux/cred.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/linkage.h>
|
||||
#include <linux/namei.h>
|
||||
#include <linux/mount.h>
|
||||
@ -41,7 +43,8 @@ static struct file *do_open(char *name, int flags)
|
||||
error = may_open(&nd, MAY_WRITE, FMODE_WRITE);
|
||||
|
||||
if (!error)
|
||||
return dentry_open(nd.path.dentry, nd.path.mnt, flags);
|
||||
return dentry_open(nd.path.dentry, nd.path.mnt, flags,
|
||||
current_cred());
|
||||
|
||||
path_put(&nd.path);
|
||||
return ERR_PTR(error);
|
||||
|
@ -27,53 +27,70 @@ int nfsexp_flags(struct svc_rqst *rqstp, struct svc_export *exp)
|
||||
|
||||
int nfsd_setuser(struct svc_rqst *rqstp, struct svc_export *exp)
|
||||
{
|
||||
struct svc_cred cred = rqstp->rq_cred;
|
||||
struct group_info *rqgi;
|
||||
struct group_info *gi;
|
||||
struct cred *new;
|
||||
int i;
|
||||
int flags = nfsexp_flags(rqstp, exp);
|
||||
int ret;
|
||||
|
||||
if (flags & NFSEXP_ALLSQUASH) {
|
||||
cred.cr_uid = exp->ex_anon_uid;
|
||||
cred.cr_gid = exp->ex_anon_gid;
|
||||
cred.cr_group_info = groups_alloc(0);
|
||||
} else if (flags & NFSEXP_ROOTSQUASH) {
|
||||
struct group_info *gi;
|
||||
if (!cred.cr_uid)
|
||||
cred.cr_uid = exp->ex_anon_uid;
|
||||
if (!cred.cr_gid)
|
||||
cred.cr_gid = exp->ex_anon_gid;
|
||||
gi = groups_alloc(cred.cr_group_info->ngroups);
|
||||
if (gi)
|
||||
for (i = 0; i < cred.cr_group_info->ngroups; i++) {
|
||||
if (!GROUP_AT(cred.cr_group_info, i))
|
||||
GROUP_AT(gi, i) = exp->ex_anon_gid;
|
||||
else
|
||||
GROUP_AT(gi, i) = GROUP_AT(cred.cr_group_info, i);
|
||||
}
|
||||
cred.cr_group_info = gi;
|
||||
} else
|
||||
get_group_info(cred.cr_group_info);
|
||||
|
||||
if (cred.cr_uid != (uid_t) -1)
|
||||
current->fsuid = cred.cr_uid;
|
||||
else
|
||||
current->fsuid = exp->ex_anon_uid;
|
||||
if (cred.cr_gid != (gid_t) -1)
|
||||
current->fsgid = cred.cr_gid;
|
||||
else
|
||||
current->fsgid = exp->ex_anon_gid;
|
||||
|
||||
if (!cred.cr_group_info)
|
||||
/* discard any old override before preparing the new set */
|
||||
revert_creds(get_cred(current->real_cred));
|
||||
new = prepare_creds();
|
||||
if (!new)
|
||||
return -ENOMEM;
|
||||
ret = set_current_groups(cred.cr_group_info);
|
||||
put_group_info(cred.cr_group_info);
|
||||
if ((cred.cr_uid)) {
|
||||
current->cap_effective =
|
||||
cap_drop_nfsd_set(current->cap_effective);
|
||||
|
||||
new->fsuid = rqstp->rq_cred.cr_uid;
|
||||
new->fsgid = rqstp->rq_cred.cr_gid;
|
||||
|
||||
rqgi = rqstp->rq_cred.cr_group_info;
|
||||
|
||||
if (flags & NFSEXP_ALLSQUASH) {
|
||||
new->fsuid = exp->ex_anon_uid;
|
||||
new->fsgid = exp->ex_anon_gid;
|
||||
gi = groups_alloc(0);
|
||||
} else if (flags & NFSEXP_ROOTSQUASH) {
|
||||
if (!new->fsuid)
|
||||
new->fsuid = exp->ex_anon_uid;
|
||||
if (!new->fsgid)
|
||||
new->fsgid = exp->ex_anon_gid;
|
||||
|
||||
gi = groups_alloc(rqgi->ngroups);
|
||||
if (!gi)
|
||||
goto oom;
|
||||
|
||||
for (i = 0; i < rqgi->ngroups; i++) {
|
||||
if (!GROUP_AT(rqgi, i))
|
||||
GROUP_AT(gi, i) = exp->ex_anon_gid;
|
||||
else
|
||||
GROUP_AT(gi, i) = GROUP_AT(rqgi, i);
|
||||
}
|
||||
} else {
|
||||
current->cap_effective =
|
||||
cap_raise_nfsd_set(current->cap_effective,
|
||||
current->cap_permitted);
|
||||
gi = get_group_info(rqgi);
|
||||
}
|
||||
|
||||
if (new->fsuid == (uid_t) -1)
|
||||
new->fsuid = exp->ex_anon_uid;
|
||||
if (new->fsgid == (gid_t) -1)
|
||||
new->fsgid = exp->ex_anon_gid;
|
||||
|
||||
ret = set_groups(new, gi);
|
||||
put_group_info(gi);
|
||||
if (!ret)
|
||||
goto error;
|
||||
|
||||
if (new->uid)
|
||||
new->cap_effective = cap_drop_nfsd_set(new->cap_effective);
|
||||
else
|
||||
new->cap_effective = cap_raise_nfsd_set(new->cap_effective,
|
||||
new->cap_permitted);
|
||||
put_cred(override_creds(new));
|
||||
return 0;
|
||||
|
||||
oom:
|
||||
ret = -ENOMEM;
|
||||
error:
|
||||
abort_creds(new);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -54,20 +54,26 @@
|
||||
static struct path rec_dir;
|
||||
static int rec_dir_init = 0;
|
||||
|
||||
static void
|
||||
nfs4_save_user(uid_t *saveuid, gid_t *savegid)
|
||||
static int
|
||||
nfs4_save_creds(const struct cred **original_creds)
|
||||
{
|
||||
*saveuid = current->fsuid;
|
||||
*savegid = current->fsgid;
|
||||
current->fsuid = 0;
|
||||
current->fsgid = 0;
|
||||
struct cred *new;
|
||||
|
||||
new = prepare_creds();
|
||||
if (!new)
|
||||
return -ENOMEM;
|
||||
|
||||
new->fsuid = 0;
|
||||
new->fsgid = 0;
|
||||
*original_creds = override_creds(new);
|
||||
put_cred(new);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
nfs4_reset_user(uid_t saveuid, gid_t savegid)
|
||||
nfs4_reset_creds(const struct cred *original)
|
||||
{
|
||||
current->fsuid = saveuid;
|
||||
current->fsgid = savegid;
|
||||
revert_creds(original);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -129,10 +135,9 @@ nfsd4_sync_rec_dir(void)
|
||||
int
|
||||
nfsd4_create_clid_dir(struct nfs4_client *clp)
|
||||
{
|
||||
const struct cred *original_cred;
|
||||
char *dname = clp->cl_recdir;
|
||||
struct dentry *dentry;
|
||||
uid_t uid;
|
||||
gid_t gid;
|
||||
int status;
|
||||
|
||||
dprintk("NFSD: nfsd4_create_clid_dir for \"%s\"\n", dname);
|
||||
@ -140,7 +145,9 @@ nfsd4_create_clid_dir(struct nfs4_client *clp)
|
||||
if (!rec_dir_init || clp->cl_firststate)
|
||||
return 0;
|
||||
|
||||
nfs4_save_user(&uid, &gid);
|
||||
status = nfs4_save_creds(&original_cred);
|
||||
if (status < 0)
|
||||
return status;
|
||||
|
||||
/* lock the parent */
|
||||
mutex_lock(&rec_dir.dentry->d_inode->i_mutex);
|
||||
@ -168,7 +175,7 @@ out_unlock:
|
||||
clp->cl_firststate = 1;
|
||||
nfsd4_sync_rec_dir();
|
||||
}
|
||||
nfs4_reset_user(uid, gid);
|
||||
nfs4_reset_creds(original_cred);
|
||||
dprintk("NFSD: nfsd4_create_clid_dir returns %d\n", status);
|
||||
return status;
|
||||
}
|
||||
@ -211,26 +218,29 @@ nfsd4_build_dentrylist(void *arg, const char *name, int namlen,
|
||||
static int
|
||||
nfsd4_list_rec_dir(struct dentry *dir, recdir_func *f)
|
||||
{
|
||||
const struct cred *original_cred;
|
||||
struct file *filp;
|
||||
struct dentry_list_arg dla = {
|
||||
.parent = dir,
|
||||
};
|
||||
struct list_head *dentries = &dla.dentries;
|
||||
struct dentry_list *child;
|
||||
uid_t uid;
|
||||
gid_t gid;
|
||||
int status;
|
||||
|
||||
if (!rec_dir_init)
|
||||
return 0;
|
||||
|
||||
nfs4_save_user(&uid, &gid);
|
||||
status = nfs4_save_creds(&original_cred);
|
||||
if (status < 0)
|
||||
return status;
|
||||
INIT_LIST_HEAD(dentries);
|
||||
|
||||
filp = dentry_open(dget(dir), mntget(rec_dir.mnt), O_RDONLY);
|
||||
filp = dentry_open(dget(dir), mntget(rec_dir.mnt), O_RDONLY,
|
||||
current_cred());
|
||||
status = PTR_ERR(filp);
|
||||
if (IS_ERR(filp))
|
||||
goto out;
|
||||
INIT_LIST_HEAD(dentries);
|
||||
status = vfs_readdir(filp, nfsd4_build_dentrylist, &dla);
|
||||
fput(filp);
|
||||
while (!list_empty(dentries)) {
|
||||
@ -249,7 +259,7 @@ out:
|
||||
dput(child->dentry);
|
||||
kfree(child);
|
||||
}
|
||||
nfs4_reset_user(uid, gid);
|
||||
nfs4_reset_creds(original_cred);
|
||||
return status;
|
||||
}
|
||||
|
||||
@ -311,8 +321,7 @@ out:
|
||||
void
|
||||
nfsd4_remove_clid_dir(struct nfs4_client *clp)
|
||||
{
|
||||
uid_t uid;
|
||||
gid_t gid;
|
||||
const struct cred *original_cred;
|
||||
int status;
|
||||
|
||||
if (!rec_dir_init || !clp->cl_firststate)
|
||||
@ -322,9 +331,13 @@ nfsd4_remove_clid_dir(struct nfs4_client *clp)
|
||||
if (status)
|
||||
goto out;
|
||||
clp->cl_firststate = 0;
|
||||
nfs4_save_user(&uid, &gid);
|
||||
|
||||
status = nfs4_save_creds(&original_cred);
|
||||
if (status < 0)
|
||||
goto out;
|
||||
|
||||
status = nfsd4_unlink_clid_dir(clp->cl_recdir, HEXDIR_LEN-1);
|
||||
nfs4_reset_user(uid, gid);
|
||||
nfs4_reset_creds(original_cred);
|
||||
if (status == 0)
|
||||
nfsd4_sync_rec_dir();
|
||||
mnt_drop_write(rec_dir.mnt);
|
||||
@ -401,16 +414,21 @@ nfsd4_recdir_load(void) {
|
||||
void
|
||||
nfsd4_init_recdir(char *rec_dirname)
|
||||
{
|
||||
uid_t uid = 0;
|
||||
gid_t gid = 0;
|
||||
int status;
|
||||
const struct cred *original_cred;
|
||||
int status;
|
||||
|
||||
printk("NFSD: Using %s as the NFSv4 state recovery directory\n",
|
||||
rec_dirname);
|
||||
|
||||
BUG_ON(rec_dir_init);
|
||||
|
||||
nfs4_save_user(&uid, &gid);
|
||||
status = nfs4_save_creds(&original_cred);
|
||||
if (status < 0) {
|
||||
printk("NFSD: Unable to change credentials to find recovery"
|
||||
" directory: error %d\n",
|
||||
status);
|
||||
return;
|
||||
}
|
||||
|
||||
status = kern_path(rec_dirname, LOOKUP_FOLLOW | LOOKUP_DIRECTORY,
|
||||
&rec_dir);
|
||||
@ -420,7 +438,7 @@ nfsd4_init_recdir(char *rec_dirname)
|
||||
|
||||
if (!status)
|
||||
rec_dir_init = 1;
|
||||
nfs4_reset_user(uid, gid);
|
||||
nfs4_reset_creds(original_cred);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -186,9 +186,14 @@ static __be32 nfsd_set_fh_dentry(struct svc_rqst *rqstp, struct svc_fh *fhp)
|
||||
* access control settings being in effect, we cannot
|
||||
* fix that case easily.
|
||||
*/
|
||||
current->cap_effective =
|
||||
cap_raise_nfsd_set(current->cap_effective,
|
||||
current->cap_permitted);
|
||||
struct cred *new = prepare_creds();
|
||||
if (!new)
|
||||
return nfserrno(-ENOMEM);
|
||||
new->cap_effective =
|
||||
cap_raise_nfsd_set(new->cap_effective,
|
||||
new->cap_permitted);
|
||||
put_cred(override_creds(new));
|
||||
put_cred(new);
|
||||
} else {
|
||||
error = nfsd_setuser_and_check_port(rqstp, exp);
|
||||
if (error)
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user