Re: [PATCH ipset v2] Check setname length in session code before copying it

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Jozsef,

On Thu, 30 Aug 2018 11:10:02 +0200 (CEST)
Jozsef Kadlecsik <kadlec@xxxxxxxxxxxxxxxxx> wrote:

> Hi Stefano,
> 
> On Wed, 29 Aug 2018, Stefano Brivio wrote:
> 
> > We might overrun the buffer used to save it otherwise.
> > 
> > Signed-off-by: Stefano Brivio <sbrivio@xxxxxxxxxx>
> > ---
> > v2: As requested by Jozsef, move validation of setname length to
> >     attr2data() for data received via netlink, instead of doing
> >     it in callback_list().
> > 
> >  lib/session.c | 13 ++++++++++++-
> >  1 file changed, 12 insertions(+), 1 deletion(-)
> > 
> > diff --git a/lib/session.c b/lib/session.c
> > index ca96aaa57ea6..74310a19850e 100644
> > --- a/lib/session.c
> > +++ b/lib/session.c
> > @@ -691,6 +691,13 @@ attr2data(struct ipset_session *session, struct nlattr *nla[],
> >  		D("nla typename %s",
> >  		  (const char *) ipset_data_get(data, IPSET_OPT_TYPENAME));
> >  #endif
> > +	if (type == IPSET_ATTR_SETNAME && nla[IPSET_ATTR_DATA]) {
> > +		const char *setname = ipset_data_setname(data);
> > +		if (!setname || strlen(setname) >= IPSET_MAXNAMELEN)
> > +			FAILURE("Broken kernel message: "
> > +				"setname missing or too long!");
> > +	}
> > +
> >  	return ret;
> >  }  
> 
> Actually, I was thinking something like this:
> 
> 	if (attr->type == MNL_TYPE_UNSPEC)
> 		return 0;
> 	else if (attr->type == MNL_TYPE_NUL_STRING) {
> 		const char *str = d;
> 		if (!d || strlen(d) >= attr->len)
> 			FAILURE(...)
> 	} ...
> 		
> That way all typename is also verified.

Oh, right, I didn't think of that. I'll send a v3.

> > @@ -2014,7 +2021,11 @@ ipset_cmd(struct ipset_session *session, enum ipset_cmd cmd, uint32_t lineno)
> >  	if (session->lineno != 0 &&
> >  	    (cmd == IPSET_CMD_ADD || cmd == IPSET_CMD_DEL)) {
> >  		/* Save setname for the next possible aggregated restore line */
> > -		strcpy(session->saved_setname, ipset_data_setname(data));
> > +		const char *setname = ipset_data_setname(data);
> > +		if (!setname || strlen(setname) >= IPSET_MAXNAMELEN)
> > +			return ipset_err(session,
> > +				"Invalid command: setname missing or too long");
> > +		strcpy(session->saved_setname, setname);  
> 
> I don't understand this part: it is from userspace to kernel and ADD/DEL 
> commands already verified that setname is filled out, in build_msg().

Right, I don't need to check that setname is there. Still, its length
is not checked as far as I can see. Would you suggest that I move the
length check to build_msg()?

-- 
Stefano



[Index of Archives]     [Netfitler Users]     [LARTC]     [Bugtraq]     [Yosemite Forum]

  Powered by Linux