Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 157338
b: refs/heads/master
c: e0e8173
h: refs/heads/master
v: v3
  • Loading branch information
David Howells authored and James Morris committed Sep 2, 2009
1 parent 3b7bfe5 commit ce44318
Show file tree
Hide file tree
Showing 12 changed files with 347 additions and 13 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: ed6d76e4c32de0c2ad5f1d572b948ef49e465176
refs/heads/master: e0e817392b9acf2c98d3be80c233dddb1b52003d
4 changes: 4 additions & 0 deletions trunk/fs/nfsd/auth.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ int nfsd_setuser(struct svc_rqst *rqstp, struct svc_export *exp)
int flags = nfsexp_flags(rqstp, exp);
int ret;

validate_process_creds();

/* discard any old override before preparing the new set */
revert_creds(get_cred(current->real_cred));
new = prepare_creds();
Expand Down Expand Up @@ -86,8 +88,10 @@ int nfsd_setuser(struct svc_rqst *rqstp, struct svc_export *exp)
else
new->cap_effective = cap_raise_nfsd_set(new->cap_effective,
new->cap_permitted);
validate_process_creds();
put_cred(override_creds(new));
put_cred(new);
validate_process_creds();
return 0;

oom:
Expand Down
2 changes: 2 additions & 0 deletions trunk/fs/nfsd/nfssvc.c
Original file line number Diff line number Diff line change
Expand Up @@ -496,7 +496,9 @@ nfsd(void *vrqstp)
/* Lock the export hash tables for reading. */
exp_readlock();

validate_process_creds();
svc_process(rqstp);
validate_process_creds();

/* Unlock export hash tables */
exp_readunlock();
Expand Down
3 changes: 3 additions & 0 deletions trunk/fs/nfsd/vfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -684,6 +684,8 @@ nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, int type,
__be32 err;
int host_err;

validate_process_creds();

/*
* If we get here, then the client has already done an "open",
* and (hopefully) checked permission - so allow OWNER_OVERRIDE
Expand Down Expand Up @@ -740,6 +742,7 @@ nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, int type,
out_nfserr:
err = nfserrno(host_err);
out:
validate_process_creds();
return err;
}

Expand Down
2 changes: 2 additions & 0 deletions trunk/fs/open.c
Original file line number Diff line number Diff line change
Expand Up @@ -959,6 +959,8 @@ struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags,
int error;
struct file *f;

validate_creds(cred);

/*
* We must always pass in a valid mount pointer. Historically
* callers got away with not passing it, but we must enforce this at
Expand Down
65 changes: 64 additions & 1 deletion trunk/include/linux/cred.h
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,13 @@ struct thread_group_cred {
*/
struct cred {
atomic_t usage;
#ifdef CONFIG_DEBUG_CREDENTIALS
atomic_t subscribers; /* number of processes subscribed */
void *put_addr;
unsigned magic;
#define CRED_MAGIC 0x43736564
#define CRED_MAGIC_DEAD 0x44656144
#endif
uid_t uid; /* real UID of the task */
gid_t gid; /* real GID of the task */
uid_t suid; /* saved UID of the task */
Expand Down Expand Up @@ -143,6 +150,7 @@ struct cred {
};

extern void __put_cred(struct cred *);
extern void exit_creds(struct task_struct *);
extern int copy_creds(struct task_struct *, unsigned long);
extern struct cred *prepare_creds(void);
extern struct cred *prepare_exec_creds(void);
Expand All @@ -158,6 +166,60 @@ extern int set_security_override_from_ctx(struct cred *, const char *);
extern int set_create_files_as(struct cred *, struct inode *);
extern void __init cred_init(void);

/*
* check for validity of credentials
*/
#ifdef CONFIG_DEBUG_CREDENTIALS
extern void __invalid_creds(const struct cred *, const char *, unsigned);
extern void __validate_process_creds(struct task_struct *,
const char *, unsigned);

static inline bool creds_are_invalid(const struct cred *cred)
{
if (cred->magic != CRED_MAGIC)
return true;
if (atomic_read(&cred->usage) < atomic_read(&cred->subscribers))
return true;
#ifdef CONFIG_SECURITY_SELINUX
if ((unsigned long) cred->security < PAGE_SIZE)
return true;
if ((*(u32*)cred->security & 0xffffff00) ==
(POISON_FREE << 24 | POISON_FREE << 16 | POISON_FREE << 8))
return true;
#endif
return false;
}

static inline void __validate_creds(const struct cred *cred,
const char *file, unsigned line)
{
if (unlikely(creds_are_invalid(cred)))
__invalid_creds(cred, file, line);
}

#define validate_creds(cred) \
do { \
__validate_creds((cred), __FILE__, __LINE__); \
} while(0)

#define validate_process_creds() \
do { \
__validate_process_creds(current, __FILE__, __LINE__); \
} while(0)

extern void validate_creds_for_do_exit(struct task_struct *);
#else
static inline void validate_creds(const struct cred *cred)
{
}
static inline void validate_creds_for_do_exit(struct task_struct *tsk)
{
}
static inline void validate_process_creds(void)
{
}
#endif

/**
* get_new_cred - Get a reference on a new set of credentials
* @cred: The new credentials to reference
Expand Down Expand Up @@ -187,6 +249,7 @@ static inline struct cred *get_new_cred(struct cred *cred)
static inline const struct cred *get_cred(const struct cred *cred)
{
struct cred *nonconst_cred = (struct cred *) cred;
validate_creds(cred);
return get_new_cred(nonconst_cred);
}

Expand All @@ -205,7 +268,7 @@ static inline void put_cred(const struct cred *_cred)
{
struct cred *cred = (struct cred *) _cred;

BUG_ON(atomic_read(&(cred)->usage) <= 0);
validate_creds(cred);
if (atomic_dec_and_test(&(cred)->usage))
__put_cred(cred);
}
Expand Down
Loading

0 comments on commit ce44318

Please sign in to comment.