Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug or feature? Handling of $var is different to ${var} #178

Open
poWer4aiX opened this issue Sep 20, 2022 · 1 comment
Open

Bug or feature? Handling of $var is different to ${var} #178

poWer4aiX opened this issue Sep 20, 2022 · 1 comment

Comments

@poWer4aiX
Copy link

I'm not sure if it is bug or a feature, but if you try to execute a command in a login shell, then the behavior when using $var and ${var} is different (which is unusual).

To replicate execute:

$ sudo -i bash -c '(export var=/etc; cd $var; pwd)'
/root
$ sudo -i bash -c '(export var=/etc; cd ${var}; pwd)'
/etc

In our case we are glad that ${var} is working as expected, i.e. is is NOT expanded before, so that cd would change into /etc in this example.

I guess the reason is the escape handling in parse_args in src/parse_args.c:

sudo/src/parse_args.c

Lines 626 to 634 in 304726a

for (dst = cmnd, av = argv; *av != NULL; av++) {
for (src = *av; *src != '\0'; src++) {
/* quote potential meta characters */
if (!isalnum((unsigned char)*src) && *src != '_' && *src != '-' && *src != '$')
*dst++ = '\\';
*dst++ = *src;
}
*dst++ = ' ';
}

As the $ is not being escaped but the { and } (is not alnum), the resulting arguments passed to the shell are different, which can also be verified in the debug log:

Sep 20 14:48:40 sudo[9839] -> sudo_execve @ ./exec_common.c:184
Sep 20 14:48:40 sudo[9839] exec /bin/bash [-bash --login -c bash -c \(export\ var\=\/etc\;\ cd\ $\{var\}\;\ pwd\;\ env\|grep\ SUDO_C\)] [HOSTNAME=
...
Sep 20 14:51:08 sudo[10689] -> sudo_execve @ ./exec_common.c:184
Sep 20 14:51:08 sudo[10689] exec /bin/bash [-bash --login -c bash -c \(export\ var\=\/etc\;\ cd\ $var\;\ pwd\;\ env\|grep\ SUDO_C\)] [HOSTNAME=

The main question here is, is this a bug or a feature? We are using the ${var} variant in tons of productive workflow environments and we don't want to fall into a trap, once the behavior get changed and we are updating to a newer version.

Environment details:

  • sudo version: 1.8.23
  • OS: RHEL 7.9 running in AWS (same behavior can be seen in ubuntu 22.04 and others)

Thanks, Christian

@ljluestc
Copy link

ljluestc commented Sep 4, 2023

The behavior you're observing is due to how the shell interprets variable expansion and escaping. The distinction between $var and ${var} is not specific to sudo but is a characteristic of how shells handle variable expansion.

  • $var: This form directly substitutes the value of the variable var into the command line. In your example, it substitutes /etc into the cd command before the command is executed.

  • ${var}: This form separates the variable name from any surrounding characters. It is often used to disambiguate the variable name from adjacent characters. In your example, ${var} is treated as a whole and substituted as /etc after the cd command is executed.

The behavior you're observing is consistent with how shells work. It's not a bug in sudo but rather a behavior of shell variable expansion.

As for using ${var} in your productive workflow environments, you should be safe to continue using it. Shells have been behaving this way for a long time, and changes in behavior are unlikely unless there's a major change in shell behavior across various operating systems.

In summary, the behavior you're observing is not a bug in sudo or any specific tool; it's how shells handle variable expansion. You can continue to use ${var} in your workflow environments without concerns about unexpected changes in behavior.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants