2005-03-13 23:32:38

by René Scharfe

[permalink] [raw]
Subject: [PATCH][RFC] Make /proc/<pid> chmod'able

OK, folks, another try to enhance privacy by hiding process details
from other users. Why not simply use chmod to set the permissions of
/proc/<pid> directories? This patch implements it.

Children processes inherit their parents' proc permissions on fork. You
can only set (and remove) read and execute permissions, the bits for
write, suid etc. are not changable. A user would add

chmod 500 /proc/$$

or something similar to his .profile to cloak his processes.

What do you think about that one?

Thanks,
Rene



diff -urp linux-2.6.11-mm3/fs/proc/base.c linux-2.6.11-mm3+/fs/proc/base.c
--- linux-2.6.11-mm3/fs/proc/base.c 2005-03-12 19:23:36.000000000 +0100
+++ linux-2.6.11-mm3+/fs/proc/base.c 2005-03-13 18:36:06.000000000 +0100
@@ -1605,6 +1605,55 @@ out:
return ERR_PTR(error);
}

+static int proc_base_setattr(struct dentry *dentry, struct iattr *attr)
+{
+ struct inode *inode = dentry->d_inode;
+ struct task_struct *task;
+ unsigned id;
+ int error;
+
+ BUG_ON(!inode);
+
+ error = -EPERM;
+ if (attr->ia_valid != (ATTR_MODE | ATTR_CTIME))
+ goto out;
+ if (attr->ia_mode & S_IALLUGO & ~(S_IRUGO | S_IXUGO))
+ goto out;
+
+ error = inode_change_ok(inode, attr);
+ if (error)
+ goto out;
+
+ error = -ENOENT;
+ id = name_to_int(dentry);
+ if (id == ~0U)
+ goto out;
+
+ read_lock(&tasklist_lock);
+ task = find_task_by_pid(id);
+ if (task)
+ get_task_struct(task);
+ read_unlock(&tasklist_lock);
+ if (!task)
+ goto out;
+
+ error = inode_setattr(inode, attr);
+ if (error)
+ goto out_drop_task;
+ /*
+ * Save permissions in task_struct as the reverse of the mode.
+ * This way a value of zero, which is the default value of a
+ * task_struct member, means "normal permissions". Children
+ * inherit the proc_dir_mask value of their parent process.
+ */
+ task->proc_dir_mask = S_IRWXUGO - (attr->ia_mode & S_IRWXUGO);
+
+out_drop_task:
+ put_task_struct(task);
+out:
+ return error;
+}
+
static struct dentry *proc_tgid_base_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd){
return proc_pident_lookup(dir, dentry, tgid_base_stuff);
}
@@ -1625,10 +1674,12 @@ static struct file_operations proc_tid_b

static struct inode_operations proc_tgid_base_inode_operations = {
.lookup = proc_tgid_base_lookup,
+ .setattr = proc_base_setattr,
};

static struct inode_operations proc_tid_base_inode_operations = {
.lookup = proc_tid_base_lookup,
+ .setattr = proc_base_setattr,
};

#ifdef CONFIG_SECURITY
@@ -1797,11 +1848,10 @@ struct dentry *proc_pid_lookup(struct in
put_task_struct(task);
goto out;
}
- inode->i_mode = S_IFDIR|S_IRUGO|S_IXUGO;
+ inode->i_mode = (S_IFDIR|S_IRUGO|S_IXUGO) & ~task->proc_dir_mask;
inode->i_op = &proc_tgid_base_inode_operations;
inode->i_fop = &proc_tgid_base_operations;
inode->i_nlink = 3;
- inode->i_flags|=S_IMMUTABLE;

dentry->d_op = &pid_base_dentry_operations;

@@ -1852,11 +1902,10 @@ static struct dentry *proc_task_lookup(s

if (!inode)
goto out_drop_task;
- inode->i_mode = S_IFDIR|S_IRUGO|S_IXUGO;
+ inode->i_mode = (S_IFDIR|S_IRUGO|S_IXUGO) & ~task->proc_dir_mask;
inode->i_op = &proc_tid_base_inode_operations;
inode->i_fop = &proc_tid_base_operations;
inode->i_nlink = 3;
- inode->i_flags|=S_IMMUTABLE;

dentry->d_op = &pid_base_dentry_operations;

diff -urp linux-2.6.11-mm3/include/linux/sched.h linux-2.6.11-mm3+/include/linux/sched.h
--- linux-2.6.11-mm3/include/linux/sched.h 2005-03-12 19:23:37.000000000 +0100
+++ linux-2.6.11-mm3+/include/linux/sched.h 2005-03-13 11:54:13.000000000 +0100
@@ -719,6 +719,10 @@ struct task_struct {
struct audit_context *audit_context;
seccomp_t seccomp;

+#ifdef CONFIG_PROC_FS
+ umode_t proc_dir_mask;
+#endif
+
/* Thread group tracking */
u32 parent_exec_id;
u32 self_exec_id;


2005-03-14 03:48:14

by Albert Cahalan

[permalink] [raw]
Subject: Re: [PATCH][RFC] Make /proc/<pid> chmod'able

> OK, folks, another try to enhance privacy by hiding
> process details from other users. Why not simply use
> chmod to set the permissions of /proc/<pid> directories?
> This patch implements it.
>
> Children processes inherit their parents' proc
> permissions on fork. You can only set (and remove)
> read and execute permissions, the bits for write,
> suid etc. are not changable. A user would add
>
> chmod 500 /proc/$$
>
> or something similar to his .profile to cloak his processes.
>
> What do you think about that one?

This is a bad idea. Users should not be allowed to
make this decision. This is rightly a decision for
the admin to make.

Note: I'm the procps (ps, top, w, etc.) maintainer.

Probably I'd have to make /bin/ps run setuid root
to deal with this. (minor changes needed) The same
goes for /usr/bin/top, which I know is currently
unsafe and difficult to fix.

Let's not go there, OK?

If you restricted this new ability to root, then I'd
have much less of an objection. (not that I'd like it)



2005-03-14 09:46:38

by René Scharfe

[permalink] [raw]
Subject: Re: [PATCH][RFC] Make /proc/<pid> chmod'able

Albert Cahalan wrote:
> This is a bad idea. Users should not be allowed to
> make this decision. This is rightly a decision for
> the admin to make.

Why do you think users should not be allowed to chmod their processes'
/proc directories? Isn't it similar to being able to chmod their home
directories? They own both objects, after all (both conceptually and as
attributed in the filesystem).

> Note: I'm the procps (ps, top, w, etc.) maintainer.
>
> Probably I'd have to make /bin/ps run setuid root
> to deal with this. (minor changes needed) The same
> goes for /usr/bin/top, which I know is currently
> unsafe and difficult to fix.
>
> Let's not go there, OK?

I have to admit to not having done any real testing with those
utilities. My excuse is this isn't such a new feature, Openwall had
something similar for at least four years now and GrSecurity contains
yet another flavour of it. Openwall also provides one patch for
procps-2.0.6, so I figured that problem (whatever their patch is about)
got fixed in later versions.

Why do ps and top need to be setuid root to deal with a resticted /proc?
What information in /proc/<pid> needs to be available to any and all
users?

> If you restricted this new ability to root, then I'd
> have much less of an objection. (not that I'd like it)

How about a boot parameter or sysctl to enable the chmod'ability of
/proc/<pid>, defaulting to off? But I'd like to resolve your more
general objections above first, if possible. :)

Thanks for your comments,
Rene

2005-03-14 16:28:36

by Albert Cahalan

[permalink] [raw]
Subject: Re: [PATCH][RFC] Make /proc/<pid> chmod'able

On Mon, 2005-03-14 at 10:42 +0100, Rene Scharfe wrote:
> Albert Cahalan wrote:
> > This is a bad idea. Users should not be allowed to
> > make this decision. This is rightly a decision for
> > the admin to make.
>
> Why do you think users should not be allowed to chmod their processes'
> /proc directories? Isn't it similar to being able to chmod their home
> directories? They own both objects, after all (both conceptually and as
> attributed in the filesystem).

This is, to use your own word, "cloaking". This would let
a bad user or even an unauthorized user hide from the admin.
Why should someone be able to hide a suspicious CPU hog?
Maybe they are cracking passwords or selling your CPU time.

Note that the admin hopefully does not normally run as root.
The admin should be using a normal user account most of the
time, to reduce the damage caused by his accidents.

Even if the admin were not running as a normal user, it is
expected that normal users can keep tabs on each other.
The admin may be sleeping. Social pressure is important to
prevent one user from sucking up all the memory and CPU time.

> > Note: I'm the procps (ps, top, w, etc.) maintainer.
> >
> > Probably I'd have to make /bin/ps run setuid root
> > to deal with this. (minor changes needed) The same
> > goes for /usr/bin/top, which I know is currently
> > unsafe and difficult to fix.
> >
> > Let's not go there, OK?
>
> I have to admit to not having done any real testing with those
> utilities. My excuse is this isn't such a new feature, Openwall had
> something similar for at least four years now and GrSecurity contains
> yet another flavour of it. Openwall also provides one patch for
> procps-2.0.6, so I figured that problem (whatever their patch is about)
> got fixed in later versions.

If I haven't seen that patch, to Hell with 'em.

It appears that Openwall is using procps-2.0.7 now. Oooh, they've
upgraded to something that's only 4.5 years old! Anybody using a
4-year-old procps is uninterested in security.

> Why do ps and top need to be setuid root to deal with a resticted /proc?
> What information in /proc/<pid> needs to be available to any and all
> users?

Anything provided by traditional UNIX and BSD systems
should be available. Users who want privacy can get their
own computer. So, these need to work:

ps -ef
ps -el
ps -ej
ps axu
ps axl
ps axj
ps axv
w
top

Note that /proc does provide a bit more info than required.
This could be changed; it requires new /proc files or a
non-proc source of data.

> > If you restricted this new ability to root, then I'd
> > have much less of an objection. (not that I'd like it)
>
> How about a boot parameter or sysctl to enable the chmod'ability of
> /proc/<pid>, defaulting to off? But I'd like to resolve your more
> general objections above first, if possible. :)

This at least avoids breaking the traditional ability of
non-root users to spot abuse.


2005-03-14 16:38:11

by Pavel Machek

[permalink] [raw]
Subject: Re: [PATCH][RFC] Make /proc/<pid> chmod'able

Hi!

> >This is a bad idea. Users should not be allowed to
> >make this decision. This is rightly a decision for
> >the admin to make.
>
> Why do you think users should not be allowed to chmod their processes'
> /proc directories? Isn't it similar to being able to chmod their home
> directories? They own both objects, after all (both conceptually and as
> attributed in the filesystem).

As a co-admin of university server...

Yes, I want users to see what each other user is doing. That way, if
someone hacks one account, some other user can notice and tell me.

In some environments it may make sense not to allow users to chmod
their $HOMEs (so that they can't hide mp3's etc), but we are not
*that* stupid/paranoid ;-).
Pavel
--
People were complaining that M$ turns users into beta-testers...
...jr ghea gurz vagb qrirybcref, naq gurl frrz gb yvxr vg gung jnl!

2005-03-14 23:07:34

by Bodo Eggert

[permalink] [raw]
Subject: Re: [PATCH][RFC] Make /proc/<pid> chmod'able

On Mon, 14 Mar 2005, Albert Cahalan wrote:
> On Mon, 2005-03-14 at 10:42 +0100, Rene Scharfe wrote:
> > Albert Cahalan wrote:

> > Why do you think users should not be allowed to chmod their processes'
> > /proc directories? Isn't it similar to being able to chmod their home
> > directories? They own both objects, after all (both conceptually and as
> > attributed in the filesystem).
>
> This is, to use your own word, "cloaking". This would let
> a bad user or even an unauthorized user hide from the admin.

NACK, the admin (and with the new inherited capabilities all users with
cap_???_override) can see all processes. Only users who don't need to know
won't see the other user's processes.

> Note that the admin hopefully does not normally run as root.

su1 and sudo exist.

> Even if the admin were not running as a normal user, it is
> expected that normal users can keep tabs on each other.
> The admin may be sleeping. Social pressure is important to
> prevent one user from sucking up all the memory and CPU time.

Privacy is important, too. Imagine each user can see the CEO (or the
admin) executing "ee nakedgirl.jpg".

> > > Note: I'm the procps (ps, top, w, etc.) maintainer.
> > >
> > > Probably I'd have to make /bin/ps run setuid root
> > > to deal with this. (minor changes needed) The same
> > > goes for /usr/bin/top, which I know is currently
> > > unsafe and difficult to fix.

I used unpatched procps 3.1.11, and it worked for me, except pstree.

> > Why do ps and top need to be setuid root to deal with a resticted /proc?
> > What information in /proc/<pid> needs to be available to any and all
> > users?
>
> Anything provided by traditional UNIX and BSD systems
> should be available.

e.g. the buffer overflow in sendmail? Or all the open relays? :)

The demands to security and privacy have increased. Linux should be able
to provide the requested privacy.

> Users who want privacy can get their
> own computer. So, these need to work:
>
> ps -ef
> ps -el
> ps -ej
> ps axu
> ps axl
> ps axj
> ps axv
> w
> top

Works as intended. Only pstree breaks, if init isn't visible.

> > > If you restricted this new ability to root, then I'd
> > > have much less of an objection. (not that I'd like it)
> >
> > How about a boot parameter or sysctl to enable the chmod'ability of
> > /proc/<pid>, defaulting to off? But I'd like to resolve your more
> > general objections above first, if possible. :)

I'd prefer a minimum and a maximum mask. If the admin wants to enforce
privacy, he can do it, and if he wants the users to spy on each other, so
be it.
--
Top 100 things you don't want the sysadmin to say:
23. What do mean by "fired"?

Fri?, Spammer: kRT8@[211.158.7.114] [email protected]

2005-03-15 02:58:42

by Albert Cahalan

[permalink] [raw]
Subject: Re: [PATCH][RFC] Make /proc/<pid> chmod'able

On Tue, 2005-03-15 at 00:08 +0100, Bodo Eggert wrote:
> On Mon, 14 Mar 2005, Albert Cahalan wrote:
> > On Mon, 2005-03-14 at 10:42 +0100, Rene Scharfe wrote:
> > > Albert Cahalan wrote:
>
> > > Why do you think users should not be allowed to chmod their processes'
> > > /proc directories? Isn't it similar to being able to chmod their home
> > > directories? They own both objects, after all (both conceptually and as
> > > attributed in the filesystem).
> >
> > This is, to use your own word, "cloaking". This would let
> > a bad user or even an unauthorized user hide from the admin.
>
> NACK, the admin (and with the new inherited capabilities all users with
> cap_???_override) can see all processes. Only users who don't need to know
> won't see the other user's processes.

Capabilities are too broken for most people to use. Normal users
do not get CAP_DAC_OVERRIDE by default anyway, for good reason.

> > Note that the admin hopefully does not normally run as root.
>
> su1 and sudo exist.

This is a pain. Now every user will need sudo access,
and the sudoers file will have to disable requesting
passwords so that scripts will work without hassle.

> > Even if the admin were not running as a normal user, it is
> > expected that normal users can keep tabs on each other.
> > The admin may be sleeping. Social pressure is important to
> > prevent one user from sucking up all the memory and CPU time.
>
> Privacy is important, too. Imagine each user can see the CEO (or the
> admin) executing "ee nakedgirl.jpg".

Obviously, he likes to have users see him do this.
He'd use a private machine if he wanted privacy.

> > > > Note: I'm the procps (ps, top, w, etc.) maintainer.
> > > >
> > > > Probably I'd have to make /bin/ps run setuid root
> > > > to deal with this. (minor changes needed) The same
> > > > goes for /usr/bin/top, which I know is currently
> > > > unsafe and difficult to fix.
>
> I used unpatched procps 3.1.11, and it worked for me, except pstree.

It does not work correctly.

Look, patches with this "feature" are called rootkits.
Think of the headlines: "Linux now with built-in rootkit".

> > > Why do ps and top need to be setuid root to deal with a resticted /proc?
> > > What information in /proc/<pid> needs to be available to any and all
> > > users?
> >
> > Anything provided by traditional UNIX and BSD systems
> > should be available.
>
> e.g. the buffer overflow in sendmail? Or all the open relays? :)
>
> The demands to security and privacy have increased. Linux should be able
> to provide the requested privacy.

This really isn't about security. Privacy may be undesirable.
With privacy comes anti-social behavior. Supposing that the
users do get privacy, perhaps because the have paid for it:

Xen, UML, VM, VMware, separate computers

Going with separate computers is best. Don't forget to use
network traffic control to keep users from being able to
detect the network activity of other users.

> > Users who want privacy can get their
> > own computer. So, these need to work:
> >
> > ps -ef
> > ps -el
> > ps -ej
> > ps axu
> > ps axl
> > ps axj
> > ps axv
> > w
> > top
>
> Works as intended. Only pstree breaks, if init isn't visible.

They work like they do with a rootkit installed.
Traditional behavior has been broken.


2005-03-15 10:51:47

by Jonathan Sambrook

[permalink] [raw]
Subject: Re: [PATCH][RFC] Make /proc/<pid> chmod'able

> Xen, UML, VM, VMware, separate computers

http://linux-vserver.org/ would also seem to be an excellent match.

2005-03-15 14:27:49

by Bodo Eggert

[permalink] [raw]
Subject: Re: [PATCH][RFC] Make /proc/<pid> chmod'able

(snipped the CC list - hope that's ok)

On Mon, 14 Mar 2005, Albert Cahalan wrote:
> On Tue, 2005-03-15 at 00:08 +0100, Bodo Eggert wrote:
> > On Mon, 14 Mar 2005, Albert Cahalan wrote:
> > > On Mon, 2005-03-14 at 10:42 +0100, Rene Scharfe wrote:
> > > > Albert Cahalan wrote:

> > NACK, the admin (and with the new inherited capabilities all users with
> > cap_???_override) can see all processes. Only users who don't need to know
> > won't see the other user's processes.
>
> Capabilities are too broken for most people to use.

That's being fixed, the new semantics will allow a wrapper.

> > > Note that the admin hopefully does not normally run as root.
> >
> > su1 and sudo exist.
>
> This is a pain.

mv ps ps.bin # -+ or just ln -s /usr/bin/us1 ~admin/bin/ps instead
ln -s su1 ps # /
echo $'\nask never\nalias ps /bin/ps\nallow admin prefix ps' >> /etc/su1.priv
# ore use * instead of admin, if all users are supposed to see everyone.

Or use the sysctl I described. It won't hurt more than the originally
suggested flag, and it's much more powerfull.

> Now every user will need sudo access,
> and the sudoers file will have to disable requesting
> passwords so that scripts will work without hassle.

Is sudo _that_ bad? Seems it was a good decision to avoid sudo.

> > > Even if the admin were not running as a normal user, it is
> > > expected that normal users can keep tabs on each other.
> > > The admin may be sleeping. Social pressure is important to
> > > prevent one user from sucking up all the memory and CPU time.
> >
> > Privacy is important, too. Imagine each user can see the CEO (or the
> > admin) executing "ee nakedgirl.jpg".
>
> Obviously, he likes to have users see him do this.
> He'd use a private machine if he wanted privacy.

UNIX and linux are supposed to be a multi-user-systems unlike Win98.
Information leakage is usurally considered {\HUGE BAD}, and some security
models demand closing all information leakages from privileged users to
less privileged users. Restricted proc is one more step towards secure
systems, unless you're depending on "peer review".

> > > > > Note: I'm the procps (ps, top, w, etc.) maintainer.
> > > > >
> > > > > Probably I'd have to make /bin/ps run setuid root
> > > > > to deal with this. (minor changes needed) The same
> > > > > goes for /usr/bin/top, which I know is currently
> > > > > unsafe and difficult to fix.
> >
> > I used unpatched procps 3.1.11, and it worked for me, except pstree.
>
> It does not work correctly.
>
> Look, patches with this "feature" are called rootkits.
> Think of the headlines: "Linux now with built-in rootkit".

Using another PC will hide the processes. Therefore using another PC is
like using a rootkit. NOT.

Maybe you'll want to print a note about inaccessible proc entries, but
that's a different issue.

> > > > Why do ps and top need to be setuid root to deal with a resticted /proc?
> > > > What information in /proc/<pid> needs to be available to any and all
> > > > users?
> > >
> > > Anything provided by traditional UNIX and BSD systems
> > > should be available.
> >
> > e.g. the buffer overflow in sendmail? Or all the open relays? :)
> >
> > The demands to security and privacy have increased. Linux should be able
> > to provide the requested privacy.
>
> This really isn't about security.

Information leakage is a security aspect.

> Privacy may be undesirable.

May. That's why I suggested the min/max sysctl.

> With privacy comes anti-social behavior.

With anti-social behavior comes the admin and his LART.

BTW: If the users want to be anti-social, they'll just rename setiathome
to something like -bash or soffice.

> Supposing that the
> users do get privacy, perhaps because the have paid for it:

Vservers,
> Xen, UML, VM, VMware, separate computers
>
> Going with separate computers is best.

If you like wasting space and energy. If the user's demands don't exceed
one percent of a historic PC, there is no point in buying more hardware.

> Don't forget to use
> network traffic control to keep users from being able to
> detect the network activity of other users.

Like that:?

$ netstat
Active Internet connections (w/o servers)
Proto Recv-Q Send-Q Local Address Foreign Address State
/proc/net/tcp: Permission denied

> > > Users who want privacy can get their
> > > own computer. So, these need to work:
> > >
> > > ps [...]
> > > w
> > > top
> >
> > Works as intended. Only pstree breaks, if init isn't visible.
>
> They work like they do with a rootkit installed.
> Traditional behavior has been broken.

They are as broken as finger or ls are if the home directory is chmodded.
--
Top 100 things you don't want the sysadmin to say:
13. Ooohh, lovely, it runs SVR4

2005-03-15 15:27:41

by René Scharfe

[permalink] [raw]
Subject: Re: [PATCH][RFC] Make /proc/<pid> chmod'able

Albert Cahalan wrote:
> Note that the admin hopefully does not normally run as root.
> The admin should be using a normal user account most of the
> time, to reduce the damage caused by his accidents.

Openwall and GrSecurity solved this by having a special group that can
see everything, just like root. E.g. we could add a proc.gid kernel
boot option for that purpose.

> Even if the admin were not running as a normal user, it is
> expected that normal users can keep tabs on each other.
> The admin may be sleeping. Social pressure is important to
> prevent one user from sucking up all the memory and CPU time.

IANAL, but creating a user profile (who ran what when, used how many
resources etc.) without the user's consent is illegal at least here in
Germany. As an admin I'd like to be able to prevent a user from even
trying to spy on another user.

> Anything provided by traditional UNIX and BSD systems
> should be available. Users who want privacy can get their
> own computer. So, these need to work:
>
> ps -ef
> ps -el
> ps -ej
> ps axu
> ps axl
> ps axj
> ps axv
> w
> top

If with "work" you mean "show info about all users" then the patch
becomes pointless. The programs "work" in the sense that they do *not*
should "cloaked" processes, which is intended. :)

OK, I understand that you need to be able to turn this feature off and I
also don't want non-root admins to suddenly go blind. Would adding a
proc.gid kernel parameter and an off-switch be sufficient for you?

Thanks,
Rene

2005-03-15 15:31:16

by Paul Jackson

[permalink] [raw]
Subject: Re: [PATCH][RFC] Make /proc/<pid> chmod'able

> (snipped the CC list - hope that's ok)

No - it's not ok.

--
I won't rest till it's the best ...
Programmer, Linux Scalability
Paul Jackson <[email protected]> 1.650.933.1373, 1.925.600.0401

2005-03-15 16:12:31

by Albert Cahalan

[permalink] [raw]
Subject: Re: [PATCH][RFC] Make /proc/<pid> chmod'able

On Tue, 2005-03-15 at 15:31 +0100, Bodo Eggert wrote:
> (snipped the CC list - hope that's ok)
>
> On Mon, 14 Mar 2005, Albert Cahalan wrote:
> > On Tue, 2005-03-15 at 00:08 +0100, Bodo Eggert wrote:
> > > On Mon, 14 Mar 2005, Albert Cahalan wrote:

> > This really isn't about security.
>
> Information leakage is a security aspect.

If you will go to such extremes, Linux is poorly suited.
A user can detect activity on the computer by examining
the performance of their own activity.

> > Privacy may be undesirable.
>
> May. That's why I suggested the min/max sysctl.
>
> > With privacy comes anti-social behavior.
>
> With anti-social behavior comes the admin and his LART.
>
> BTW: If the users want to be anti-social, they'll just rename setiathome
> to something like -bash or soffice.

This does not matter: "Rene, your soffice program is eating
too much CPU time. Find some other place to run it."

> > Supposing that the
> > users do get privacy, perhaps because the have paid for it:
>
> Vservers,
> > Xen, UML, VM, VMware, separate computers
> >
> > Going with separate computers is best.
>
> If you like wasting space and energy. If the user's demands don't exceed
> one percent of a historic PC, there is no point in buying more hardware.

Sure there is:

a. info leakage (way more than just /proc)
b. admin control
c. budget control
d. downtime hits fewer users

> > Don't forget to use
> > network traffic control to keep users from being able to
> > detect the network activity of other users.
>
> Like that:?
>
> $ netstat
> Active Internet connections (w/o servers)
> Proto Recv-Q Send-Q Local Address Foreign Address State
> /proc/net/tcp: Permission denied

Nope. If you really care about information leakage, you'll
be concerned about the ability to detect network congestion.

Example #1

A spy sends packets from time to time. He measures the delay
and packet loss to determine if the network is busy. When the
network suddenly becomes busy, he can guess that you have
started some operation that requires heavy network traffic.

Example #2

A spy sends packets from time to time. He measures the delay
and packet loss to determine if the network is busy. Over time,
he learns when workers are busy. From this he can determine an
appropriate time to sneak into your building.

Hey, if you're going to be paranoid about %CPU and %MEM, you
have to be paranoid about %NET too. This requires traffic
control unless you have separate networks. Assign a fixed
portion of bandwidth to any user that you wish to hide info
from. Be sure to consider latency as well.

> > > > Users who want privacy can get their
> > > > own computer. So, these need to work:
> > > >
> > > > ps [...]
> > > > w
> > > > top
> > >
> > > Works as intended. Only pstree breaks, if init isn't visible.
> >
> > They work like they do with a rootkit installed.
> > Traditional behavior has been broken.
>
> They are as broken as finger or ls are if the home directory is chmodded.

Probably something should be done to deal with the problem of
a chmodded home directory. It's not ls that matters though.
It's du that matters. On a normal shared system, a user should
be able to see where all the disk blocks and inodes are going.
Filenames need not be visible. Then: "Rene, you're being kind
of greedy about the disk space aren't you? You're using 666 GB."


2005-03-15 21:03:47

by Bodo Eggert

[permalink] [raw]
Subject: Re: [PATCH][RFC] Make /proc/<pid> chmod'able

(refiled the CC list)

On Tue, 15 Mar 2005, Albert Cahalan wrote:
> On Tue, 2005-03-15 at 15:31 +0100, Bodo Eggert wrote:
> > On Mon, 14 Mar 2005, Albert Cahalan wrote:
> > > On Tue, 2005-03-15 at 00:08 +0100, Bodo Eggert wrote:
> > > > On Mon, 14 Mar 2005, Albert Cahalan wrote:

> > > This really isn't about security.
> >
> > Information leakage is a security aspect.
>
> If you will go to such extremes, Linux is poorly suited.
> A user can detect activity on the computer by examining
> the performance of their own activity.

Way to go, better start walking.

> > > Privacy may be undesirable.
> >
> > May. That's why I suggested the min/max sysctl.
> >
> > > With privacy comes anti-social behavior.
> >
> > With anti-social behavior comes the admin and his LART.
> >
> > BTW: If the users want to be anti-social, they'll just rename setiathome
> > to something like -bash or soffice.
>
> This does not matter: "Rene, your soffice program is eating
> too much CPU time. Find some other place to run it."

That's ok for _some_ environments.

> > > Supposing that the
> > > users do get privacy, perhaps because the have paid for it:
> >
> > Vservers,
> > > Xen, UML, VM, VMware, separate computers
> > >
> > > Going with separate computers is best.
> >
> > If you like wasting space and energy. If the user's demands don't exceed
> > one percent of a historic PC, there is no point in buying more hardware.
>
> Sure there is:
>
> a. info leakage (way more than just /proc)

selinux, rsbac,.

> b. admin control
> c. budget control
> d. downtime hits fewer users

no central administration, higher expenses.

The battle has ben fought since the early days, and there is still no
winner.

> > > Don't forget to use
> > > network traffic control to keep users from being able to
> > > detect the network activity of other users.
> >
> > Like that:?
> >
> > $ netstat
> > Active Internet connections (w/o servers)
> > Proto Recv-Q Send-Q Local Address Foreign Address State
> > /proc/net/tcp: Permission denied
>
> Nope. If you really care about information leakage, you'll
> be concerned about the ability to detect network congestion.

Those who should be are able to see the network usage.

On the other hand, the privileged user might open and close ports to
signal information to less privileged users.

[examples]

> Hey, if you're going to be paranoid about %CPU and %MEM, you
> have to be paranoid about %NET too. This requires traffic
> control unless you have separate networks.

Traffic shaping is available.

> > > > > Users who want privacy can get their
> > > > > own computer. So, these need to work:
> > > > >
> > > > > ps [...]
> > > > > w
> > > > > top
> > > >
> > > > Works as intended. Only pstree breaks, if init isn't visible.
> > >
> > > They work like they do with a rootkit installed.
> > > Traditional behavior has been broken.
> >
> > They are as broken as finger or ls are if the home directory is chmodded.
>
> Probably something should be done to deal with the problem of
> a chmodded home directory. It's not ls that matters though.
> It's du that matters. On a normal shared system, a user should
> be able to see where all the disk blocks and inodes are going.
> Filenames need not be visible. Then: "Rene, you're being kind
> of greedy about the disk space aren't you? You're using 666 GB."

That's what quota is for.
--
If at first you don't succeed call in an air-strike.

Fri?, Spammer: [email protected] [email protected]
[email protected] [email protected] [email protected]

2005-03-15 21:18:23

by René Scharfe

[permalink] [raw]
Subject: Re: [PATCH][RFC] Make /proc/<pid> chmod'able

Albert Cahalan wrote:
> This really isn't about security. Privacy may be undesirable.

I agree, privacy is not security. My patch tries to enhance privacy
without giving up security.

You think losing the social pressure that comes with mutual surveillance
results in loss of security, I don't. Now I think Linux should support
both ways and those writing security policies should make the decision.

> With privacy comes anti-social behavior. Supposing that the
> users do get privacy, perhaps because the have paid for it:
>
> Xen, UML, VM, VMware, separate computers
>
> Going with separate computers is best. Don't forget to use
> network traffic control to keep users from being able to
> detect the network activity of other users.

That would work, but it requires a *lot* of administrative and computing
overhead. Note that "separate computers" alone is not sufficient
because most places with more than a few machines have some kind of
single signon and run SSH or similar.

[ps, w, top]
> They work like they do with a rootkit installed.
> Traditional behavior has been broken.

That's one way to put it; you could also say those tools now provide
enhanced privacy. ;)

I also think things have changed in the last few years. Since the
advent of special data processing laws privacy is taken more serious.
Privacy certainly was no real concern when UNIX was young. I also guess
it's a cultural thing, its importance being different from country to
country.

It's easily visible in the style of public toilets: in some contries you
have one big room with no walls in between where all men or women
merrily shit together, in other countries (like mine) every person can
lock himself into a private closet. Both ways work, there's nothing too
special about using a toilet, but I'm simply used to the privacy
provided by those thin walls. I assure you, I don't do anything evil in
there. :]

2005-03-16 00:21:51

by Kyle Moffett

[permalink] [raw]
Subject: Re: [PATCH][RFC] Make /proc/<pid> chmod'able

On Mar 15, 2005, at 16:18, Rene Scharfe wrote:
> It's easily visible in the style of public toilets: in some contries
> you have one big room with no walls in between where all men or women
> merrily shit together, in other countries (like mine) every person can
> lock himself into a private closet. Both ways work, there's nothing
> too special about using a toilet, but I'm simply used to the privacy
> provided by those thin walls. I assure you, I don't do anything evil
> in there. :]

Just as long as our labs "bathrooms" don't mysteriously get a
bazillion walls all over the place on kernel upgrade, we're ok.
I don't mind adding new options for advanced security, as long
as you don't change the defaults. It's hard enough managing
a boatload of workstations under ideal conditions. When the
default settings change every month it gets really annoying
really quickly. :-D.

Cheers,
Kyle Moffett

-----BEGIN GEEK CODE BLOCK-----
Version: 3.12
GCM/CS/IT/U d- s++: a18 C++++>$ UB/L/X/*++++(+)>$ P+++(++++)>$
L++++(+++) E W++(+) N+++(++) o? K? w--- O? M++ V? PS+() PE+(-) Y+
PGP+++ t+(+++) 5 X R? tv-(--) b++++(++) DI+ D+ G e->++++$ h!*()>++$ r
!y?(-)
------END GEEK CODE BLOCK------


2005-03-16 02:39:55

by René Scharfe

[permalink] [raw]
Subject: Re: [PATCH][RFC] /proc umask and gid [was: Make /proc/<pid> chmod'able]

So, I gather from the feedback I've got that chmod'able /proc/<pid>
would be a bit over the top. 8-) While providing the easiest and most
intuitive user interface for changing the permissions on those
directories, it is overkill. Paul is right when he says that such a
feature should be turned on or off for all sessions at once, and that's
it.

My patch had at least one other problem: the contents of eac
/proc/<pid> directory became chmod'able, too, which was not intended.

Instead of fixing it up I took two steps back, dusted off the umask
kernel parameter patch and added the "special gid" feature I mentioned.

Without the new kernel parameters behaviour is unchanged. Add
proc.umask=077 and all /proc/<pid> will get a permission mode of 500.
This breaks pstree (no output), as Bodo already noted, because this
program needs access to /proc/1. It also breaks w -- it shows the
correct number of users but it lists XXXXX even for sessions owned
by the user running it.

Use proc.umask=007 and proc.gid=50 instead and all /proc/<pid> dirs
will have a mode of 550 and their group attribute will be set to 50
(that's "staff" on my Debian system). Pstree will work for all members
of that special group (just like top, ps and w -- which also show
everything in that case). Normal users will still have a restricted
view.

Albert, would you take fixes for w even though you despise the feature
that makes them necessary?

Is this less scary? Still useful?

Thanks,
Rene



diff -urp linux-2.6.11-mm3/Documentation/kernel-parameters.txt l5/Documentation/kernel-parameters.txt
--- linux-2.6.11-mm3/Documentation/kernel-parameters.txt 2005-03-12 19:23:30.000000000 +0100
+++ l5/Documentation/kernel-parameters.txt 2005-03-16 01:14:05.000000000 +0100
@@ -1095,16 +1095,22 @@ running once the system is up.
[ISAPNP] Exclude memory regions for the autoconfiguration
Ranges are in pairs (memory base and size).

+ processor.max_cstate= [HW, ACPI]
+ Limit processor to maximum C-state
+ max_cstate=9 overrides any DMI blacklist limit.
+
+ proc.gid= [KNL] If non-zero all /proc/<pid> directories will
+ have their group attribute set to that value.
+
+ proc.umask= [KNL] Restrict permissions of process specific
+ entries in /proc (i.e. the numerical directories).
+
profile= [KNL] Enable kernel profiling via /proc/profile
{ schedule | <number> }
(param: schedule - profile schedule points}
(param: profile step/bucket size as a power of 2 for
statistical time based profiling)

- processor.max_cstate= [HW, ACPI]
- Limit processor to maximum C-state
- max_cstate=9 overrides any DMI blacklist limit.
-
prompt_ramdisk= [RAM] List of RAM disks to prompt for floppy disk
before loading.
See Documentation/ramdisk.txt.
diff -urp linux-2.6.11-mm3/fs/proc/base.c l5/fs/proc/base.c
--- linux-2.6.11-mm3/fs/proc/base.c 2005-03-12 19:23:36.000000000 +0100
+++ l5/fs/proc/base.c 2005-03-16 01:54:52.000000000 +0100
@@ -35,8 +35,18 @@
#include <linux/seccomp.h>
#include <linux/cpuset.h>
#include <linux/audit.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
#include "internal.h"

+static umode_t proc_umask;
+module_param_named(umask, proc_umask, ushort, 0);
+MODULE_PARM_DESC(umask, "umask for all /proc/<pid> entries");
+
+static gid_t proc_gid;
+module_param_named(gid, proc_gid, uint, 0);
+MODULE_PARM_DESC(gid, "group attribute of all /proc/<pid> entries");
+
/*
* For hysterical raisins we keep the same inumbers as in the old procfs.
* Feel free to change the macro below - just keep the range distinct from
@@ -1149,6 +1159,8 @@ static struct inode *proc_pid_make_inode
inode->i_uid = task->euid;
inode->i_gid = task->egid;
}
+ if ((ino == PROC_TGID_INO || ino == PROC_TID_INO) && proc_gid)
+ inode->i_gid = proc_gid;
security_task_to_inode(task, inode);

out:
@@ -1182,6 +1194,8 @@ static int pid_revalidate(struct dentry
inode->i_uid = 0;
inode->i_gid = 0;
}
+ if ((proc_type(inode) == PROC_TGID_INO || proc_type(inode) == PROC_TID_INO) && proc_gid)
+ inode->i_gid = proc_gid;
security_task_to_inode(task, inode);
return 1;
}
@@ -1797,7 +1811,7 @@ struct dentry *proc_pid_lookup(struct in
put_task_struct(task);
goto out;
}
- inode->i_mode = S_IFDIR|S_IRUGO|S_IXUGO;
+ inode->i_mode = S_IFDIR | ((S_IRUGO|S_IXUGO) & ~proc_umask);
inode->i_op = &proc_tgid_base_inode_operations;
inode->i_fop = &proc_tgid_base_operations;
inode->i_nlink = 3;
@@ -1852,7 +1866,7 @@ static struct dentry *proc_task_lookup(s

if (!inode)
goto out_drop_task;
- inode->i_mode = S_IFDIR|S_IRUGO|S_IXUGO;
+ inode->i_mode = S_IFDIR | ((S_IRUGO|S_IXUGO) & ~proc_umask);
inode->i_op = &proc_tid_base_inode_operations;
inode->i_fop = &proc_tid_base_operations;
inode->i_nlink = 3;

2005-03-16 04:46:00

by Albert Cahalan

[permalink] [raw]
Subject: Re: [PATCH][RFC] /proc umask and gid [was: Make /proc/<pid> chmod'able]

On Wed, 2005-03-16 at 03:39 +0100, Rene Scharfe wrote:
> So, I gather from the feedback I've got that chmod'able /proc/<pid>
> would be a bit over the top. 8-) While providing the easiest and most
> intuitive user interface for changing the permissions on those
> directories, it is overkill. Paul is right when he says that such a
> feature should be turned on or off for all sessions at once, and that's
> it.
>
> My patch had at least one other problem: the contents of eac
> /proc/<pid> directory became chmod'able, too, which was not intended.
>
> Instead of fixing it up I took two steps back, dusted off the umask
> kernel parameter patch and added the "special gid" feature I mentioned.
>
> Without the new kernel parameters behaviour is unchanged. Add
> proc.umask=077 and all /proc/<pid> will get a permission mode of 500.
> This breaks pstree (no output), as Bodo already noted, because this
> program needs access to /proc/1. It also breaks w -- it shows the
> correct number of users but it lists XXXXX even for sessions owned
> by the user running it.
>
> Use proc.umask=007 and proc.gid=50 instead and all /proc/<pid> dirs
> will have a mode of 550 and their group attribute will be set to 50
> (that's "staff" on my Debian system). Pstree will work for all members
> of that special group (just like top, ps and w -- which also show
> everything in that case). Normal users will still have a restricted
> view.
>
> Albert, would you take fixes for w even though you despise the feature
> that makes them necessary?

I will take patches if they are not too messy and they do not
cause tools to report garbage output. For example, I do not
wish to have tools reporting -1, 0, or uninitialized data in
place of correct data.

Distinct controls for the various files could be useful.
I might want to make /proc/*/cmdline be public, or make
/proc/*/maps be private. This is particularly helpful if
a low-security file is added for bare-bones ps operation.

You might make a special exception for built-in kernel tasks
and init.


2005-03-16 04:55:47

by Albert Cahalan

[permalink] [raw]
Subject: Re: [PATCH][RFC] /proc umask and gid [was: Make /proc/<pid> chmod'able]

Better interface:

/sbin/sysctl -w proc.maps=0440
/sbin/sysctl -w proc.cmdline=0444
/sbin/sysctl -w proc.status=0444

The /etc/sysctl.conf file can be used to set these
at boot time.


2005-03-19 01:51:47

by René Scharfe

[permalink] [raw]
Subject: Re: [PATCH][RFC] /proc umask and gid [was: Make /proc/<pid> chmod'able]

On Tue, Mar 15, 2005 at 11:41:28PM -0500, Albert Cahalan wrote:
> Better interface:
>
> /sbin/sysctl -w proc.maps=0440
> /sbin/sysctl -w proc.cmdline=0444
> /sbin/sysctl -w proc.status=0444

Indeed it is, but it's much harder to implement.

Patch is against 2.6.11-mm3 but works with -mm4, too. I only made the
permissions configurable for some of the files, more can be added easily
if and when needed.

It's uglier than it needs to be, but before cleaning it up I'll go and
get some sleep.

Comments and patches much appreciated! :)

Rene



diff -pur linux-2.6.11-mm3/fs/proc/base.c l5/fs/proc/base.c
--- linux-2.6.11-mm3/fs/proc/base.c 2005-03-12 19:23:36.000000000 +0100
+++ l5/fs/proc/base.c 2005-03-19 01:08:40.000000000 +0100
@@ -35,6 +35,7 @@
#include <linux/seccomp.h>
#include <linux/cpuset.h>
#include <linux/audit.h>
+#include <linux/sysctl.h>
#include "internal.h"

/*
@@ -1419,6 +1420,93 @@ static struct file_operations proc_tgid_
static struct inode_operations proc_tgid_attr_inode_operations;
#endif

+static struct pid_entry *proc_base_entry_by_name(struct pid_entry *ents,
+ struct qstr *name)
+{
+ struct pid_entry *p;
+
+ for (p = ents; p->name; p++) {
+ if (p->len != name->len)
+ continue;
+ if (!memcmp(name->name, p->name, p->len))
+ return p;
+ }
+ return NULL;
+}
+
+#ifdef CONFIG_SYSCTL
+struct proc_sysctl_info {
+ int type;
+ mode_t mode;
+};
+
+/* order must match the CTL_PROC table in sysctl.h */
+struct proc_sysctl_info proc_base_permissions[] = {
+ {PROC_TGID_CMDLINE, S_IRUGO},
+ {PROC_TGID_MAPS, S_IRUGO},
+ {PROC_TGID_STAT, S_IRUGO},
+ {PROC_TGID_STATM, S_IRUGO},
+ {PROC_TGID_STATUS, S_IRUGO},
+ {0, 0}
+};
+
+static inline int is_system_task(struct task_struct *task)
+{
+ int rc = 0;
+
+ if (task->pid == 1)
+ rc = 1;
+ // TODO: kernel threads?
+ return rc;
+}
+
+static void proc_update_mode(mode_t *mode, int type, struct task_struct *task)
+{
+ struct proc_sysctl_info *s;
+
+ if (is_system_task(task))
+ return;
+ for (s = proc_base_permissions; s->type; s++) {
+ if (s->type == type) {
+ *mode = (*mode & ~S_IALLUGO) | s->mode;
+ break;
+ }
+ }
+}
+
+static int proc_base_permission(struct inode *inode, int mask,
+ struct nameidata *nd)
+{
+ struct task_struct *task = proc_task(inode);
+ struct pid_entry *p;
+
+ p = proc_base_entry_by_name(tgid_base_stuff, &nd->dentry->d_name);
+ if (p)
+ proc_update_mode(&inode->i_mode, p->type, task);
+ return generic_permission(inode, mask, NULL);
+}
+
+static int proc_base_getattr(struct vfsmount *mnt, struct dentry *dentry,
+ struct kstat *stat)
+{
+ struct inode *inode = dentry->d_inode;
+ struct task_struct *task = proc_task(inode);
+ struct pid_entry *p;
+
+ generic_fillattr(inode, stat);
+ p = proc_base_entry_by_name(tgid_base_stuff, &dentry->d_name);
+ if (p)
+ proc_update_mode(&inode->i_mode, p->type, task);
+ return 0;
+}
+
+static struct inode_operations proc_base_inode_operations = {
+ .getattr = proc_base_getattr,
+ .permission = proc_base_permission,
+};
+
+#endif /* CONFIG_SYSCTL */
+
/* SMP-safe */
static struct dentry *proc_pident_lookup(struct inode *dir,
struct dentry *dentry,
@@ -1436,13 +1524,8 @@ static struct dentry *proc_pident_lookup
if (!pid_alive(task))
goto out;

- for (p = ents; p->name; p++) {
- if (p->len != dentry->d_name.len)
- continue;
- if (!memcmp(dentry->d_name.name, p->name, p->len))
- break;
- }
- if (!p->name)
+ p = proc_base_entry_by_name(ents, &dentry->d_name);
+ if (p == NULL)
goto out;

error = -EINVAL;
@@ -1452,6 +1535,10 @@ static struct dentry *proc_pident_lookup

ei = PROC_I(inode);
inode->i_mode = p->mode;
+#ifdef CONFIG_SYSCTL
+ proc_update_mode(&inode->i_mode, p->type, task);
+ inode->i_op = &proc_base_inode_operations;
+#endif
/*
* Yes, it does not scale. And it should not. Don't add
* new entries into /proc/<tgid>/ without very good reasons.
diff -pur linux-2.6.11-mm3/include/linux/sysctl.h l5/include/linux/sysctl.h
--- linux-2.6.11-mm3/include/linux/sysctl.h 2005-03-12 19:23:37.000000000 +0100
+++ l5/include/linux/sysctl.h 2005-03-18 23:40:59.000000000 +0100
@@ -654,6 +654,13 @@ enum {
};

/* CTL_PROC names: */
+enum {
+ PROC_CMDLINE = 1,
+ PROC_MAPS = 2,
+ PROC_STAT = 3,
+ PROC_STATM = 4,
+ PROC_STATUS = 5,
+};

/* CTL_FS names: */
enum
diff -pur linux-2.6.11-mm3/kernel/sysctl.c l5/kernel/sysctl.c
--- linux-2.6.11-mm3/kernel/sysctl.c 2005-03-12 19:23:38.000000000 +0100
+++ l5/kernel/sysctl.c 2005-03-19 00:39:33.000000000 +0100
@@ -168,6 +168,15 @@ extern struct proc_dir_entry *proc_sys_r

static void register_proc_table(ctl_table *, struct proc_dir_entry *);
static void unregister_proc_table(ctl_table *, struct proc_dir_entry *);
+
+struct proc_sysctl_info {
+ int type;
+ mode_t mode;
+};
+extern struct proc_sysctl_info proc_base_permissions[];
+
+int proc_domode(ctl_table *, int, struct file *, void __user *, size_t *, loff_t *);
+
#endif

/* The default sysctl tables: */
@@ -839,7 +848,53 @@ static ctl_table vm_table[] = {
{ .ctl_name = 0 }
};

+#ifdef CONFIG_PROC_FS
+static int mode_r_ugo = S_IRUGO;
+#endif
+
static ctl_table proc_table[] = {
+#ifdef CONFIG_PROC_FS
+ {
+ .ctl_name = PROC_CMDLINE,
+ .procname = "cmdline",
+ .data = &proc_base_permissions[PROC_CMDLINE-1].mode,
+ .mode = 0644,
+ .proc_handler = &proc_domode,
+ .extra1 = &mode_r_ugo,
+ },
+ {
+ .ctl_name = PROC_MAPS,
+ .procname = "maps",
+ .data = &proc_base_permissions[PROC_MAPS-1].mode,
+ .mode = 0644,
+ .proc_handler = &proc_domode,
+ .extra1 = &mode_r_ugo,
+ },
+ {
+ .ctl_name = PROC_STAT,
+ .procname = "stat",
+ .data = &proc_base_permissions[PROC_STAT-1].mode,
+ .mode = 0644,
+ .proc_handler = &proc_domode,
+ .extra1 = &mode_r_ugo,
+ },
+ {
+ .ctl_name = PROC_STATM,
+ .procname = "statm",
+ .data = &proc_base_permissions[PROC_STATM-1].mode,
+ .mode = 0644,
+ .proc_handler = &proc_domode,
+ .extra1 = &mode_r_ugo,
+ },
+ {
+ .ctl_name = PROC_STATUS,
+ .procname = "status",
+ .data = &proc_base_permissions[PROC_STATUS-1].mode,
+ .mode = 0644,
+ .proc_handler = &proc_domode,
+ .extra1 = &mode_r_ugo,
+ },
+#endif
{ .ctl_name = 0 }
};

@@ -1459,6 +1514,79 @@ static int proc_doutsstring(ctl_table *t
return r;
}

+/**
+ * proc_domode - read a file mode value
+ * @table: the sysctl table
+ * @write: %TRUE if this is a write to the sysctl file
+ * @filp: the file structure
+ * @buffer: the user buffer
+ * @lenp: the size of the user buffer
+ * @ppos: file position
+ *
+ * Reads/writes one file mode value (data type mode_t)
+ * from/to the user buffer, treated as an ASCII string.
+ * Optionally checks that the value fits within the mask
+ * specified with *table->extra1.
+ *
+ * Returns 0 on success.
+ */
+int proc_domode(ctl_table *table, int write, struct file *filp,
+ void __user *buffer, size_t *lenp, loff_t *ppos)
+{
+ size_t len;
+ char __user *p;
+ char c;
+ char buf[6];
+ char *endp;
+ mode_t maxmask = 07777;
+ unsigned long mode;
+
+ if (!table->data || !*lenp || (*ppos && !write)) {
+ *lenp = 0;
+ return 0;
+ }
+
+ if (write) {
+ if (table->extra1)
+ maxmask = *((mode_t *)table->extra1);
+ len = 0;
+ p = buffer;
+ while (len < *lenp) {
+ if (get_user(c, p++))
+ return -EFAULT;
+ if (c == 0 || c == '\n')
+ break;
+ len++;
+ }
+ if (len > 6)
+ return -EINVAL;
+ if (copy_from_user(buf, buffer, len))
+ return -EFAULT;
+ buf[len] = '\0';
+ mode = simple_strtoul(buf, &endp, 0);
+ if (mode & ~maxmask)
+ return -EPERM;
+ *((mode_t *)table->data) = mode;
+ *ppos += *lenp;
+ } else {
+ if (*((mode_t *)table->data) > 07777)
+ return -EINVAL;
+ mode = *((mode_t *)table->data);
+ if (mode & 07000)
+ len = sprintf(buf, "%05o\n", (mode_t)mode);
+ else
+ len = sprintf(buf, "%04o\n", (mode_t)mode);
+ if (len > *lenp)
+ len = *lenp;
+ if (len)
+ if (copy_to_user(buffer, buf, len))
+ return -EFAULT;
+ *lenp = len;
+ *ppos += len;
+ }
+ return 0;
+}
+
static int do_proc_dointvec_conv(int *negp, unsigned long *lvalp,
int *valp,
int write, void *data)