pledge(2) user(8)

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

pledge(2) user(8)

Ricardo Mestre-2
Hi tech@

This is an attempt to pledge(2) user(8) where the following are the possible
codepaths depending on how it was invoked:

groupadd -> creategid
groupdel -> modify_gid
groupmod -> modify_gid
groupinfo -> find_group_info

useradd -> adduser / creategid
userdel -> moduser
usermod -> moduser
userinfo -> find_user_info

And these are the promises I applied depending on each codepath:

groupadd -> stdio rpath wpath cpath fattr flock getpw
modify_gid -> stdio rpath wpath cpath fattr flock
find_group_info -> stdio rpath getpw

adduser -> stdio rpath wpath cpath fattr flock proc exec getpw id
moduser -> stdio rpath wpath cpath fattr flock proc exec getpw id
find_user_info -> stdio rpath getpw

And finally, the promises are needed for this (at least):

rpath/wpath: open files r/w
cpath: create files, unlink
flock: flock
fattr: chmod
proc/exec: vfork through pw_mkdb, system
getpw: getpwnam/getgrent and friends
id: setrlimit through pw_init

I made several tests and doesn't seem to break, but with so many flags I may
have missed something, could you please test this and let me know it looks ok?

Regards,
mestre

Index: user.c
===================================================================
RCS file: /cvs/src/usr.sbin/user/user.c,v
retrieving revision 1.108
diff -u -p -u -r1.108 user.c
--- user.c 29 Mar 2016 17:21:50 -0000 1.108
+++ user.c 29 Mar 2016 19:27:01 -0000
@@ -391,6 +391,9 @@ modify_gid(char *group, char *newent)
  int fd;
  int cc;
 
+ if (pledge("stdio rpath wpath cpath fattr flock", NULL) == -1)
+ err(1, NULL);
+
  if ((from = fopen(_PATH_GROUP, "r")) == NULL) {
  warn("can't modify gid for `%s': can't open `%s'", group,
     _PATH_GROUP);
@@ -945,6 +948,9 @@ find_user_info(const char *name)
  const char *errstr;
  uid_t uid;
 
+ if (pledge("stdio rpath getpw", NULL) == -1)
+ err(1, "pledge");
+
  if ((pwp = getpwnam(name)) == NULL) {
  uid = strtonum(name, -1, UID_MAX, &errstr);
  if (errstr == NULL)
@@ -961,6 +967,9 @@ find_group_info(const char *name)
  const char *errstr;
  gid_t gid;
 
+ if (pledge("stdio rpath getpw", NULL) == -1)
+ err(1, "pledge");
+
  if ((grp = getgrnam(name)) == NULL) {
  gid = strtonum(name, -1, GID_MAX, &errstr);
  if (errstr == NULL)
@@ -988,6 +997,10 @@ adduser(char *login_name, user_t *up)
  int i, yp = 0;
  FILE *fp;
 
+ if (pledge("stdio rpath wpath cpath fattr flock proc exec getpw id",
+    NULL) == -1)
+ err(1, NULL);
+
  if (!valid_login(login_name)) {
  errx(EXIT_FAILURE, "`%s' is not a valid login name", login_name);
  }
@@ -1402,6 +1415,10 @@ moduser(char *login_name, char *newlogin
  int rval;
  int i;
 
+ if (pledge("stdio rpath wpath cpath fattr flock proc exec getpw id",
+    NULL) == -1)
+ err(1, NULL);
+
  if (!valid_login(newlogin)) {
  errx(EXIT_FAILURE, "`%s' is not a valid login name", login_name);
  }
@@ -2109,6 +2126,10 @@ groupadd(int argc, char **argv)
  if (argc != 1) {
  usermgmt_usage("groupadd");
  }
+
+ if (pledge("stdio rpath wpath cpath fattr flock getpw", NULL) == -1)
+ err(1, NULL);
+
  checkeuid();
  if (!valid_group(*argv)) {
  errx(EXIT_FAILURE, "invalid group name `%s'", *argv);

Reply | Threaded
Open this post in threaded view
|

Re: pledge(2) user(8)

patrick keshishian
On 3/29/16, Ricardo Mestre <[hidden email]> wrote:

> Hi tech@
>
> This is an attempt to pledge(2) user(8) where the following are the
> possible
> codepaths depending on how it was invoked:
>
> groupadd -> creategid
> groupdel -> modify_gid
> groupmod -> modify_gid
> groupinfo -> find_group_info
>
> useradd -> adduser / creategid
> userdel -> moduser
> usermod -> moduser
> userinfo -> find_user_info
>
> And these are the promises I applied depending on each codepath:
>
> groupadd -> stdio rpath wpath cpath fattr flock getpw
> modify_gid -> stdio rpath wpath cpath fattr flock
> find_group_info -> stdio rpath getpw
>
> adduser -> stdio rpath wpath cpath fattr flock proc exec getpw id
> moduser -> stdio rpath wpath cpath fattr flock proc exec getpw id
> find_user_info -> stdio rpath getpw
>
> And finally, the promises are needed for this (at least):
>
> rpath/wpath: open files r/w
> cpath: create files, unlink
> flock: flock
> fattr: chmod
> proc/exec: vfork through pw_mkdb, system
> getpw: getpwnam/getgrent and friends
> id: setrlimit through pw_init
>
> I made several tests and doesn't seem to break, but with so many flags I
> may
> have missed something, could you please test this and let me know it looks
> ok?
>
> Regards,
> mestre
>
> Index: user.c
> ===================================================================
> RCS file: /cvs/src/usr.sbin/user/user.c,v
> retrieving revision 1.108
> diff -u -p -u -r1.108 user.c
> --- user.c 29 Mar 2016 17:21:50 -0000 1.108
> +++ user.c 29 Mar 2016 19:27:01 -0000
> @@ -391,6 +391,9 @@ modify_gid(char *group, char *newent)
>   int fd;
>   int cc;
>
> + if (pledge("stdio rpath wpath cpath fattr flock", NULL) == -1)
> + err(1, NULL);
> +

why the inconsistent err(3) usage here and ...


>   if ((from = fopen(_PATH_GROUP, "r")) == NULL) {
>   warn("can't modify gid for `%s': can't open `%s'", group,
>      _PATH_GROUP);
> @@ -945,6 +948,9 @@ find_user_info(const char *name)
>   const char *errstr;
>   uid_t uid;
>
> + if (pledge("stdio rpath getpw", NULL) == -1)
> + err(1, "pledge");
> +

here?

>   if ((pwp = getpwnam(name)) == NULL) {
>   uid = strtonum(name, -1, UID_MAX, &errstr);
>   if (errstr == NULL)
> @@ -961,6 +967,9 @@ find_group_info(const char *name)
>   const char *errstr;
>   gid_t gid;
>
> + if (pledge("stdio rpath getpw", NULL) == -1)
> + err(1, "pledge");
> +

and, here and ...

>   if ((grp = getgrnam(name)) == NULL) {
>   gid = strtonum(name, -1, GID_MAX, &errstr);
>   if (errstr == NULL)
> @@ -988,6 +997,10 @@ adduser(char *login_name, user_t *up)
>   int i, yp = 0;
>   FILE *fp;
>
> + if (pledge("stdio rpath wpath cpath fattr flock proc exec getpw id",
> +    NULL) == -1)
> + err(1, NULL);
> +

here? and the next two.


>   if (!valid_login(login_name)) {
>   errx(EXIT_FAILURE, "`%s' is not a valid login name", login_name);
>   }
> @@ -1402,6 +1415,10 @@ moduser(char *login_name, char *newlogin
>   int rval;
>   int i;
>
> + if (pledge("stdio rpath wpath cpath fattr flock proc exec getpw id",
> +    NULL) == -1)
> + err(1, NULL);
> +
>   if (!valid_login(newlogin)) {
>   errx(EXIT_FAILURE, "`%s' is not a valid login name", login_name);
>   }
> @@ -2109,6 +2126,10 @@ groupadd(int argc, char **argv)
>   if (argc != 1) {
>   usermgmt_usage("groupadd");
>   }
> +
> + if (pledge("stdio rpath wpath cpath fattr flock getpw", NULL) == -1)
> + err(1, NULL);
> +
>   checkeuid();
>   if (!valid_group(*argv)) {
>   errx(EXIT_FAILURE, "invalid group name `%s'", *argv);
>
>

Reply | Threaded
Open this post in threaded view
|

Re: pledge(2) user(8)

Ricardo Mestre-2
Copy pasto problem, they should all be err(1, "pledge");
But did you try this out ?

Regards,
mestre

On 13:19 Tue 29 Mar     , patrick keshishian wrote:

> On 3/29/16, Ricardo Mestre <[hidden email]> wrote:
> > Hi tech@
> >
> > This is an attempt to pledge(2) user(8) where the following are the
> > possible
> > codepaths depending on how it was invoked:
> >
> > groupadd -> creategid
> > groupdel -> modify_gid
> > groupmod -> modify_gid
> > groupinfo -> find_group_info
> >
> > useradd -> adduser / creategid
> > userdel -> moduser
> > usermod -> moduser
> > userinfo -> find_user_info
> >
> > And these are the promises I applied depending on each codepath:
> >
> > groupadd -> stdio rpath wpath cpath fattr flock getpw
> > modify_gid -> stdio rpath wpath cpath fattr flock
> > find_group_info -> stdio rpath getpw
> >
> > adduser -> stdio rpath wpath cpath fattr flock proc exec getpw id
> > moduser -> stdio rpath wpath cpath fattr flock proc exec getpw id
> > find_user_info -> stdio rpath getpw
> >
> > And finally, the promises are needed for this (at least):
> >
> > rpath/wpath: open files r/w
> > cpath: create files, unlink
> > flock: flock
> > fattr: chmod
> > proc/exec: vfork through pw_mkdb, system
> > getpw: getpwnam/getgrent and friends
> > id: setrlimit through pw_init
> >
> > I made several tests and doesn't seem to break, but with so many flags I
> > may
> > have missed something, could you please test this and let me know it looks
> > ok?
> >
> > Regards,
> > mestre
> >
> > Index: user.c
> > ===================================================================
> > RCS file: /cvs/src/usr.sbin/user/user.c,v
> > retrieving revision 1.108
> > diff -u -p -u -r1.108 user.c
> > --- user.c 29 Mar 2016 17:21:50 -0000 1.108
> > +++ user.c 29 Mar 2016 19:27:01 -0000
> > @@ -391,6 +391,9 @@ modify_gid(char *group, char *newent)
> >   int fd;
> >   int cc;
> >
> > + if (pledge("stdio rpath wpath cpath fattr flock", NULL) == -1)
> > + err(1, NULL);
> > +
>
> why the inconsistent err(3) usage here and ...
>
>
> >   if ((from = fopen(_PATH_GROUP, "r")) == NULL) {
> >   warn("can't modify gid for `%s': can't open `%s'", group,
> >      _PATH_GROUP);
> > @@ -945,6 +948,9 @@ find_user_info(const char *name)
> >   const char *errstr;
> >   uid_t uid;
> >
> > + if (pledge("stdio rpath getpw", NULL) == -1)
> > + err(1, "pledge");
> > +
>
> here?
>
> >   if ((pwp = getpwnam(name)) == NULL) {
> >   uid = strtonum(name, -1, UID_MAX, &errstr);
> >   if (errstr == NULL)
> > @@ -961,6 +967,9 @@ find_group_info(const char *name)
> >   const char *errstr;
> >   gid_t gid;
> >
> > + if (pledge("stdio rpath getpw", NULL) == -1)
> > + err(1, "pledge");
> > +
>
> and, here and ...
>
> >   if ((grp = getgrnam(name)) == NULL) {
> >   gid = strtonum(name, -1, GID_MAX, &errstr);
> >   if (errstr == NULL)
> > @@ -988,6 +997,10 @@ adduser(char *login_name, user_t *up)
> >   int i, yp = 0;
> >   FILE *fp;
> >
> > + if (pledge("stdio rpath wpath cpath fattr flock proc exec getpw id",
> > +    NULL) == -1)
> > + err(1, NULL);
> > +
>
> here? and the next two.
>
>
> >   if (!valid_login(login_name)) {
> >   errx(EXIT_FAILURE, "`%s' is not a valid login name", login_name);
> >   }
> > @@ -1402,6 +1415,10 @@ moduser(char *login_name, char *newlogin
> >   int rval;
> >   int i;
> >
> > + if (pledge("stdio rpath wpath cpath fattr flock proc exec getpw id",
> > +    NULL) == -1)
> > + err(1, NULL);
> > +
> >   if (!valid_login(newlogin)) {
> >   errx(EXIT_FAILURE, "`%s' is not a valid login name", login_name);
> >   }
> > @@ -2109,6 +2126,10 @@ groupadd(int argc, char **argv)
> >   if (argc != 1) {
> >   usermgmt_usage("groupadd");
> >   }
> > +
> > + if (pledge("stdio rpath wpath cpath fattr flock getpw", NULL) == -1)
> > + err(1, NULL);
> > +
> >   checkeuid();
> >   if (!valid_group(*argv)) {
> >   errx(EXIT_FAILURE, "invalid group name `%s'", *argv);
> >
> >